[
  {
    "path": "Readme.md",
    "content": "\n# Neural Slime Volleyball\n\nHTML5-JS Slime Volleyball clone.  AI agent is a trained recurrent neural network, trained using basic conventional neuroevolution techniques.  Neural network implemented using the [convnetjs](http://cs.stanford.edu/people/karpathy/convnetjs/) library.  It is very difficult to win!\n\nSee my blog post at [blog.otoro.net](http://blog.otoro.net/2015/03/28/neural-slime-volleyball/) for more information, or [otoro.net](http://otoro.net/slimevolley/) to actually play the game.\n\n## online demo\n- [Neural Slime Volleyball](http://otoro.net/slimevolley)\n\n## Training\n\nIf you wish to experiment with adding extra AI modules, or just to see how the learning works, please edit both pro.html and the slimevolley_pro.js.  They are the versions I will use in the future.\n\nInside pro.html, you can switch on/off the training mode by changing trainingVersion = true/false\n\nIf it is running on training version, the most capable neural net, in the form of a JSON array is dumped to nn_gene on the screen every 50 training generations.  You can copy and paste that blob back into initGeneJSON as a quoted text inside slimevolley_pro.js to incorporate back into the game, and switching training mode back to false to play with the new trained network.\n\nHave fun-\n\n## License\nGNU GPL v3\n"
  },
  {
    "path": "index.html",
    "content": "<html>\n<head>\n  <title>neural slime volleyball</title>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=320, initial-scale=1.0, maximum-scale=1.0, user-scalable=0\"/>\n    <meta name=\"apple-mobile-web-app-capable\" content=\"yes\" />\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"mobile-web-app-capable\" content=\"yes\">\n    <meta name=\"description\" content=\"ōtoro.net\">\n    <meta name=\"author\" content=\"hardmaru\">\n\n    <!-- Bootstrap Core CSS - Uses Bootswatch Flatly Theme: http://bootswatch.com/flatly/ -->\n    <link rel=\"stylesheet\" href=\"http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css\">\n\n    <!-- extra styles -->\n    <style>\n    a {\n        font-family: \"Helvetica Neue\",Helvetica,Arial,sans-serif;\n        font-size: 2.0em;\n        font-weight: 150;\n        font-style: inherit;\n        color: orange;\n    }\n\n    head {\n      margin: 0;\n      padding: 0;\n    }\n    body {\n      margin: 0;\n      padding: 0;\n      font-family: \"Helvetica Neue\",Helvetica,Arial,sans-serif;\n      font-weight: 100;\n      display: none;\n    }\n    p {\n      padding: 10px;\n      font-family: Courier, \"Helvetica Neue\",Helvetica,Arial,sans-serif;\n      font-weight: 100;\n      font-size: 2.0em;\n    }\n    textarea {\n      padding: 5;\n      font-family: Courier, \"Helvetica Neue\",Helvetica,Arial,sans-serif;\n      font-weight: 100;\n      font-size: 0.5em;\n    }\n    #nn_weights { white-space: pre; }\n    </style>\n\n\n</head>\n<body>\n\n<a href=\"http://blog.otoro.net/2015/03/28/neural-slime-volleyball/\" id=\"initTitle\" target=\"_blank\">neural slime volleyball</a>\n<a href=\"http://blog.otoro.net/2015/03/28/neural-slime-volleyball/\" id=\"finalTitle\" target=\"_blank\">&copy; <ruby>ōtoro</ruby>.net</a>\n<p id=\"theHand\"><span class=\"glyphicon glyphicon-hand-up\"></span></p>\n<!--\n    <p id=\"nn_weights\"></p>\n-->\n    <div id=\"p5Container\">\n    </div>\n\n\n\n  <img src=\"img/neural_slime_volleyball.png\" class=\"img-responsive\" alt=\"\" id=\"pageImage\">\n\n  <!-- jQuery -->\n  <script src=\"http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js\"></script>\n  <!-- Bootstrap Core JavaScript -->\n  <script src=\"http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js\"></script>\n  <script src=\"http://cdn.jsdelivr.net/mobile-detect.js/0.4.1/mobile-detect.min.js\"></script>\n  <script src=\"./lib/convnetjs/convnet.js\"></script>\n  <script src=\"./lib/convnetjs/ga.js\"></script>\n\n<script>\n\n$(\"#pageImage\").hide();\n\n$(\"#initTitle\").hide();\n$(\"#theHand\").hide();\n$(\"#initTitle\").css({ \n    \"position\": \"absolute\",\n    \"top\": 8 + \"px\",\n    \"left\": 24 + \"px\",\n    });\n\n\n$(\"#finalTitle\").hide();\n$(\"#finalTitle\").css({ \n    \"position\": \"absolute\",\n    \"top\": 8 + \"px\",\n    \"right\": 24 + \"px\",\n    \"font-size\": 1.5 +\"em\"\n    });\n\nsetTimeout(function(){\n  $(\"body\").fadeIn(500);\n  $(\"#theHand\").fadeIn(500);\n  $(\"#initTitle\").fadeIn(500);\n},0);\n\n/*\nsetTimeout(function(){\n  $(\"#theHand\").fadeIn(1000);\n},2000);\n*/\nsetTimeout(function(){\n    $(\"#initTitle\").fadeOut(500);\n    $(\"#finalTitle\").fadeIn(500);\n},10000);\n\nsetTimeout(function(){\n    $(\"#theHand\").fadeOut(1000);\n},4000);\n\n/*\nsetTimeout(function(){\n    $(\"#mainNavBar\").fadeOut(1000);\n},4000);\n*/\n\n</script>\n\n<script language=\"javascript\" type=\"text/javascript\" src=\"./lib/p5.js\"></script>\n<script language=\"javascript\" type=\"text/javascript\" src=\"./lib/p5.dom.js\"></script>\n<script language=\"javascript\" type=\"text/javascript\" src=\"useful.js\"></script>\n<script language=\"javascript\" type=\"text/javascript\" src=\"slimevolley.js\"></script>\n\n<script>\n  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){\n  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),\n  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)\n  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');\n\n  ga('create', 'UA-61361005-1', 'auto');\n  ga('send', 'pageview');\n\n</script>\n</body>\n</html>"
  },
  {
    "path": "lib/box2d-camera.js",
    "content": "\n// -----------------------------------------------------------------------------\n// Scale Methods\n// -----------------------------------------------------------------------------\n\n// supposed to translate (x_b2, y_b2) -> (x_pixel, y_pixel).  everything else scaled by a factor of scaleFactor\nvar b2Camera = { \n  scaleFactor : 10,\n  x_b2: 0,\n  y_b2: 0,\n  x_pixel: 0,\n  y_pixel: 0\n};\n\nvar gravity;\nvar gravityStrength = 20;\n\nvar scaleToWorld = function(a,b) {\n  var newv;\n  if (a instanceof box2d.b2Vec2) {\n    newv = new box2d.b2Vec2();\n    newv.x = (a.x-b2Camera.x_pixel)/b2Camera.scaleFactor+b2Camera.x_b2;\n    newv.y = (a.y-b2Camera.y_pixel)/b2Camera.scaleFactor+b2Camera.y_b2;\n    return newv;\n  } else if (\"undefined\"!=typeof b) {\n    newv = new box2d.b2Vec2();\n    newv.x = (a-b2Camera.x_pixel)/b2Camera.scaleFactor+b2Camera.x_b2;\n    newv.y = (b-b2Camera.y_pixel)/b2Camera.scaleFactor+b2Camera.y_b2;\n    return newv;\n  } else {\n    return a/b2Camera.scaleFactor;\n  }\n};\n\n\nvar makeB2Vec2 = function(a,b) {\n  var newv;\n  newv = new box2d.b2Vec2();\n  newv.x = (a)/1;\n  newv.y = (b)/1;\n  return newv;\n};\n\nvar scaleToPixels = function(a,b) {\n  var newv;\n  if (a instanceof box2d.b2Vec2) {\n    newv = new box2d.b2Vec2();\n    newv.x = (a.x-b2Camera.x_b2)*b2Camera.scaleFactor+b2Camera.x_pixel;\n    newv.y = (a.y-b2Camera.y_b2)*b2Camera.scaleFactor+b2Camera.y_pixel;\n    return newv;\n  } else if (\"undefined\"!=typeof b) {\n    newv = new box2d.b2Vec2();\n    newv.x = (a-b2Camera.x_b2)*b2Camera.scaleFactor+b2Camera.x_pixel;\n    newv.y = (b-b2Camera.y_b2)*b2Camera.scaleFactor+b2Camera.y_pixel;\n    return newv;\n  } else {\n    return a*b2Camera.scaleFactor;\n  }\n};\n\n// -----------------------------------------------------------------------------\n// Create Methods\n// -----------------------------------------------------------------------------\n\nvar createWorld = function() {\n\n\tvar worldAABB = new box2d.b2AABB();\n\tworldAABB.lowerBound.SetXY(-this.bounds, -this.bounds);\n\tworldAABB.upperBound.SetXY(this.bounds, this.bounds);\n\tgravity = new box2d.b2Vec2(0,gravityStrength);\n\tvar doSleep = true;\n\n\treturn new box2d.b2World(gravity, doSleep);\n};\n\n// -----------------------------------------------------------------------------\n// Draw Methods\n// -----------------------------------------------------------------------------\n\nvar debugDraw = function(canvas, scale, world) {\n\n\tvar context = canvas.getContext('2d');\n  var j, b, f;\n  context.fillStyle = '#DDD';\n  context.fillRect(0, 0, canvas.width, canvas.height);\n\n\t// Draw joints\n\tfor( j=world.m_jointList; j; j=j.m_next) {\n    context.lineWidth = 0.25;\n    context.strokeStyle = '#00F';\n    drawJoint(context, scale, world, j);\n  }\n\n\t// Draw body shapes\n\tfor( b=world.m_bodyList; b; b=b.m_next) {\n\t\tfor( f = b.GetFixtureList(); f!==null; f=f.GetNext()) {  \n      context.lineWidth = 0.5;\n\t\t\tcontext.strokeStyle = '#F00';\n      drawShape(context, scale, world, b, f);\n    }\n  }\n};\n\nvar drawJoint = function(context, scale, world, joint) {\n\tcontext.save();\n  context.scale(scale,scale);\n  context.lineWidth /= scale;\n\n  var b1 = joint.m_bodyA;\n  var b2 = joint.m_bodyB;\n  var x1 = b1.GetPosition();\n  var x2 = b2.GetPosition();\n  var p1 = joint.GetAnchorA();\n  var p2 = joint.GetAnchorB();\n\n  context.beginPath();\n  switch (joint.m_type) {\n    case box2d.b2Joint.e_distanceJoint:\n      context.moveTo(p1.x, p1.y);\n      context.lineTo(p2.x, p2.y);\n      break;\n    default: {\n      if (b1 == world.m_groundBody) {\n        context.moveTo(p1.x, p1.y);\n        context.lineTo(x2.x, x2.y);\n      }\n      else if (b2 == world.m_groundBody) {\n        context.moveTo(p1.x, p1.y);\n        context.lineTo(x1.x, x1.y);\n      }\n      else {\n        context.moveTo(x1.x, x1.y);\n        context.lineTo(p1.x, p1.y);\n        context.lineTo(x2.x, x2.y);\n        context.lineTo(p2.x, p2.y);\n      }\n    } break;\n  }\n  context.closePath();\n  context.stroke();\n  context.restore();\n};\n\nvar drawShape = function(context, scale, world, body, fixture) {\n\n  context.save();\n  context.scale(scale,scale);\n\n  var bPos = body.GetPosition();\n  context.translate(bPos.x, bPos.y);\n  context.rotate(body.GetAngleRadians());\n  \n  context.beginPath();\n  context.lineWidth /= scale;\n\n\tvar shape = fixture.m_shape;\n  var i;\n  switch(shape.m_type) {\n    case box2d.b2ShapeType.e_circleShape: {\n      var r = shape.m_radius;\n      var segments = 16.0;\n      var theta = 0.0;\n      var dtheta = 2.0 * Math.PI / segments;\n\n      context.moveTo(r, 0);\n      for (i = 0; i < segments; i++) {\n        context.lineTo(r + r * Math.cos(theta), r * Math.sin(theta));\n        theta += dtheta;\n      }\n      context.lineTo(r, 0);\n    } break;\n\n    case box2d.b2ShapeType.e_polygonShape:\n    case box2d.b2ShapeType.e_chainShape: {\n\n      var vertices = shape.m_vertices;\n      var vertexCount = shape.m_count;\n      if (!vertexCount) return;\n\n      context.moveTo(vertices[0].x, vertices[0].y);\n      for (i = 0; i < vertexCount; i++)\n        context.lineTo(vertices[i].x, vertices[i].y);\n    } break;\n  }\n\n  context.closePath();\n  context.stroke();\n  context.restore();\n};"
  },
  {
    "path": "lib/box2d-helper.js",
    "content": "\n// -----------------------------------------------------------------------------\n// Scale Methods\n// -----------------------------------------------------------------------------\n\nvar scaleFactor;\n\nvar scaleToWorld = function(a,b) {\n  var newv;\n  if (a instanceof box2d.b2Vec2) {\n    newv = new box2d.b2Vec2();\n    newv.x = (a.x)/scaleFactor;\n    newv.y = (a.y)/scaleFactor;\n    return newv;\n  } else if (\"undefined\"!=typeof b) {\n    newv = new box2d.b2Vec2();\n    newv.x = (a)/scaleFactor;\n    newv.y = (b)/scaleFactor;\n    return newv;\n  } else {\n    return a/scaleFactor;\n  }\n};\n\nvar scaleToPixels = function(a,b) {\n  var newv;\n  if (a instanceof box2d.b2Vec2) {\n    newv = new box2d.b2Vec2();\n    newv.x = a.x*scaleFactor;\n    newv.y = a.y*scaleFactor;\n    return newv;\n  } else if (\"undefined\"!=typeof b) {\n    newv = new box2d.b2Vec2();\n    newv.x = a*scaleFactor;\n    newv.y = b*scaleFactor;\n    return newv;\n  } else {\n    return a*scaleFactor;\n  }\n};\n\n// -----------------------------------------------------------------------------\n// Create Methods\n// -----------------------------------------------------------------------------\n\nvar createWorld = function() {\n\n\tvar worldAABB = new box2d.b2AABB();\n\tworldAABB.lowerBound.SetXY(-this.bounds, -this.bounds);\n\tworldAABB.upperBound.SetXY(this.bounds, this.bounds);\n\tvar gravity = new box2d.b2Vec2(0,20);\n\tvar doSleep = true;\n\n  scaleFactor = 10;\n\n\treturn new box2d.b2World(gravity, doSleep);\n};\n\n// -----------------------------------------------------------------------------\n// Draw Methods\n// -----------------------------------------------------------------------------\n\nvar debugDraw = function(canvas, scale, world) {\n\n\tvar context = canvas.getContext('2d');\n  var j, b, f;\n  context.fillStyle = '#DDD';\n  context.fillRect(0, 0, canvas.width, canvas.height);\n\n\t// Draw joints\n\tfor( j=world.m_jointList; j; j=j.m_next) {\n    context.lineWidth = 0.25;\n    context.strokeStyle = '#00F';\n    drawJoint(context, scale, world, j);\n  }\n\n\t// Draw body shapes\n\tfor( b=world.m_bodyList; b; b=b.m_next) {\n\t\tfor( f = b.GetFixtureList(); f!==null; f=f.GetNext()) {  \n      context.lineWidth = 0.5;\n\t\t\tcontext.strokeStyle = '#F00';\n      drawShape(context, scale, world, b, f);\n    }\n  }\n};\n\nvar drawJoint = function(context, scale, world, joint) {\n\tcontext.save();\n  context.scale(scale,scale);\n  context.lineWidth /= scale;\n\n  var b1 = joint.m_bodyA;\n  var b2 = joint.m_bodyB;\n  var x1 = b1.GetPosition();\n  var x2 = b2.GetPosition();\n  var p1 = joint.GetAnchorA();\n  var p2 = joint.GetAnchorB();\n\n  context.beginPath();\n  switch (joint.m_type) {\n    case box2d.b2Joint.e_distanceJoint:\n      context.moveTo(p1.x, p1.y);\n      context.lineTo(p2.x, p2.y);\n      break;\n    default: {\n      if (b1 == world.m_groundBody) {\n        context.moveTo(p1.x, p1.y);\n        context.lineTo(x2.x, x2.y);\n      }\n      else if (b2 == world.m_groundBody) {\n        context.moveTo(p1.x, p1.y);\n        context.lineTo(x1.x, x1.y);\n      }\n      else {\n        context.moveTo(x1.x, x1.y);\n        context.lineTo(p1.x, p1.y);\n        context.lineTo(x2.x, x2.y);\n        context.lineTo(p2.x, p2.y);\n      }\n    } break;\n  }\n  context.closePath();\n  context.stroke();\n  context.restore();\n};\n\nvar drawShape = function(context, scale, world, body, fixture) {\n\n  context.save();\n  context.scale(scale,scale);\n\n  var bPos = body.GetPosition();\n  context.translate(bPos.x, bPos.y);\n  context.rotate(body.GetAngleRadians());\n  \n  context.beginPath();\n  context.lineWidth /= scale;\n\n\tvar shape = fixture.m_shape;\n  var i;\n  switch(shape.m_type) {\n    case box2d.b2ShapeType.e_circleShape: {\n      var r = shape.m_radius;\n      var segments = 16.0;\n      var theta = 0.0;\n      var dtheta = 2.0 * Math.PI / segments;\n\n      context.moveTo(r, 0);\n      for (i = 0; i < segments; i++) {\n        context.lineTo(r + r * Math.cos(theta), r * Math.sin(theta));\n        theta += dtheta;\n      }\n      context.lineTo(r, 0);\n    } break;\n\n    case box2d.b2ShapeType.e_polygonShape:\n    case box2d.b2ShapeType.e_chainShape: {\n\n      var vertices = shape.m_vertices;\n      var vertexCount = shape.m_count;\n      if (!vertexCount) return;\n\n      context.moveTo(vertices[0].x, vertices[0].y);\n      for (i = 0; i < vertexCount; i++)\n        context.lineTo(vertices[i].x, vertices[i].y);\n    } break;\n  }\n\n  context.closePath();\n  context.stroke();\n  context.restore();\n};"
  },
  {
    "path": "lib/box2d-html5.js",
    "content": "var COMPILED=!0,goog=goog||{};goog.global=this;goog.DEBUG=!1;goog.LOCALE=\"en\";goog.TRUSTED_SITE=!0;goog.provide=function(a){if(!COMPILED){if(goog.isProvided_(a))throw Error('Namespace \"'+a+'\" already declared.');delete goog.implicitNamespaces_[a];for(var b=a;(b=b.substring(0,b.lastIndexOf(\".\")))&&!goog.getObjectByName(b);)goog.implicitNamespaces_[b]=!0}goog.exportPath_(a)};\ngoog.setTestOnly=function(a){if(COMPILED&&!goog.DEBUG)throw a=a||\"\",Error(\"Importing test-only code into non-debug environment\"+a?\": \"+a:\".\");};COMPILED||(goog.isProvided_=function(a){return!goog.implicitNamespaces_[a]&&!!goog.getObjectByName(a)},goog.implicitNamespaces_={});goog.exportPath_=function(a,b,c){a=a.split(\".\");c=c||goog.global;a[0]in c||!c.execScript||c.execScript(\"var \"+a[0]);for(var e;a.length&&(e=a.shift());)!a.length&&goog.isDef(b)?c[e]=b:c=c[e]?c[e]:c[e]={}};\ngoog.getObjectByName=function(a,b){for(var c=a.split(\".\"),e=b||goog.global,d;d=c.shift();)if(goog.isDefAndNotNull(e[d]))e=e[d];else return null;return e};goog.globalize=function(a,b){var c=b||goog.global,e;for(e in a)c[e]=a[e]};\ngoog.addDependency=function(a,b,c){if(!COMPILED){var e;a=a.replace(/\\\\/g,\"/\");for(var d=goog.dependencies_,f=0;e=b[f];f++)d.nameToPath[e]=a,a in d.pathToNames||(d.pathToNames[a]={}),d.pathToNames[a][e]=!0;for(e=0;b=c[e];e++)a in d.requires||(d.requires[a]={}),d.requires[a][b]=!0}};goog.ENABLE_DEBUG_LOADER=!0;\ngoog.require=function(a){if(!COMPILED&&!goog.isProvided_(a)){if(goog.ENABLE_DEBUG_LOADER){var b=goog.getPathFromDeps_(a);if(b){goog.included_[b]=!0;goog.writeScripts_();return}}a=\"goog.require could not find: \"+a;goog.global.console&&goog.global.console.error(a);throw Error(a);}};goog.basePath=\"\";goog.nullFunction=function(){};goog.identityFunction=function(a,b){return a};goog.abstractMethod=function(){throw Error(\"unimplemented abstract method\");};\ngoog.addSingletonGetter=function(a){a.getInstance=function(){if(a.instance_)return a.instance_;goog.DEBUG&&(goog.instantiatedSingletons_[goog.instantiatedSingletons_.length]=a);return a.instance_=new a}};goog.instantiatedSingletons_=[];\n!COMPILED&&goog.ENABLE_DEBUG_LOADER&&(goog.included_={},goog.dependencies_={pathToNames:{},nameToPath:{},requires:{},visited:{},written:{}},goog.inHtmlDocument_=function(){var a=goog.global.document;return\"undefined\"!=typeof a&&\"write\"in a},goog.findBasePath_=function(){if(goog.global.CLOSURE_BASE_PATH)goog.basePath=goog.global.CLOSURE_BASE_PATH;else if(goog.inHtmlDocument_())for(var a=goog.global.document.getElementsByTagName(\"script\"),b=a.length-1;0<=b;--b){var c=a[b].src,e=c.lastIndexOf(\"?\"),e=\n-1==e?c.length:e;if(\"base.js\"==c.substr(e-7,7)){goog.basePath=c.substr(0,e-7);break}}},goog.importScript_=function(a){var b=goog.global.CLOSURE_IMPORT_SCRIPT||goog.writeScriptTag_;!goog.dependencies_.written[a]&&b(a)&&(goog.dependencies_.written[a]=!0)},goog.writeScriptTag_=function(a){if(goog.inHtmlDocument_()){var b=goog.global.document;if(\"complete\"==b.readyState){if(/\\bdeps.js$/.test(a))return!1;throw Error('Cannot write \"'+a+'\" after document load');}b.write('<script type=\"text/javascript\" src=\"'+\na+'\">\\x3c/script>');return!0}return!1},goog.writeScripts_=function(){function a(d){if(!(d in e.written)){if(!(d in e.visited)&&(e.visited[d]=!0,d in e.requires))for(var g in e.requires[d])if(!goog.isProvided_(g))if(g in e.nameToPath)a(e.nameToPath[g]);else throw Error(\"Undefined nameToPath for \"+g);d in c||(c[d]=!0,b.push(d))}}var b=[],c={},e=goog.dependencies_,d;for(d in goog.included_)e.written[d]||a(d);for(d=0;d<b.length;d++)if(b[d])goog.importScript_(goog.basePath+b[d]);else throw Error(\"Undefined script input\");\n},goog.getPathFromDeps_=function(a){return a in goog.dependencies_.nameToPath?goog.dependencies_.nameToPath[a]:null},goog.findBasePath_(),goog.global.CLOSURE_NO_DEPS||goog.importScript_(goog.basePath+\"deps.js\"));\ngoog.typeOf=function(a){var b=typeof a;if(\"object\"==b)if(a){if(a instanceof Array)return\"array\";if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if(\"[object Window]\"==c)return\"object\";if(\"[object Array]\"==c||\"number\"==typeof a.length&&\"undefined\"!=typeof a.splice&&\"undefined\"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable(\"splice\"))return\"array\";if(\"[object Function]\"==c||\"undefined\"!=typeof a.call&&\"undefined\"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable(\"call\"))return\"function\"}else return\"null\";\nelse if(\"function\"==b&&\"undefined\"==typeof a.call)return\"object\";return b};goog.isDef=function(a){return void 0!==a};goog.isNull=function(a){return null===a};goog.isDefAndNotNull=function(a){return null!=a};goog.isArray=function(a){return\"array\"==goog.typeOf(a)};goog.isArrayLike=function(a){var b=goog.typeOf(a);return\"array\"==b||\"object\"==b&&\"number\"==typeof a.length};goog.isDateLike=function(a){return goog.isObject(a)&&\"function\"==typeof a.getFullYear};goog.isString=function(a){return\"string\"==typeof a};\ngoog.isBoolean=function(a){return\"boolean\"==typeof a};goog.isNumber=function(a){return\"number\"==typeof a};goog.isFunction=function(a){return\"function\"==goog.typeOf(a)};goog.isObject=function(a){var b=typeof a;return\"object\"==b&&null!=a||\"function\"==b};goog.getUid=function(a){return a[goog.UID_PROPERTY_]||(a[goog.UID_PROPERTY_]=++goog.uidCounter_)};goog.removeUid=function(a){\"removeAttribute\"in a&&a.removeAttribute(goog.UID_PROPERTY_);try{delete a[goog.UID_PROPERTY_]}catch(b){}};\ngoog.UID_PROPERTY_=\"closure_uid_\"+(1E9*Math.random()>>>0);goog.uidCounter_=0;goog.getHashCode=goog.getUid;goog.removeHashCode=goog.removeUid;goog.cloneObject=function(a){var b=goog.typeOf(a);if(\"object\"==b||\"array\"==b){if(a.clone)return a.clone();var b=\"array\"==b?[]:{},c;for(c in a)b[c]=goog.cloneObject(a[c]);return b}return a};goog.bindNative_=function(a,b,c){return a.call.apply(a.bind,arguments)};\ngoog.bindJs_=function(a,b,c){if(!a)throw Error();if(2<arguments.length){var e=Array.prototype.slice.call(arguments,2);return function(){var c=Array.prototype.slice.call(arguments);Array.prototype.unshift.apply(c,e);return a.apply(b,c)}}return function(){return a.apply(b,arguments)}};goog.bind=function(a,b,c){Function.prototype.bind&&-1!=Function.prototype.bind.toString().indexOf(\"native code\")?goog.bind=goog.bindNative_:goog.bind=goog.bindJs_;return goog.bind.apply(null,arguments)};\ngoog.partial=function(a,b){var c=Array.prototype.slice.call(arguments,1);return function(){var b=Array.prototype.slice.call(arguments);b.unshift.apply(b,c);return a.apply(this,b)}};goog.mixin=function(a,b){for(var c in b)a[c]=b[c]};goog.now=goog.TRUSTED_SITE&&Date.now||function(){return+new Date};\ngoog.globalEval=function(a){if(goog.global.execScript)goog.global.execScript(a,\"JavaScript\");else if(goog.global.eval)if(null==goog.evalWorksForGlobals_&&(goog.global.eval(\"var _et_ = 1;\"),\"undefined\"!=typeof goog.global._et_?(delete goog.global._et_,goog.evalWorksForGlobals_=!0):goog.evalWorksForGlobals_=!1),goog.evalWorksForGlobals_)goog.global.eval(a);else{var b=goog.global.document,c=b.createElement(\"script\");c.type=\"text/javascript\";c.defer=!1;c.appendChild(b.createTextNode(a));b.body.appendChild(c);\nb.body.removeChild(c)}else throw Error(\"goog.globalEval not available\");};goog.evalWorksForGlobals_=null;goog.getCssName=function(a,b){var c=function(a){return goog.cssNameMapping_[a]||a},e=function(a){a=a.split(\"-\");for(var b=[],e=0;e<a.length;e++)b.push(c(a[e]));return b.join(\"-\")},e=goog.cssNameMapping_?\"BY_WHOLE\"==goog.cssNameMappingStyle_?c:e:function(a){return a};return b?a+\"-\"+e(b):e(a)};goog.setCssNameMapping=function(a,b){goog.cssNameMapping_=a;goog.cssNameMappingStyle_=b};\n!COMPILED&&goog.global.CLOSURE_CSS_NAME_MAPPING&&(goog.cssNameMapping_=goog.global.CLOSURE_CSS_NAME_MAPPING);goog.getMsg=function(a,b){var c=b||{},e;for(e in c){var d=(\"\"+c[e]).replace(/\\$/g,\"$$$$\");a=a.replace(RegExp(\"\\\\{\\\\$\"+e+\"\\\\}\",\"gi\"),d)}return a};goog.getMsgWithFallback=function(a,b){return a};goog.exportSymbol=function(a,b,c){goog.exportPath_(a,b,c)};goog.exportProperty=function(a,b,c){a[b]=c};\ngoog.inherits=function(a,b){function c(){}c.prototype=b.prototype;a.superClass_=b.prototype;a.prototype=new c;a.prototype.constructor=a};\ngoog.base=function(a,b,c){var e=arguments.callee.caller;if(e.superClass_)return e.superClass_.constructor.apply(a,Array.prototype.slice.call(arguments,1));for(var d=Array.prototype.slice.call(arguments,2),f=!1,g=a.constructor;g;g=g.superClass_&&g.superClass_.constructor)if(g.prototype[b]===e)f=!0;else if(f)return g.prototype[b].apply(a,d);if(a[b]===e)return a.constructor.prototype[b].apply(a,d);throw Error(\"goog.base called from a method of one name to a method of a different name\");};\ngoog.scope=function(a){a.call(goog.global)};var box2d={b2Settings:{}};Object.defineProperty||(Object.defineProperty=function(a,b,c){Object.__defineGetter__&&(\"get\"in c?a.__defineGetter__(b,c.get):\"value\"in c&&a.__defineGetter__(b,c.value));Object.__defineSetter__&&(\"set\"in c?a.__defineSetter__(b,c.set):\"value\"in c&&a.__defineSetter__(b,c.value))});box2d.DEBUG=!1;goog.exportSymbol(\"box2d.DEBUG\",box2d.DEBUG);box2d.ENABLE_ASSERTS=box2d.DEBUG;goog.exportSymbol(\"box2d.ENABLE_ASSERTS\",box2d.ENABLE_ASSERTS);\nbox2d.b2Assert=function(a,b,c){if(box2d.DEBUG&&!a)debugger};goog.exportSymbol(\"box2d.b2Assert\",box2d.b2Assert);box2d.b2_maxFloat=1E37;goog.exportSymbol(\"box2d.b2_maxFloat\",box2d.b2_maxFloat);box2d.b2_epsilon=1E-5;goog.exportSymbol(\"box2d.b2_epsilon\",box2d.b2_epsilon);box2d.b2_epsilon_sq=box2d.b2_epsilon*box2d.b2_epsilon;goog.exportSymbol(\"box2d.b2_epsilon_sq\",box2d.b2_epsilon_sq);box2d.b2_pi=Math.PI;goog.exportSymbol(\"box2d.b2_pi\",box2d.b2_pi);box2d.b2_maxManifoldPoints=2;\ngoog.exportSymbol(\"box2d.b2_maxManifoldPoints\",box2d.b2_maxManifoldPoints);box2d.b2_maxPolygonVertices=8;goog.exportSymbol(\"box2d.b2_maxPolygonVertices\",box2d.b2_maxPolygonVertices);box2d.b2_aabbExtension=0.1;goog.exportSymbol(\"box2d.b2_aabbExtension\",box2d.b2_aabbExtension);box2d.b2_aabbMultiplier=2;goog.exportSymbol(\"box2d.b2_aabbMultiplier\",box2d.b2_aabbMultiplier);box2d.b2_linearSlop=0.008;goog.exportSymbol(\"box2d.b2_linearSlop\",box2d.b2_linearSlop);box2d.b2_angularSlop=2/180*box2d.b2_pi;\ngoog.exportSymbol(\"box2d.b2_angularSlop\",box2d.b2_angularSlop);box2d.b2_polygonRadius=2*box2d.b2_linearSlop;goog.exportSymbol(\"box2d.b2_polygonRadius\",box2d.b2_polygonRadius);box2d.b2_maxSubSteps=8;goog.exportSymbol(\"box2d.b2_maxSubSteps\",box2d.b2_maxSubSteps);box2d.b2_maxTOIContacts=32;goog.exportSymbol(\"box2d.b2_maxTOIContacts\",box2d.b2_maxTOIContacts);box2d.b2_velocityThreshold=1;goog.exportSymbol(\"box2d.b2_velocityThreshold\",box2d.b2_velocityThreshold);box2d.b2_maxLinearCorrection=0.2;\ngoog.exportSymbol(\"box2d.b2_maxLinearCorrection\",box2d.b2_maxLinearCorrection);box2d.b2_maxAngularCorrection=8/180*box2d.b2_pi;goog.exportSymbol(\"box2d.b2_maxAngularCorrection\",box2d.b2_maxAngularCorrection);box2d.b2_maxTranslation=2;goog.exportSymbol(\"box2d.b2_maxTranslation\",box2d.b2_maxTranslation);box2d.b2_maxTranslationSquared=box2d.b2_maxTranslation*box2d.b2_maxTranslation;goog.exportSymbol(\"box2d.b2_maxTranslationSquared\",box2d.b2_maxTranslationSquared);box2d.b2_maxRotation=0.5*box2d.b2_pi;\ngoog.exportSymbol(\"box2d.b2_maxRotation\",box2d.b2_maxRotation);box2d.b2_maxRotationSquared=box2d.b2_maxRotation*box2d.b2_maxRotation;goog.exportSymbol(\"box2d.b2_maxRotationSquared\",box2d.b2_maxRotationSquared);box2d.b2_baumgarte=0.2;goog.exportSymbol(\"box2d.b2_baumgarte\",box2d.b2_baumgarte);box2d.b2_toiBaumgarte=0.75;goog.exportSymbol(\"box2d.b2_toiBaumgarte\",box2d.b2_toiBaumgarte);box2d.b2_timeToSleep=0.5;goog.exportSymbol(\"box2d.b2_timeToSleep\",box2d.b2_timeToSleep);\nbox2d.b2_linearSleepTolerance=0.01;goog.exportSymbol(\"box2d.b2_linearSleepTolerance\",box2d.b2_linearSleepTolerance);box2d.b2_angularSleepTolerance=2/180*box2d.b2_pi;goog.exportSymbol(\"box2d.b2_angularSleepTolerance\",box2d.b2_angularSleepTolerance);box2d.b2Alloc=function(a){return null};goog.exportSymbol(\"box2d.b2Alloc\",box2d.b2Alloc);box2d.b2Free=function(a){};goog.exportSymbol(\"box2d.b2Free\",box2d.b2Free);box2d.b2Log=function(a){goog.global.console.log.apply(null,arguments)};\ngoog.exportSymbol(\"box2d.b2Log\",box2d.b2Log);box2d.b2Version=function(a,b,c){this.major=a||0;this.minor=b||0;this.revision=c||0};goog.exportSymbol(\"box2d.b2Version\",box2d.b2Version);box2d.b2Version.prototype.major=0;goog.exportProperty(box2d.b2Version.prototype,\"major\",box2d.b2Version.prototype.major);box2d.b2Version.prototype.minor=0;goog.exportProperty(box2d.b2Version.prototype,\"minor\",box2d.b2Version.prototype.minor);box2d.b2Version.prototype.revision=0;\ngoog.exportProperty(box2d.b2Version.prototype,\"revision\",box2d.b2Version.prototype.revision);box2d.b2Version.prototype.toString=function(){return this.major+\".\"+this.minor+\".\"+this.revision};goog.exportProperty(box2d.b2Version.prototype,\"toString\",box2d.b2Version.prototype.toString);box2d.b2_version=new box2d.b2Version(2,3,0);goog.exportSymbol(\"box2d.b2_version\",box2d.b2_version);box2d.b2_changelist=278;goog.exportSymbol(\"box2d.b2_changelist\",box2d.b2_changelist);\nbox2d.b2ParseInt=function(a){return parseInt(a,10)};goog.exportSymbol(\"box2d.b2ParseInt\",box2d.b2ParseInt);box2d.b2ParseUInt=function(a){return box2d.b2Abs(parseInt(a,10))};goog.exportSymbol(\"box2d.b2ParseUInt\",box2d.b2ParseUInt);box2d.b2MakeArray=function(a,b){void 0===a&&(a=0);var c=Array(a);if(void 0!==b)for(var e=0;e<a;++e)c[e]=b(e);return c};goog.exportSymbol(\"box2d.b2MakeArray\",box2d.b2MakeArray);box2d.b2MakeNumberArray=function(a){return box2d.b2MakeArray(a,function(a){return 0})};\ngoog.exportSymbol(\"box2d.b2MakeNumberArray\",box2d.b2MakeNumberArray);box2d.b2Math={};box2d.b2_pi_over_180=box2d.b2_pi/180;goog.exportSymbol(\"box2d.b2_pi_over_180\",box2d.b2_pi_over_180);box2d.b2_180_over_pi=180/box2d.b2_pi;goog.exportSymbol(\"box2d.b2_180_over_pi\",box2d.b2_180_over_pi);box2d.b2_two_pi=2*box2d.b2_pi;goog.exportSymbol(\"box2d.b2_two_pi\",box2d.b2_two_pi);box2d.b2Abs=function(a){return 0>a?-a:a};goog.exportSymbol(\"box2d.b2Abs\",box2d.b2Abs);box2d.b2Min=function(a,b){return a<b?a:b};goog.exportSymbol(\"box2d.b2Min\",box2d.b2Min);\nbox2d.b2Max=function(a,b){return a>b?a:b};goog.exportSymbol(\"box2d.b2Max\",box2d.b2Max);box2d.b2Clamp=function(a,b,c){return a<b?b:a>c?c:a};goog.exportSymbol(\"box2d.b2Clamp\",box2d.b2Clamp);box2d.b2Swap=function(a,b){box2d.ENABLE_ASSERTS&&box2d.b2Assert(!1);var c=a[0];a[0]=b[0];b[0]=c};goog.exportSymbol(\"box2d.b2Swap\",box2d.b2Swap);box2d.b2IsValid=function(a){return isFinite(a)};goog.exportSymbol(\"box2d.b2IsValid\",box2d.b2IsValid);box2d.b2Sq=function(a){return a*a};goog.exportSymbol(\"box2d.b2Sq\",box2d.b2Sq);\nbox2d.b2InvSqrt=function(a){return 1/Math.sqrt(a)};goog.exportSymbol(\"box2d.b2InvSqrt\",box2d.b2InvSqrt);box2d.b2Sqrt=function(a){return Math.sqrt(a)};goog.exportSymbol(\"box2d.b2Sqrt\",box2d.b2Sqrt);box2d.b2Pow=function(a,b){return Math.pow(a,b)};goog.exportSymbol(\"box2d.b2Pow\",box2d.b2Pow);box2d.b2DegToRad=function(a){return a*box2d.b2_pi_over_180};goog.exportSymbol(\"box2d.b2DegToRad\",box2d.b2DegToRad);box2d.b2RadToDeg=function(a){return a*box2d.b2_180_over_pi};\ngoog.exportSymbol(\"box2d.b2RadToDeg\",box2d.b2RadToDeg);box2d.b2Cos=function(a){return Math.cos(a)};goog.exportSymbol(\"box2d.b2Cos\",box2d.b2Cos);box2d.b2Sin=function(a){return Math.sin(a)};goog.exportSymbol(\"box2d.b2Sin\",box2d.b2Sin);box2d.b2Acos=function(a){return Math.acos(a)};goog.exportSymbol(\"box2d.b2Acos\",box2d.b2Acos);box2d.b2Asin=function(a){return Math.asin(a)};goog.exportSymbol(\"box2d.b2Asin\",box2d.b2Asin);box2d.b2Atan2=function(a,b){return Math.atan2(a,b)};\ngoog.exportSymbol(\"box2d.b2Atan2\",box2d.b2Atan2);box2d.b2NextPowerOfTwo=function(a){a|=a>>1&2147483647;a|=a>>2&1073741823;a|=a>>4&268435455;a|=a>>8&16777215;return(a|a>>16&65535)+1};goog.exportSymbol(\"box2d.b2NextPowerOfTwo\",box2d.b2NextPowerOfTwo);box2d.b2IsPowerOfTwo=function(a){return 0<a&&0===(a&a-1)};goog.exportSymbol(\"box2d.b2IsPowerOfTwo\",box2d.b2IsPowerOfTwo);box2d.b2Random=function(){return 2*Math.random()-1};goog.exportSymbol(\"box2d.b2Random\",box2d.b2Random);\nbox2d.b2RandomRange=function(a,b){return(b-a)*Math.random()+a};goog.exportSymbol(\"box2d.b2RandomRange\",box2d.b2RandomRange);box2d.b2Vec2=function(a,b){this.x=a||0;this.y=b||0};goog.exportSymbol(\"box2d.b2Vec2\",box2d.b2Vec2);box2d.b2Vec2.prototype.x=0;goog.exportProperty(box2d.b2Vec2.prototype,\"x\",box2d.b2Vec2.prototype.x);box2d.b2Vec2.prototype.y=0;goog.exportProperty(box2d.b2Vec2.prototype,\"y\",box2d.b2Vec2.prototype.y);box2d.b2Vec2_zero=new box2d.b2Vec2;goog.exportSymbol(\"box2d.b2Vec2_zero\",box2d.b2Vec2_zero);\nbox2d.b2Vec2.ZERO=new box2d.b2Vec2;goog.exportProperty(box2d.b2Vec2,\"ZERO\",box2d.b2Vec2.ZERO);box2d.b2Vec2.UNITX=new box2d.b2Vec2(1,0);goog.exportProperty(box2d.b2Vec2,\"UNITX\",box2d.b2Vec2.UNITX);box2d.b2Vec2.UNITY=new box2d.b2Vec2(0,1);goog.exportProperty(box2d.b2Vec2,\"UNITY\",box2d.b2Vec2.UNITY);box2d.b2Vec2.s_t0=new box2d.b2Vec2;goog.exportProperty(box2d.b2Vec2,\"s_t0\",box2d.b2Vec2.s_t0);box2d.b2Vec2.s_t1=new box2d.b2Vec2;goog.exportProperty(box2d.b2Vec2,\"s_t1\",box2d.b2Vec2.s_t1);\nbox2d.b2Vec2.s_t2=new box2d.b2Vec2;goog.exportProperty(box2d.b2Vec2,\"s_t2\",box2d.b2Vec2.s_t2);box2d.b2Vec2.s_t3=new box2d.b2Vec2;goog.exportProperty(box2d.b2Vec2,\"s_t3\",box2d.b2Vec2.s_t3);box2d.b2Vec2.MakeArray=function(a){return box2d.b2MakeArray(a,function(a){return new box2d.b2Vec2})};goog.exportProperty(box2d.b2Vec2,\"MakeArray\",box2d.b2Vec2.MakeArray);box2d.b2Vec2.prototype.Clone=function(){return new box2d.b2Vec2(this.x,this.y)};goog.exportProperty(box2d.b2Vec2.prototype,\"Clone\",box2d.b2Vec2.prototype.Clone);\nbox2d.b2Vec2.prototype.SetZero=function(){this.y=this.x=0;return this};goog.exportProperty(box2d.b2Vec2.prototype,\"SetZero\",box2d.b2Vec2.prototype.SetZero);box2d.b2Vec2.prototype.SetXY=function(a,b){this.x=a;this.y=b;return this};goog.exportProperty(box2d.b2Vec2.prototype,\"SetXY\",box2d.b2Vec2.prototype.SetXY);box2d.b2Vec2.prototype.Copy=function(a){this.x=a.x;this.y=a.y;return this};goog.exportProperty(box2d.b2Vec2.prototype,\"Copy\",box2d.b2Vec2.prototype.Copy);\nbox2d.b2Vec2.prototype.SelfAdd=function(a){this.x+=a.x;this.y+=a.y;return this};goog.exportProperty(box2d.b2Vec2.prototype,\"SelfAdd\",box2d.b2Vec2.prototype.SelfAdd);box2d.b2Vec2.prototype.SelfAddXY=function(a,b){this.x+=a;this.y+=b;return this};goog.exportProperty(box2d.b2Vec2.prototype,\"SelfAddXY\",box2d.b2Vec2.prototype.SelfAddXY);box2d.b2Vec2.prototype.SelfSub=function(a){this.x-=a.x;this.y-=a.y;return this};goog.exportProperty(box2d.b2Vec2.prototype,\"SelfSub\",box2d.b2Vec2.prototype.SelfSub);\nbox2d.b2Vec2.prototype.SelfSubXY=function(a,b){this.x-=a;this.y-=b;return this};goog.exportProperty(box2d.b2Vec2.prototype,\"SelfSubXY\",box2d.b2Vec2.prototype.SelfSubXY);box2d.b2Vec2.prototype.SelfMul=function(a){this.x*=a;this.y*=a;return this};goog.exportProperty(box2d.b2Vec2.prototype,\"SelfMul\",box2d.b2Vec2.prototype.SelfMul);box2d.b2Vec2.prototype.SelfMulAdd=function(a,b){this.x+=a*b.x;this.y+=a*b.y;return this};goog.exportProperty(box2d.b2Vec2.prototype,\"SelfMulAdd\",box2d.b2Vec2.prototype.SelfMulAdd);\nbox2d.b2Vec2.prototype.SelfMulSub=function(a,b){this.x-=a*b.x;this.y-=a*b.y;return this};goog.exportProperty(box2d.b2Vec2.prototype,\"SelfMulSub\",box2d.b2Vec2.prototype.SelfMulSub);box2d.b2Vec2.prototype.Dot=function(a){return this.x*a.x+this.y*a.y};goog.exportProperty(box2d.b2Vec2.prototype,\"Dot\",box2d.b2Vec2.prototype.Dot);box2d.b2Vec2.prototype.Cross=function(a){return this.x*a.y-this.y*a.x};goog.exportProperty(box2d.b2Vec2.prototype,\"Cross\",box2d.b2Vec2.prototype.Cross);\nbox2d.b2Vec2.prototype.Length=function(){var a=this.x,b=this.y;return Math.sqrt(a*a+b*b)};goog.exportProperty(box2d.b2Vec2.prototype,\"Length\",box2d.b2Vec2.prototype.Length);box2d.b2Vec2.prototype.GetLength=box2d.b2Vec2.prototype.Length;goog.exportProperty(box2d.b2Vec2.prototype,\"GetLength\",box2d.b2Vec2.prototype.GetLength);box2d.b2Vec2.prototype.LengthSquared=function(){var a=this.x,b=this.y;return a*a+b*b};goog.exportProperty(box2d.b2Vec2.prototype,\"LengthSquared\",box2d.b2Vec2.prototype.LengthSquared);\nbox2d.b2Vec2.prototype.GetLengthSquared=box2d.b2Vec2.prototype.LengthSquared;goog.exportProperty(box2d.b2Vec2.prototype,\"GetLengthSquared\",box2d.b2Vec2.prototype.GetLengthSquared);box2d.b2Vec2.prototype.Normalize=function(){var a=this.GetLength();if(a>=box2d.b2_epsilon){var b=1/a;this.x*=b;this.y*=b}return a};goog.exportProperty(box2d.b2Vec2.prototype,\"Normalize\",box2d.b2Vec2.prototype.Normalize);\nbox2d.b2Vec2.prototype.SelfNormalize=function(){var a=this.GetLength();a>=box2d.b2_epsilon&&(a=1/a,this.x*=a,this.y*=a);return this};goog.exportProperty(box2d.b2Vec2.prototype,\"SelfNormalize\",box2d.b2Vec2.prototype.SelfNormalize);box2d.b2Vec2.prototype.SelfRotate=function(a,b){var c=this.x,e=this.y;this.x=a*c-b*e;this.y=b*c+a*e;return this};goog.exportProperty(box2d.b2Vec2.prototype,\"SelfRotate\",box2d.b2Vec2.prototype.SelfRotate);\nbox2d.b2Vec2.prototype.SelfRotateRadians=function(a){return this.SelfRotate(Math.cos(a),Math.sin(a))};goog.exportProperty(box2d.b2Vec2.prototype,\"SelfRotateRadians\",box2d.b2Vec2.prototype.SelfRotateRadians);box2d.b2Vec2.prototype.SelfRotateDegrees=function(a){return this.SelfRotateRadians(box2d.b2DegToRad(a))};goog.exportProperty(box2d.b2Vec2.prototype,\"SelfRotateDegrees\",box2d.b2Vec2.prototype.SelfRotateDegrees);box2d.b2Vec2.prototype.IsValid=function(){return isFinite(this.x)&&isFinite(this.y)};\ngoog.exportProperty(box2d.b2Vec2.prototype,\"IsValid\",box2d.b2Vec2.prototype.IsValid);box2d.b2Vec2.prototype.SelfCrossVS=function(a){var b=this.x;this.x=a*this.y;this.y=-a*b;return this};goog.exportProperty(box2d.b2Vec2.prototype,\"SelfCrossVS\",box2d.b2Vec2.prototype.SelfCrossVS);box2d.b2Vec2.prototype.SelfCrossSV=function(a){var b=this.x;this.x=-a*this.y;this.y=a*b;return this};goog.exportProperty(box2d.b2Vec2.prototype,\"SelfCrossSV\",box2d.b2Vec2.prototype.SelfCrossSV);\nbox2d.b2Vec2.prototype.SelfMinV=function(a){this.x=box2d.b2Min(this.x,a.x);this.y=box2d.b2Min(this.y,a.y);return this};goog.exportProperty(box2d.b2Vec2.prototype,\"SelfMinV\",box2d.b2Vec2.prototype.SelfMinV);box2d.b2Vec2.prototype.SelfMaxV=function(a){this.x=box2d.b2Max(this.x,a.x);this.y=box2d.b2Max(this.y,a.y);return this};goog.exportProperty(box2d.b2Vec2.prototype,\"SelfMaxV\",box2d.b2Vec2.prototype.SelfMaxV);\nbox2d.b2Vec2.prototype.SelfAbs=function(){this.x=box2d.b2Abs(this.x);this.y=box2d.b2Abs(this.y);return this};goog.exportProperty(box2d.b2Vec2.prototype,\"SelfAbs\",box2d.b2Vec2.prototype.SelfAbs);box2d.b2Vec2.prototype.SelfNeg=function(){this.x=-this.x;this.y=-this.y;return this};goog.exportProperty(box2d.b2Vec2.prototype,\"SelfNeg\",box2d.b2Vec2.prototype.SelfNeg);box2d.b2Vec2.prototype.SelfSkew=function(){var a=this.x;this.x=-this.y;this.y=a;return this};\ngoog.exportProperty(box2d.b2Vec2.prototype,\"SelfSkew\",box2d.b2Vec2.prototype.SelfSkew);box2d.b2AbsV=function(a,b){b.x=box2d.b2Abs(a.x);b.y=box2d.b2Abs(a.y);return b};goog.exportSymbol(\"box2d.b2AbsV\",box2d.b2AbsV);box2d.b2MinV=function(a,b,c){c.x=box2d.b2Min(a.x,b.x);c.y=box2d.b2Min(a.y,b.y);return c};goog.exportSymbol(\"box2d.b2MinV\",box2d.b2MinV);box2d.b2MaxV=function(a,b,c){c.x=box2d.b2Max(a.x,b.x);c.y=box2d.b2Max(a.y,b.y);return c};goog.exportSymbol(\"box2d.b2MaxV\",box2d.b2MaxV);\nbox2d.b2ClampV=function(a,b,c,e){e.x=box2d.b2Clamp(a.x,b.x,c.x);e.y=box2d.b2Clamp(a.y,b.y,c.y);return e};goog.exportSymbol(\"box2d.b2ClampV\",box2d.b2ClampV);box2d.b2RotateV=function(a,b,c,e){var d=a.x;a=a.y;e.x=b*d-c*a;e.y=c*d+b*a;return e};goog.exportSymbol(\"box2d.b2RotateV\",box2d.b2RotateV);box2d.b2RotateRadiansV=function(a,b,c){return box2d.b2RotateV(a,Math.cos(b),Math.sin(b),c)};goog.exportSymbol(\"box2d.b2RotateRadiansV\",box2d.b2RotateRadiansV);\nbox2d.b2RotateDegreesV=function(a,b,c){return box2d.b2RotateRadiansV(a,box2d.b2DegToRad(b),c)};goog.exportSymbol(\"box2d.b2RotateDegreesV\",box2d.b2RotateDegreesV);box2d.b2DotVV=function(a,b){return a.x*b.x+a.y*b.y};goog.exportSymbol(\"box2d.b2DotVV\",box2d.b2DotVV);box2d.b2CrossVV=function(a,b){return a.x*b.y-a.y*b.x};goog.exportSymbol(\"box2d.b2CrossVV\",box2d.b2CrossVV);box2d.b2CrossVS=function(a,b,c){var e=a.x;c.x=b*a.y;c.y=-b*e;return c};goog.exportSymbol(\"box2d.b2CrossVS\",box2d.b2CrossVS);\nbox2d.b2CrossVOne=function(a,b){var c=a.x;b.x=a.y;b.y=-c;return b};goog.exportSymbol(\"box2d.b2CrossVOne\",box2d.b2CrossVOne);box2d.b2CrossSV=function(a,b,c){var e=b.x;c.x=-a*b.y;c.y=a*e;return c};goog.exportSymbol(\"box2d.b2CrossSV\",box2d.b2CrossSV);box2d.b2CrossOneV=function(a,b){var c=a.x;b.x=-a.y;b.y=c;return b};goog.exportSymbol(\"box2d.b2CrossOneV\",box2d.b2CrossOneV);box2d.b2AddVV=function(a,b,c){c.x=a.x+b.x;c.y=a.y+b.y;return c};goog.exportSymbol(\"box2d.b2AddVV\",box2d.b2AddVV);\nbox2d.b2SubVV=function(a,b,c){c.x=a.x-b.x;c.y=a.y-b.y;return c};goog.exportSymbol(\"box2d.b2SubVV\",box2d.b2SubVV);box2d.b2MulSV=function(a,b,c){c.x=b.x*a;c.y=b.y*a;return c};goog.exportSymbol(\"box2d.b2MulSV\",box2d.b2MulSV);box2d.b2AddVMulSV=function(a,b,c,e){e.x=a.x+b*c.x;e.y=a.y+b*c.y;return e};goog.exportSymbol(\"box2d.b2AddVMulSV\",box2d.b2AddVMulSV);box2d.b2SubVMulSV=function(a,b,c,e){e.x=a.x-b*c.x;e.y=a.y-b*c.y;return e};goog.exportSymbol(\"box2d.b2SubVMulSV\",box2d.b2SubVMulSV);\nbox2d.b2AddVCrossSV=function(a,b,c,e){var d=c.x;e.x=a.x-b*c.y;e.y=a.y+b*d;return e};goog.exportSymbol(\"box2d.b2AddVCrossSV\",box2d.b2AddVCrossSV);box2d.b2MidVV=function(a,b,c){c.x=0.5*(a.x+b.x);c.y=0.5*(a.y+b.y);return c};goog.exportSymbol(\"box2d.b2MidVV\",box2d.b2MidVV);box2d.b2ExtVV=function(a,b,c){c.x=0.5*(b.x-a.x);c.y=0.5*(b.y-a.y);return c};goog.exportSymbol(\"box2d.b2ExtVV\",box2d.b2ExtVV);box2d.b2IsEqualToV=function(a,b){return a.x===b.x&&a.y===b.y};goog.exportSymbol(\"box2d.b2IsEqualToV\",box2d.b2IsEqualToV);\nbox2d.b2DistanceVV=function(a,b){var c=a.x-b.x,e=a.y-b.y;return Math.sqrt(c*c+e*e)};goog.exportSymbol(\"box2d.b2DistanceVV\",box2d.b2DistanceVV);box2d.b2DistanceSquaredVV=function(a,b){var c=a.x-b.x,e=a.y-b.y;return c*c+e*e};goog.exportSymbol(\"box2d.b2DistanceSquaredVV\",box2d.b2DistanceSquaredVV);box2d.b2NegV=function(a,b){b.x=-a.x;b.y=-a.y;return b};goog.exportSymbol(\"box2d.b2NegV\",box2d.b2NegV);box2d.b2Vec3=function(a,b,c){this.x=a||0;this.y=b||0;this.z=c||0};goog.exportSymbol(\"box2d.b2Vec3\",box2d.b2Vec3);\nbox2d.b2Vec3.prototype.x=0;goog.exportProperty(box2d.b2Vec3.prototype,\"x\",box2d.b2Vec3.prototype.x);box2d.b2Vec3.prototype.y=0;goog.exportProperty(box2d.b2Vec3.prototype,\"y\",box2d.b2Vec3.prototype.y);box2d.b2Vec3.prototype.z=0;goog.exportProperty(box2d.b2Vec3.prototype,\"z\",box2d.b2Vec3.prototype.z);box2d.b2Vec3.ZERO=new box2d.b2Vec3;goog.exportProperty(box2d.b2Vec3,\"ZERO\",box2d.b2Vec3.ZERO);box2d.b2Vec3.s_t0=new box2d.b2Vec3;goog.exportProperty(box2d.b2Vec3,\"s_t0\",box2d.b2Vec3.s_t0);\nbox2d.b2Vec3.prototype.Clone=function(){return new box2d.b2Vec3(this.x,this.y,this.z)};goog.exportProperty(box2d.b2Vec3.prototype,\"Clone\",box2d.b2Vec3.prototype.Clone);box2d.b2Vec3.prototype.SetZero=function(){this.z=this.y=this.x=0;return this};goog.exportProperty(box2d.b2Vec3.prototype,\"SetZero\",box2d.b2Vec3.prototype.SetZero);box2d.b2Vec3.prototype.SetXYZ=function(a,b,c){this.x=a;this.y=b;this.z=c;return this};goog.exportProperty(box2d.b2Vec3.prototype,\"SetXYZ\",box2d.b2Vec3.prototype.SetXYZ);\nbox2d.b2Vec3.prototype.Copy=function(a){this.x=a.x;this.y=a.y;this.z=a.z;return this};goog.exportProperty(box2d.b2Vec3.prototype,\"Copy\",box2d.b2Vec3.prototype.Copy);box2d.b2Vec3.prototype.SelfNeg=function(){this.x=-this.x;this.y=-this.y;this.z=-this.z;return this};goog.exportProperty(box2d.b2Vec3.prototype,\"SelfNeg\",box2d.b2Vec3.prototype.SelfNeg);box2d.b2Vec3.prototype.SelfAdd=function(a){this.x+=a.x;this.y+=a.y;this.z+=a.z;return this};goog.exportProperty(box2d.b2Vec3.prototype,\"SelfAdd\",box2d.b2Vec3.prototype.SelfAdd);\nbox2d.b2Vec3.prototype.SelfAddXYZ=function(a,b,c){this.x+=a;this.y+=b;this.z+=c;return this};goog.exportProperty(box2d.b2Vec3.prototype,\"SelfAddXYZ\",box2d.b2Vec3.prototype.SelfAddXYZ);box2d.b2Vec3.prototype.SelfSub=function(a){this.x-=a.x;this.y-=a.y;this.z-=a.z;return this};goog.exportProperty(box2d.b2Vec3.prototype,\"SelfSub\",box2d.b2Vec3.prototype.SelfSub);box2d.b2Vec3.prototype.SelfSubXYZ=function(a,b,c){this.x-=a;this.y-=b;this.z-=c;return this};\ngoog.exportProperty(box2d.b2Vec3.prototype,\"SelfSubXYZ\",box2d.b2Vec3.prototype.SelfSubXYZ);box2d.b2Vec3.prototype.SelfMul=function(a){this.x*=a;this.y*=a;this.z*=a;return this};goog.exportProperty(box2d.b2Vec3.prototype,\"SelfMul\",box2d.b2Vec3.prototype.SelfMul);box2d.b2DotV3V3=function(a,b){return a.x*b.x+a.y*b.y+a.z*b.z};goog.exportSymbol(\"box2d.b2DotV3V3\",box2d.b2DotV3V3);box2d.b2CrossV3V3=function(a,b,c){var e=a.x,d=a.y;a=a.z;var f=b.x,g=b.y;b=b.z;c.x=d*b-a*g;c.y=a*f-e*b;c.z=e*g-d*f;return c};\ngoog.exportSymbol(\"box2d.b2CrossV3V3\",box2d.b2CrossV3V3);box2d.b2Mat22=function(){this.ex=new box2d.b2Vec2(1,0);this.ey=new box2d.b2Vec2(0,1)};goog.exportSymbol(\"box2d.b2Mat22\",box2d.b2Mat22);box2d.b2Mat22.prototype.ex=null;goog.exportProperty(box2d.b2Mat22.prototype,\"ex\",box2d.b2Mat22.prototype.ex);box2d.b2Mat22.prototype.ey=null;goog.exportProperty(box2d.b2Mat22.prototype,\"ey\",box2d.b2Mat22.prototype.ey);box2d.b2Mat22.IDENTITY=new box2d.b2Mat22;goog.exportProperty(box2d.b2Mat22,\"IDENTITY\",box2d.b2Mat22.IDENTITY);\nbox2d.b2Mat22.prototype.Clone=function(){return(new box2d.b2Mat22).Copy(this)};goog.exportProperty(box2d.b2Mat22.prototype,\"Clone\",box2d.b2Mat22.prototype.Clone);box2d.b2Mat22.FromVV=function(a,b){return(new box2d.b2Mat22).SetVV(a,b)};goog.exportProperty(box2d.b2Mat22,\"FromVV\",box2d.b2Mat22.FromVV);box2d.b2Mat22.FromSSSS=function(a,b,c,e){return(new box2d.b2Mat22).SetSSSS(a,b,c,e)};goog.exportProperty(box2d.b2Mat22,\"FromSSSS\",box2d.b2Mat22.FromSSSS);box2d.b2Mat22.FromAngleRadians=function(a){return(new box2d.b2Mat22).SetAngleRadians(a)};\ngoog.exportProperty(box2d.b2Mat22,\"FromAngleRadians\",box2d.b2Mat22.FromAngleRadians);box2d.b2Mat22.prototype.SetSSSS=function(a,b,c,e){this.ex.SetXY(a,c);this.ey.SetXY(b,e);return this};goog.exportProperty(box2d.b2Mat22.prototype,\"SetSSSS\",box2d.b2Mat22.prototype.SetSSSS);box2d.b2Mat22.prototype.SetVV=function(a,b){this.ex.Copy(a);this.ey.Copy(b);return this};goog.exportProperty(box2d.b2Mat22.prototype,\"SetVV\",box2d.b2Mat22.prototype.SetVV);\nbox2d.b2Mat22.prototype.SetAngle=function(a){var b=Math.cos(a);a=Math.sin(a);this.ex.SetXY(b,a);this.ey.SetXY(-a,b);return this};goog.exportProperty(box2d.b2Mat22.prototype,\"SetAngle\",box2d.b2Mat22.prototype.SetAngle);box2d.b2Mat22.prototype.SetAngleRadians=box2d.b2Mat22.prototype.SetAngle;box2d.b2Mat22.prototype.SetAngleDegrees=function(a){return this.SetAngle(box2d.b2DegToRad(a))};box2d.b2Mat22.prototype.Copy=function(a){this.ex.Copy(a.ex);this.ey.Copy(a.ey);return this};\ngoog.exportProperty(box2d.b2Mat22.prototype,\"Copy\",box2d.b2Mat22.prototype.Copy);box2d.b2Mat22.prototype.SetIdentity=function(){this.ex.SetXY(1,0);this.ey.SetXY(0,1);return this};goog.exportProperty(box2d.b2Mat22.prototype,\"SetIdentity\",box2d.b2Mat22.prototype.SetIdentity);box2d.b2Mat22.prototype.SetZero=function(){this.ex.SetZero();this.ey.SetZero();return this};goog.exportProperty(box2d.b2Mat22.prototype,\"SetZero\",box2d.b2Mat22.prototype.SetZero);\nbox2d.b2Mat22.prototype.GetAngle=function(){return Math.atan2(this.ex.y,this.ex.x)};goog.exportProperty(box2d.b2Mat22.prototype,\"GetAngle\",box2d.b2Mat22.prototype.GetAngle);box2d.b2Mat22.prototype.GetAngleRadians=box2d.b2Mat22.prototype.GetAngle;box2d.b2Mat22.prototype.GetInverse=function(a){var b=this.ex.x,c=this.ey.x,e=this.ex.y,d=this.ey.y,f=b*d-c*e;0!==f&&(f=1/f);a.ex.x=f*d;a.ey.x=-f*c;a.ex.y=-f*e;a.ey.y=f*b;return a};goog.exportProperty(box2d.b2Mat22.prototype,\"GetInverse\",box2d.b2Mat22.prototype.GetInverse);\nbox2d.b2Mat22.prototype.Solve=function(a,b,c){var e=this.ex.x,d=this.ey.x,f=this.ex.y,g=this.ey.y,h=e*g-d*f;0!==h&&(h=1/h);c.x=h*(g*a-d*b);c.y=h*(e*b-f*a);return c};goog.exportProperty(box2d.b2Mat22.prototype,\"Solve\",box2d.b2Mat22.prototype.Solve);box2d.b2Mat22.prototype.SelfAbs=function(){this.ex.SelfAbs();this.ey.SelfAbs();return this};goog.exportProperty(box2d.b2Mat22.prototype,\"SelfAbs\",box2d.b2Mat22.prototype.SelfAbs);box2d.b2Mat22.prototype.SelfInv=function(){return this.GetInverse(this)};\ngoog.exportProperty(box2d.b2Mat22.prototype,\"SelfInv\",box2d.b2Mat22.prototype.SelfInv);box2d.b2Mat22.prototype.SelfAddM=function(a){this.ex.SelfAdd(a.ex);this.ey.SelfAdd(a.ey);return this};goog.exportProperty(box2d.b2Mat22.prototype,\"SelfAddM\",box2d.b2Mat22.prototype.SelfAddM);box2d.b2Mat22.prototype.SelfSubM=function(a){this.ex.SelfSub(a.ex);this.ey.SelfSub(a.ey);return this};goog.exportProperty(box2d.b2Mat22.prototype,\"SelfSubM\",box2d.b2Mat22.prototype.SelfSubM);\nbox2d.b2AbsM=function(a,b){var c=a.ex,e=a.ey;b.ex.x=box2d.b2Abs(c.x);b.ex.y=box2d.b2Abs(c.y);b.ey.x=box2d.b2Abs(e.x);b.ey.y=box2d.b2Abs(e.y);return b};goog.exportSymbol(\"box2d.b2AbsM\",box2d.b2AbsM);box2d.b2MulMV=function(a,b,c){var e=a.ex;a=a.ey;var d=b.x;b=b.y;c.x=e.x*d+a.x*b;c.y=e.y*d+a.y*b;return c};goog.exportSymbol(\"box2d.b2MulMV\",box2d.b2MulMV);box2d.b2MulTMV=function(a,b,c){var e=a.ex;a=a.ey;var d=b.x;b=b.y;c.x=e.x*d+e.y*b;c.y=a.x*d+a.y*b;return c};goog.exportSymbol(\"box2d.b2MulTMV\",box2d.b2MulTMV);\nbox2d.b2AddMM=function(a,b,c){var e=a.ex;a=a.ey;var d=b.ex;b=b.ey;c.ex.x=e.x+d.x;c.ex.y=e.y+d.y;c.ey.x=a.x+b.x;c.ey.y=a.y+b.y;return c};goog.exportSymbol(\"box2d.b2AddMM\",box2d.b2AddMM);box2d.b2MulMM=function(a,b,c){var e=a.ex.x,d=a.ex.y,f=a.ey.x;a=a.ey.y;var g=b.ex.x,h=b.ex.y,l=b.ey.x;b=b.ey.y;c.ex.x=e*g+f*h;c.ex.y=d*g+a*h;c.ey.x=e*l+f*b;c.ey.y=d*l+a*b;return c};goog.exportSymbol(\"box2d.b2MulMM\",box2d.b2MulMM);\nbox2d.b2MulTMM=function(a,b,c){var e=a.ex.x,d=a.ex.y,f=a.ey.x;a=a.ey.y;var g=b.ex.x,h=b.ex.y,l=b.ey.x;b=b.ey.y;c.ex.x=e*g+d*h;c.ex.y=f*g+a*h;c.ey.x=e*l+d*b;c.ey.y=f*l+a*b;return c};goog.exportSymbol(\"box2d.b2MulTMM\",box2d.b2MulTMM);box2d.b2Mat33=function(){this.ex=new box2d.b2Vec3(1,0,0);this.ey=new box2d.b2Vec3(0,1,0);this.ez=new box2d.b2Vec3(0,0,1)};goog.exportSymbol(\"box2d.b2Mat33\",box2d.b2Mat33);box2d.b2Mat33.prototype.ex=null;goog.exportProperty(box2d.b2Mat33.prototype,\"ex\",box2d.b2Mat33.prototype.ex);\nbox2d.b2Mat33.prototype.ey=null;goog.exportProperty(box2d.b2Mat33.prototype,\"ey\",box2d.b2Mat33.prototype.ey);box2d.b2Mat33.prototype.ez=null;goog.exportProperty(box2d.b2Mat33.prototype,\"ez\",box2d.b2Mat33.prototype.ez);box2d.b2Mat33.IDENTITY=new box2d.b2Mat33;goog.exportProperty(box2d.b2Mat33,\"IDENTITY\",box2d.b2Mat33.IDENTITY);box2d.b2Mat33.prototype.Clone=function(){return(new box2d.b2Mat33).Copy(this)};goog.exportProperty(box2d.b2Mat33.prototype,\"Clone\",box2d.b2Mat33.prototype.Clone);\nbox2d.b2Mat33.prototype.SetVVV=function(a,b,c){this.ex.Copy(a);this.ey.Copy(b);this.ez.Copy(c);return this};goog.exportProperty(box2d.b2Mat33.prototype,\"SetVVV\",box2d.b2Mat33.prototype.SetVVV);box2d.b2Mat33.prototype.Copy=function(a){this.ex.Copy(a.ex);this.ey.Copy(a.ey);this.ez.Copy(a.ez);return this};goog.exportProperty(box2d.b2Mat33.prototype,\"Copy\",box2d.b2Mat33.prototype.Copy);box2d.b2Mat33.prototype.SetIdentity=function(){this.ex.SetXYZ(1,0,0);this.ey.SetXYZ(0,1,0);this.ez.SetXYZ(0,0,1);return this};\ngoog.exportProperty(box2d.b2Mat33.prototype,\"SetIdentity\",box2d.b2Mat33.prototype.SetIdentity);box2d.b2Mat33.prototype.SetZero=function(){this.ex.SetZero();this.ey.SetZero();this.ez.SetZero();return this};goog.exportProperty(box2d.b2Mat33.prototype,\"SetZero\",box2d.b2Mat33.prototype.SetZero);box2d.b2Mat33.prototype.SelfAddM=function(a){this.ex.SelfAdd(a.ex);this.ey.SelfAdd(a.ey);this.ez.SelfAdd(a.ez);return this};goog.exportProperty(box2d.b2Mat33.prototype,\"SelfAddM\",box2d.b2Mat33.prototype.SelfAddM);\nbox2d.b2Mat33.prototype.Solve33=function(a,b,c,e){var d=this.ex.x,f=this.ex.y,g=this.ex.z,h=this.ey.x,l=this.ey.y,k=this.ey.z,m=this.ez.x,n=this.ez.y,p=this.ez.z,q=d*(l*p-k*n)+f*(k*m-h*p)+g*(h*n-l*m);0!==q&&(q=1/q);e.x=q*(a*(l*p-k*n)+b*(k*m-h*p)+c*(h*n-l*m));e.y=q*(d*(b*p-c*n)+f*(c*m-a*p)+g*(a*n-b*m));e.z=q*(d*(l*c-k*b)+f*(k*a-h*c)+g*(h*b-l*a));return e};goog.exportProperty(box2d.b2Mat33.prototype,\"Solve33\",box2d.b2Mat33.prototype.Solve33);\nbox2d.b2Mat33.prototype.Solve22=function(a,b,c){var e=this.ex.x,d=this.ey.x,f=this.ex.y,g=this.ey.y,h=e*g-d*f;0!==h&&(h=1/h);c.x=h*(g*a-d*b);c.y=h*(e*b-f*a);return c};goog.exportProperty(box2d.b2Mat33.prototype,\"Solve22\",box2d.b2Mat33.prototype.Solve22);box2d.b2Mat33.prototype.GetInverse22=function(a){var b=this.ex.x,c=this.ey.x,e=this.ex.y,d=this.ey.y,f=b*d-c*e;0!==f&&(f=1/f);a.ex.x=f*d;a.ey.x=-f*c;a.ex.z=0;a.ex.y=-f*e;a.ey.y=f*b;a.ey.z=0;a.ez.x=0;a.ez.y=0;a.ez.z=0};\ngoog.exportProperty(box2d.b2Mat33.prototype,\"GetInverse22\",box2d.b2Mat33.prototype.GetInverse22);box2d.b2Mat33.prototype.GetSymInverse33=function(a){var b=box2d.b2DotV3V3(this.ex,box2d.b2CrossV3V3(this.ey,this.ez,box2d.b2Vec3.s_t0));0!==b&&(b=1/b);var c=this.ex.x,e=this.ey.x,d=this.ez.x,f=this.ey.y,g=this.ez.y,h=this.ez.z;a.ex.x=b*(f*h-g*g);a.ex.y=b*(d*g-e*h);a.ex.z=b*(e*g-d*f);a.ey.x=a.ex.y;a.ey.y=b*(c*h-d*d);a.ey.z=b*(d*e-c*g);a.ez.x=a.ex.z;a.ez.y=a.ey.z;a.ez.z=b*(c*f-e*e)};\ngoog.exportProperty(box2d.b2Mat33.prototype,\"GetSymInverse33\",box2d.b2Mat33.prototype.GetSymInverse33);box2d.b2MulM33V3=function(a,b,c){var e=b.x,d=b.y;b=b.z;c.x=a.ex.x*e+a.ey.x*d+a.ez.x*b;c.y=a.ex.y*e+a.ey.y*d+a.ez.y*b;c.z=a.ex.z*e+a.ey.z*d+a.ez.z*b;return c};goog.exportSymbol(\"box2d.b2MulM33V3\",box2d.b2MulM33V3);box2d.b2MulM33XYZ=function(a,b,c,e,d){d.x=a.ex.x*b+a.ey.x*c+a.ez.x*e;d.y=a.ex.y*b+a.ey.y*c+a.ez.y*e;d.z=a.ex.z*b+a.ey.z*c+a.ez.z*e;return d};goog.exportSymbol(\"box2d.b2MulM33XYZ\",box2d.b2MulM33XYZ);\nbox2d.b2MulM33V2=function(a,b,c){var e=b.x;b=b.y;c.x=a.ex.x*e+a.ey.x*b;c.y=a.ex.y*e+a.ey.y*b;return c};goog.exportSymbol(\"box2d.b2MulM33V2\",box2d.b2MulM33V2);box2d.b2MulM33XY=function(a,b,c,e){e.x=a.ex.x*b+a.ey.x*c;e.y=a.ex.y*b+a.ey.y*c;return e};goog.exportSymbol(\"box2d.b2MulM33XY\",box2d.b2MulM33XY);box2d.b2Rot=function(a){a&&(this.angle=a,this.s=Math.sin(a),this.c=Math.cos(a))};goog.exportSymbol(\"box2d.b2Rot\",box2d.b2Rot);box2d.b2Rot.prototype.angle=0;\ngoog.exportProperty(box2d.b2Rot.prototype,\"angle\",box2d.b2Rot.prototype.angle);box2d.b2Rot.prototype.s=0;goog.exportProperty(box2d.b2Rot.prototype,\"s\",box2d.b2Rot.prototype.s);box2d.b2Rot.prototype.c=1;goog.exportProperty(box2d.b2Rot.prototype,\"c\",box2d.b2Rot.prototype.c);box2d.b2Rot.IDENTITY=new box2d.b2Rot;goog.exportProperty(box2d.b2Rot,\"IDENTITY\",box2d.b2Rot.IDENTITY);box2d.b2Rot.prototype.Clone=function(){return(new box2d.b2Rot).Copy(this)};goog.exportProperty(box2d.b2Rot.prototype,\"Clone\",box2d.b2Rot.prototype.Clone);\nbox2d.b2Rot.prototype.Copy=function(a){this.angle=a.angle;this.s=a.s;this.c=a.c;return this};goog.exportProperty(box2d.b2Rot.prototype,\"Copy\",box2d.b2Rot.prototype.Copy);box2d.b2Rot.prototype.SetAngle=function(a){this.angle!==a&&(this.angle=a,this.s=Math.sin(a),this.c=Math.cos(a));return this};goog.exportProperty(box2d.b2Rot.prototype,\"SetAngle\",box2d.b2Rot.prototype.SetAngle);box2d.b2Rot.prototype.SetAngleRadians=box2d.b2Rot.prototype.SetAngle;box2d.b2Rot.prototype.SetAngleDegrees=function(a){return this.SetAngle(box2d.b2DegToRad(a))};\nbox2d.b2Rot.prototype.SetIdentity=function(){this.s=this.angle=0;this.c=1;return this};goog.exportProperty(box2d.b2Rot.prototype,\"SetIdentity\",box2d.b2Rot.prototype.SetIdentity);box2d.b2Rot.prototype.GetAngle=function(){return this.angle};goog.exportProperty(box2d.b2Rot.prototype,\"GetAngle\",box2d.b2Rot.prototype.GetAngle);box2d.b2Rot.prototype.GetAngleRadians=box2d.b2Rot.prototype.GetAngle;box2d.b2Rot.prototype.GetAngleDegrees=function(){return box2d.b2RadToDeg(this.GetAngle())};\nbox2d.b2Rot.prototype.GetXAxis=function(a){a.x=this.c;a.y=this.s;return a};goog.exportProperty(box2d.b2Rot.prototype,\"GetXAxis\",box2d.b2Rot.prototype.GetXAxis);box2d.b2Rot.prototype.GetYAxis=function(a){a.x=-this.s;a.y=this.c;return a};goog.exportProperty(box2d.b2Rot.prototype,\"GetYAxis\",box2d.b2Rot.prototype.GetYAxis);\nbox2d.b2MulRR=function(a,b,c){var e=a.c,d=a.s,f=b.c,g=b.s;c.s=d*f+e*g;c.c=e*f-d*g;for(c.angle=a.angle+b.angle;c.angle<-box2d.b2_pi;)c.angle+=box2d.b2_two_pi;for(;c.angle>=box2d.b2_pi;)c.angle-=box2d.b2_two_pi;return c};goog.exportSymbol(\"box2d.b2MulRR\",box2d.b2MulRR);box2d.b2MulTRR=function(a,b,c){var e=a.c,d=a.s,f=b.c,g=b.s;c.s=e*g-d*f;c.c=e*f+d*g;for(c.angle=a.angle-b.angle;c.angle<-box2d.b2_pi;)c.angle+=box2d.b2_two_pi;for(;c.angle>=box2d.b2_pi;)c.angle-=box2d.b2_two_pi;return c};\ngoog.exportSymbol(\"box2d.b2MulTRR\",box2d.b2MulTRR);box2d.b2MulRV=function(a,b,c){var e=a.c;a=a.s;var d=b.x;b=b.y;c.x=e*d-a*b;c.y=a*d+e*b;return c};goog.exportSymbol(\"box2d.b2MulRV\",box2d.b2MulRV);box2d.b2MulTRV=function(a,b,c){var e=a.c;a=a.s;var d=b.x;b=b.y;c.x=e*d+a*b;c.y=-a*d+e*b;return c};goog.exportSymbol(\"box2d.b2MulTRV\",box2d.b2MulTRV);box2d.b2Transform=function(){this.p=new box2d.b2Vec2;this.q=new box2d.b2Rot};goog.exportSymbol(\"box2d.b2Transform\",box2d.b2Transform);\nbox2d.b2Transform.prototype.p=null;goog.exportProperty(box2d.b2Transform.prototype,\"p\",box2d.b2Transform.prototype.p);box2d.b2Transform.prototype.q=null;goog.exportProperty(box2d.b2Transform.prototype,\"q\",box2d.b2Transform.prototype.q);box2d.b2Transform.IDENTITY=new box2d.b2Transform;goog.exportProperty(box2d.b2Transform,\"IDENTITY\",box2d.b2Transform.IDENTITY);box2d.b2Transform.prototype.Clone=function(){return(new box2d.b2Transform).Copy(this)};\ngoog.exportProperty(box2d.b2Transform.prototype,\"Clone\",box2d.b2Transform.prototype.Clone);box2d.b2Transform.prototype.Copy=function(a){this.p.Copy(a.p);this.q.Copy(a.q);return this};goog.exportProperty(box2d.b2Transform.prototype,\"Copy\",box2d.b2Transform.prototype.Copy);box2d.b2Transform.prototype.SetIdentity=function(){this.p.SetZero();this.q.SetIdentity();return this};goog.exportProperty(box2d.b2Transform.prototype,\"SetIdentity\",box2d.b2Transform.prototype.SetIdentity);\nbox2d.b2Transform.prototype.SetPositionRotation=function(a,b){this.p.Copy(a);this.q.Copy(b);return this};goog.exportProperty(box2d.b2Transform.prototype,\"SetPositionRotation\",box2d.b2Transform.prototype.SetPositionRotation);box2d.b2Transform.prototype.SetPositionAngleRadians=function(a,b){this.p.Copy(a);this.q.SetAngleRadians(b);return this};goog.exportProperty(box2d.b2Transform.prototype,\"SetPositionAngleRadians\",box2d.b2Transform.prototype.SetPositionAngleRadians);\nbox2d.b2Transform.prototype.SetPosition=function(a){this.p.Copy(a);return this};goog.exportProperty(box2d.b2Transform.prototype,\"SetPosition\",box2d.b2Transform.prototype.SetPosition);box2d.b2Transform.prototype.SetPositionXY=function(a,b){this.p.SetXY(a,b);return this};goog.exportProperty(box2d.b2Transform.prototype,\"SetPositionXY\",box2d.b2Transform.prototype.SetPositionXY);box2d.b2Transform.prototype.SetRotation=function(a){this.q.Copy(a);return this};\ngoog.exportProperty(box2d.b2Transform.prototype,\"SetRotation\",box2d.b2Transform.prototype.SetRotation);box2d.b2Transform.prototype.SetRotationAngleRadians=function(a){this.q.SetAngleRadians(a);return this};goog.exportProperty(box2d.b2Transform.prototype,\"SetRotationAngleRadians\",box2d.b2Transform.prototype.SetRotationAngleRadians);box2d.b2Transform.prototype.GetPosition=function(){return this.p};goog.exportProperty(box2d.b2Transform.prototype,\"GetPosition\",box2d.b2Transform.prototype.GetPosition);\nbox2d.b2Transform.prototype.GetRotation=function(){return this.q};goog.exportProperty(box2d.b2Transform.prototype,\"GetRotation\",box2d.b2Transform.prototype.GetRotation);box2d.b2Transform.prototype.GetRotationAngle=function(){return this.q.GetAngle()};goog.exportProperty(box2d.b2Transform.prototype,\"GetRotationAngle\",box2d.b2Transform.prototype.GetRotationAngle);box2d.b2Transform.prototype.GetRotationAngleRadians=box2d.b2Transform.prototype.GetRotationAngle;box2d.b2Transform.prototype.GetAngle=function(){return this.q.GetAngle()};\ngoog.exportProperty(box2d.b2Transform.prototype,\"GetAngle\",box2d.b2Transform.prototype.GetAngle);box2d.b2Transform.prototype.GetAngleRadians=box2d.b2Transform.prototype.GetAngle;box2d.b2MulXV=function(a,b,c){var e=a.q.c,d=a.q.s,f=b.x;b=b.y;c.x=e*f-d*b+a.p.x;c.y=d*f+e*b+a.p.y;return c};goog.exportSymbol(\"box2d.b2MulXV\",box2d.b2MulXV);box2d.b2MulTXV=function(a,b,c){var e=a.q.c,d=a.q.s,f=b.x-a.p.x;a=b.y-a.p.y;c.x=e*f+d*a;c.y=-d*f+e*a;return c};goog.exportSymbol(\"box2d.b2MulTXV\",box2d.b2MulTXV);\nbox2d.b2MulXX=function(a,b,c){box2d.b2MulRR(a.q,b.q,c.q);box2d.b2AddVV(box2d.b2MulRV(a.q,b.p,c.p),a.p,c.p);return c};goog.exportSymbol(\"box2d.b2MulXX\",box2d.b2MulXX);box2d.b2MulTXX=function(a,b,c){box2d.b2MulTRR(a.q,b.q,c.q);box2d.b2MulTRV(a.q,box2d.b2SubVV(b.p,a.p,c.p),c.p);return c};goog.exportSymbol(\"box2d.b2MulTXX\",box2d.b2MulTXX);box2d.b2Sweep=function(){this.localCenter=new box2d.b2Vec2;this.c0=new box2d.b2Vec2;this.c=new box2d.b2Vec2};goog.exportSymbol(\"box2d.b2Sweep\",box2d.b2Sweep);\nbox2d.b2Sweep.prototype.localCenter=null;goog.exportProperty(box2d.b2Sweep.prototype,\"localCenter\",box2d.b2Sweep.prototype.localCenter);box2d.b2Sweep.prototype.c0=null;goog.exportProperty(box2d.b2Sweep.prototype,\"c0\",box2d.b2Sweep.prototype.c0);box2d.b2Sweep.prototype.c=null;goog.exportProperty(box2d.b2Sweep.prototype,\"c\",box2d.b2Sweep.prototype.c);box2d.b2Sweep.prototype.a0=0;goog.exportProperty(box2d.b2Sweep.prototype,\"a0\",box2d.b2Sweep.prototype.a0);box2d.b2Sweep.prototype.a=0;\ngoog.exportProperty(box2d.b2Sweep.prototype,\"a\",box2d.b2Sweep.prototype.a);box2d.b2Sweep.prototype.alpha0=0;goog.exportProperty(box2d.b2Sweep.prototype,\"alpha0\",box2d.b2Sweep.prototype.alpha0);box2d.b2Sweep.prototype.Clone=function(){return(new box2d.b2Sweep).Copy(this)};goog.exportProperty(box2d.b2Sweep.prototype,\"Clone\",box2d.b2Sweep.prototype.Clone);\nbox2d.b2Sweep.prototype.Copy=function(a){this.localCenter.Copy(a.localCenter);this.c0.Copy(a.c0);this.c.Copy(a.c);this.a0=a.a0;this.a=a.a;this.alpha0=a.alpha0;return this};goog.exportProperty(box2d.b2Sweep.prototype,\"Copy\",box2d.b2Sweep.prototype.Copy);box2d.b2Sweep.prototype.GetTransform=function(a,b){var c=1-b;a.p.x=c*this.c0.x+b*this.c.x;a.p.y=c*this.c0.y+b*this.c.y;a.q.SetAngleRadians(c*this.a0+b*this.a);a.p.SelfSub(box2d.b2MulRV(a.q,this.localCenter,box2d.b2Vec2.s_t0));return a};\ngoog.exportProperty(box2d.b2Sweep.prototype,\"GetTransform\",box2d.b2Sweep.prototype.GetTransform);box2d.b2Sweep.prototype.Advance=function(a){box2d.ENABLE_ASSERTS&&box2d.b2Assert(1>this.alpha0);var b=(a-this.alpha0)/(1-this.alpha0);this.c0.x+=b*(this.c.x-this.c0.x);this.c0.y+=b*(this.c.y-this.c0.y);this.a0+=b*(this.a-this.a0);this.alpha0=a};goog.exportProperty(box2d.b2Sweep.prototype,\"Advance\",box2d.b2Sweep.prototype.Advance);\nbox2d.b2Sweep.prototype.Normalize=function(){var a=box2d.b2_two_pi*Math.floor(this.a0/box2d.b2_two_pi);this.a0-=a;this.a-=a};goog.exportProperty(box2d.b2Sweep.prototype,\"Normalize\",box2d.b2Sweep.prototype.Normalize);box2d.b2ControllerEdge=function(){};goog.exportSymbol(\"box2d.b2ControllerEdge\",box2d.b2ControllerEdge);box2d.b2ControllerEdge.prototype.controller=null;goog.exportProperty(box2d.b2ControllerEdge.prototype,\"controller\",box2d.b2ControllerEdge.prototype.controller);box2d.b2ControllerEdge.prototype.body=null;goog.exportProperty(box2d.b2ControllerEdge.prototype,\"body\",box2d.b2ControllerEdge.prototype.body);box2d.b2ControllerEdge.prototype.prevBody=null;\ngoog.exportProperty(box2d.b2ControllerEdge.prototype,\"prevBody\",box2d.b2ControllerEdge.prototype.prevBody);box2d.b2ControllerEdge.prototype.nextBody=null;goog.exportProperty(box2d.b2ControllerEdge.prototype,\"nextBody\",box2d.b2ControllerEdge.prototype.nextBody);box2d.b2ControllerEdge.prototype.prevController=null;goog.exportProperty(box2d.b2ControllerEdge.prototype,\"prevController\",box2d.b2ControllerEdge.prototype.prevController);box2d.b2ControllerEdge.prototype.nextController=null;\ngoog.exportProperty(box2d.b2ControllerEdge.prototype,\"nextController\",box2d.b2ControllerEdge.prototype.nextController);box2d.b2Controller=function(){};goog.exportSymbol(\"box2d.b2Controller\",box2d.b2Controller);box2d.b2Controller.prototype.m_world=null;goog.exportProperty(box2d.b2Controller.prototype,\"m_world\",box2d.b2Controller.prototype.m_world);box2d.b2Controller.prototype.m_bodyList=null;goog.exportProperty(box2d.b2Controller.prototype,\"m_bodyList\",box2d.b2Controller.prototype.m_bodyList);\nbox2d.b2Controller.prototype.m_bodyCount=0;goog.exportProperty(box2d.b2Controller.prototype,\"m_bodyCount\",box2d.b2Controller.prototype.m_bodyCount);box2d.b2Controller.prototype.m_prev=null;goog.exportProperty(box2d.b2Controller.prototype,\"m_prev\",box2d.b2Controller.prototype.m_prev);box2d.b2Controller.prototype.m_next=null;goog.exportProperty(box2d.b2Controller.prototype,\"m_next\",box2d.b2Controller.prototype.m_next);box2d.b2Controller.prototype.Step=function(a){};\ngoog.exportProperty(box2d.b2Controller.prototype,\"Step\",box2d.b2Controller.prototype.Step);box2d.b2Controller.prototype.Draw=function(a){};goog.exportProperty(box2d.b2Controller.prototype,\"Draw\",box2d.b2Controller.prototype.Draw);box2d.b2Controller.prototype.GetNext=function(){return this.m_next};goog.exportProperty(box2d.b2Controller.prototype,\"GetNext\",box2d.b2Controller.prototype.GetNext);box2d.b2Controller.prototype.GetPrev=function(){return this.m_prev};\ngoog.exportProperty(box2d.b2Controller.prototype,\"GetPrev\",box2d.b2Controller.prototype.GetPrev);box2d.b2Controller.prototype.GetWorld=function(){return this.m_world};goog.exportProperty(box2d.b2Controller.prototype,\"GetWorld\",box2d.b2Controller.prototype.GetWorld);box2d.b2Controller.prototype.GetBodyList=function(){return this.m_bodyList};goog.exportProperty(box2d.b2Controller.prototype,\"GetBodyList\",box2d.b2Controller.prototype.GetBodyList);\nbox2d.b2Controller.prototype.AddBody=function(a){var b=new box2d.b2ControllerEdge;b.body=a;b.controller=this;b.nextBody=this.m_bodyList;b.prevBody=null;this.m_bodyList&&(this.m_bodyList.prevBody=b);this.m_bodyList=b;++this.m_bodyCount;b.nextController=a.m_controllerList;b.prevController=null;a.m_controllerList&&(a.m_controllerList.prevController=b);a.m_controllerList=b;++a.m_controllerCount};goog.exportProperty(box2d.b2Controller.prototype,\"AddBody\",box2d.b2Controller.prototype.AddBody);\nbox2d.b2Controller.prototype.RemoveBody=function(a){box2d.ENABLE_ASSERTS&&box2d.b2Assert(0<this.m_bodyCount);for(var b=this.m_bodyList;b&&b.body!==a;)b=b.nextBody;box2d.ENABLE_ASSERTS&&box2d.b2Assert(null!==b);b.prevBody&&(b.prevBody.nextBody=b.nextBody);b.nextBody&&(b.nextBody.prevBody=b.prevBody);this.m_bodyList===b&&(this.m_bodyList=b.nextBody);--this.m_bodyCount;b.nextController&&(b.nextController.prevController=b.prevController);b.prevController&&(b.prevController.nextController=b.nextController);\na.m_controllerList===b&&(a.m_controllerList=b.nextController);--a.m_controllerCount};goog.exportProperty(box2d.b2Controller.prototype,\"RemoveBody\",box2d.b2Controller.prototype.RemoveBody);box2d.b2Controller.prototype.Clear=function(){for(;this.m_bodyList;)this.RemoveBody(this.m_bodyList.body);this.m_bodyCount=0};goog.exportProperty(box2d.b2Controller.prototype,\"Clear\",box2d.b2Controller.prototype.Clear);box2d.b2ConstantAccelController=function(){box2d.b2Controller.call(this);this.A=new box2d.b2Vec2(0,0)};goog.inherits(box2d.b2ConstantAccelController,box2d.b2Controller);goog.exportSymbol(\"box2d.b2ConstantAccelController\",box2d.b2ConstantAccelController);box2d.b2ConstantAccelController.prototype.A=null;goog.exportProperty(box2d.b2ConstantAccelController.prototype,\"A\",box2d.b2ConstantAccelController.prototype.A);\nbox2d.b2ConstantAccelController.prototype.Step=function(a){a=box2d.b2MulSV(a.dt,this.A,box2d.b2ConstantAccelController.prototype.Step.s_dtA);for(var b=this.m_bodyList;b;b=b.nextBody){var c=b.body;c.IsAwake()&&c.SetLinearVelocity(box2d.b2AddVV(c.GetLinearVelocity(),a,box2d.b2Vec2.s_t0))}};goog.exportProperty(box2d.b2ConstantAccelController.prototype,\"Step\",box2d.b2ConstantAccelController.prototype.Step);box2d.b2ConstantAccelController.prototype.Step.s_dtA=new box2d.b2Vec2;box2d.b2JointType={e_unknownJoint:0,e_revoluteJoint:1,e_prismaticJoint:2,e_distanceJoint:3,e_pulleyJoint:4,e_mouseJoint:5,e_gearJoint:6,e_wheelJoint:7,e_weldJoint:8,e_frictionJoint:9,e_ropeJoint:10,e_motorJoint:11,e_areaJoint:12};goog.exportSymbol(\"box2d.b2JointType\",box2d.b2JointType);goog.exportProperty(box2d.b2JointType,\"e_unknownJoint\",box2d.b2JointType.e_unknownJoint);goog.exportProperty(box2d.b2JointType,\"e_revoluteJoint\",box2d.b2JointType.e_revoluteJoint);\ngoog.exportProperty(box2d.b2JointType,\"e_prismaticJoint\",box2d.b2JointType.e_prismaticJoint);goog.exportProperty(box2d.b2JointType,\"e_distanceJoint\",box2d.b2JointType.e_distanceJoint);goog.exportProperty(box2d.b2JointType,\"e_pulleyJoint\",box2d.b2JointType.e_pulleyJoint);goog.exportProperty(box2d.b2JointType,\"e_mouseJoint\",box2d.b2JointType.e_mouseJoint);goog.exportProperty(box2d.b2JointType,\"e_gearJoint\",box2d.b2JointType.e_gearJoint);goog.exportProperty(box2d.b2JointType,\"e_wheelJoint\",box2d.b2JointType.e_wheelJoint);\ngoog.exportProperty(box2d.b2JointType,\"e_weldJoint\",box2d.b2JointType.e_weldJoint);goog.exportProperty(box2d.b2JointType,\"e_frictionJoint\",box2d.b2JointType.e_frictionJoint);goog.exportProperty(box2d.b2JointType,\"e_ropeJoint\",box2d.b2JointType.e_ropeJoint);goog.exportProperty(box2d.b2JointType,\"e_motorJoint\",box2d.b2JointType.e_motorJoint);goog.exportProperty(box2d.b2JointType,\"e_areaJoint\",box2d.b2JointType.e_areaJoint);box2d.b2LimitState={e_inactiveLimit:0,e_atLowerLimit:1,e_atUpperLimit:2,e_equalLimits:3};\ngoog.exportSymbol(\"box2d.b2LimitState\",box2d.b2LimitState);goog.exportProperty(box2d.b2LimitState,\"e_inactiveLimit\",box2d.b2LimitState.e_inactiveLimit);goog.exportProperty(box2d.b2LimitState,\"e_atLowerLimit\",box2d.b2LimitState.e_atLowerLimit);goog.exportProperty(box2d.b2LimitState,\"e_atUpperLimit\",box2d.b2LimitState.e_atUpperLimit);goog.exportProperty(box2d.b2LimitState,\"e_equalLimits\",box2d.b2LimitState.e_equalLimits);box2d.b2Jacobian=function(){this.linear=new box2d.b2Vec2};\ngoog.exportSymbol(\"box2d.b2Jacobian\",box2d.b2Jacobian);box2d.b2Jacobian.prototype.linear=null;goog.exportProperty(box2d.b2Jacobian.prototype,\"linear\",box2d.b2Jacobian.prototype.linear);box2d.b2Jacobian.prototype.angularA=0;goog.exportProperty(box2d.b2Jacobian.prototype,\"angularA\",box2d.b2Jacobian.prototype.angularA);box2d.b2Jacobian.prototype.angularB=0;goog.exportProperty(box2d.b2Jacobian.prototype,\"angularB\",box2d.b2Jacobian.prototype.angularB);\nbox2d.b2Jacobian.prototype.SetZero=function(){this.linear.SetZero();this.angularB=this.angularA=0;return this};goog.exportProperty(box2d.b2Jacobian.prototype,\"SetZero\",box2d.b2Jacobian.prototype.SetZero);box2d.b2Jacobian.prototype.Set=function(a,b,c){this.linear.Copy(a);this.angularA=b;this.angularB=c;return this};goog.exportProperty(box2d.b2Jacobian.prototype,\"Set\",box2d.b2Jacobian.prototype.Set);box2d.b2JointEdge=function(){};goog.exportSymbol(\"box2d.b2JointEdge\",box2d.b2JointEdge);\nbox2d.b2JointEdge.prototype.other=null;goog.exportProperty(box2d.b2JointEdge.prototype,\"other\",box2d.b2JointEdge.prototype.other);box2d.b2JointEdge.prototype.joint=null;goog.exportProperty(box2d.b2JointEdge.prototype,\"joint\",box2d.b2JointEdge.prototype.joint);box2d.b2JointEdge.prototype.prev=null;goog.exportProperty(box2d.b2JointEdge.prototype,\"prev\",box2d.b2JointEdge.prototype.prev);box2d.b2JointEdge.prototype.next=null;goog.exportProperty(box2d.b2JointEdge.prototype,\"next\",box2d.b2JointEdge.prototype.next);\nbox2d.b2JointDef=function(a){this.type=a};goog.exportSymbol(\"box2d.b2JointDef\",box2d.b2JointDef);box2d.b2JointDef.prototype.type=box2d.b2JointType.e_unknownJoint;goog.exportProperty(box2d.b2JointDef.prototype,\"type\",box2d.b2JointDef.prototype.type);box2d.b2JointDef.prototype.userData=null;goog.exportProperty(box2d.b2JointDef.prototype,\"userData\",box2d.b2JointDef.prototype.userData);box2d.b2JointDef.prototype.bodyA=null;goog.exportProperty(box2d.b2JointDef.prototype,\"bodyA\",box2d.b2JointDef.prototype.bodyA);\nbox2d.b2JointDef.prototype.bodyB=null;goog.exportProperty(box2d.b2JointDef.prototype,\"bodyB\",box2d.b2JointDef.prototype.bodyB);box2d.b2JointDef.prototype.collideConnected=!1;goog.exportProperty(box2d.b2JointDef.prototype,\"collideConnected\",box2d.b2JointDef.prototype.collideConnected);\nbox2d.b2Joint=function(a){box2d.ENABLE_ASSERTS&&box2d.b2Assert(a.bodyA!==a.bodyB);this.m_type=a.type;this.m_edgeA=new box2d.b2JointEdge;this.m_edgeB=new box2d.b2JointEdge;this.m_bodyA=a.bodyA;this.m_bodyB=a.bodyB;this.m_collideConnected=a.collideConnected;this.m_userData=a.userData};goog.exportSymbol(\"box2d.b2Joint\",box2d.b2Joint);box2d.b2Joint.prototype.m_type=box2d.b2JointType.e_unknownJoint;goog.exportProperty(box2d.b2Joint.prototype,\"m_type\",box2d.b2Joint.prototype.m_type);\nbox2d.b2Joint.prototype.m_prev=null;goog.exportProperty(box2d.b2Joint.prototype,\"m_prev\",box2d.b2Joint.prototype.m_prev);box2d.b2Joint.prototype.m_next=null;goog.exportProperty(box2d.b2Joint.prototype,\"m_next\",box2d.b2Joint.prototype.m_next);box2d.b2Joint.prototype.m_edgeA=null;goog.exportProperty(box2d.b2Joint.prototype,\"m_edgeA\",box2d.b2Joint.prototype.m_edgeA);box2d.b2Joint.prototype.m_edgeB=null;goog.exportProperty(box2d.b2Joint.prototype,\"m_edgeB\",box2d.b2Joint.prototype.m_edgeB);\nbox2d.b2Joint.prototype.m_bodyA=null;goog.exportProperty(box2d.b2Joint.prototype,\"m_bodyA\",box2d.b2Joint.prototype.m_bodyA);box2d.b2Joint.prototype.m_bodyB=null;goog.exportProperty(box2d.b2Joint.prototype,\"m_bodyB\",box2d.b2Joint.prototype.m_bodyB);box2d.b2Joint.prototype.m_index=0;goog.exportProperty(box2d.b2Joint.prototype,\"m_index\",box2d.b2Joint.prototype.m_index);box2d.b2Joint.prototype.m_islandFlag=!1;goog.exportProperty(box2d.b2Joint.prototype,\"m_islandFlag\",box2d.b2Joint.prototype.m_islandFlag);\nbox2d.b2Joint.prototype.m_collideConnected=!1;goog.exportProperty(box2d.b2Joint.prototype,\"m_collideConnected\",box2d.b2Joint.prototype.m_collideConnected);box2d.b2Joint.prototype.m_userData=null;goog.exportProperty(box2d.b2Joint.prototype,\"m_userData\",box2d.b2Joint.prototype.m_userData);box2d.b2Joint.prototype.GetAnchorA=function(a){return a.SetZero()};goog.exportProperty(box2d.b2Joint.prototype,\"GetAnchorA\",box2d.b2Joint.prototype.GetAnchorA);box2d.b2Joint.prototype.GetAnchorB=function(a){return a.SetZero()};\ngoog.exportProperty(box2d.b2Joint.prototype,\"GetAnchorB\",box2d.b2Joint.prototype.GetAnchorB);box2d.b2Joint.prototype.GetReactionForce=function(a,b){return b.SetZero()};goog.exportProperty(box2d.b2Joint.prototype,\"GetReactionForce\",box2d.b2Joint.prototype.GetReactionForce);box2d.b2Joint.prototype.GetReactionTorque=function(a){return 0};goog.exportProperty(box2d.b2Joint.prototype,\"GetReactionTorque\",box2d.b2Joint.prototype.GetReactionTorque);box2d.b2Joint.prototype.InitVelocityConstraints=function(a){};\ngoog.exportProperty(box2d.b2Joint.prototype,\"InitVelocityConstraints\",box2d.b2Joint.prototype.InitVelocityConstraints);box2d.b2Joint.prototype.SolveVelocityConstraints=function(a){};goog.exportProperty(box2d.b2Joint.prototype,\"SolveVelocityConstraints\",box2d.b2Joint.prototype.SolveVelocityConstraints);box2d.b2Joint.prototype.SolvePositionConstraints=function(a){return!1};goog.exportProperty(box2d.b2Joint.prototype,\"SolvePositionConstraints\",box2d.b2Joint.prototype.SolvePositionConstraints);\nbox2d.b2Joint.prototype.GetType=function(){return this.m_type};goog.exportProperty(box2d.b2Joint.prototype,\"GetType\",box2d.b2Joint.prototype.GetType);box2d.b2Joint.prototype.GetBodyA=function(){return this.m_bodyA};goog.exportProperty(box2d.b2Joint.prototype,\"GetBodyA\",box2d.b2Joint.prototype.GetBodyA);box2d.b2Joint.prototype.GetBodyB=function(){return this.m_bodyB};goog.exportProperty(box2d.b2Joint.prototype,\"GetBodyB\",box2d.b2Joint.prototype.GetBodyB);box2d.b2Joint.prototype.GetNext=function(){return this.m_next};\ngoog.exportProperty(box2d.b2Joint.prototype,\"GetNext\",box2d.b2Joint.prototype.GetNext);box2d.b2Joint.prototype.GetUserData=function(){return this.m_userData};goog.exportProperty(box2d.b2Joint.prototype,\"GetUserData\",box2d.b2Joint.prototype.GetUserData);box2d.b2Joint.prototype.SetUserData=function(a){this.m_userData=a};goog.exportProperty(box2d.b2Joint.prototype,\"SetUserData\",box2d.b2Joint.prototype.SetUserData);box2d.b2Joint.prototype.GetCollideConnected=function(){return this.m_collideConnected};\ngoog.exportProperty(box2d.b2Joint.prototype,\"GetCollideConnected\",box2d.b2Joint.prototype.GetCollideConnected);box2d.b2Joint.prototype.Dump=function(){box2d.DEBUG&&box2d.b2Log(\"// Dump is not supported for this joint type.\\n\")};goog.exportProperty(box2d.b2Joint.prototype,\"Dump\",box2d.b2Joint.prototype.Dump);box2d.b2Joint.prototype.IsActive=function(){return this.m_bodyA.IsActive()&&this.m_bodyB.IsActive()};goog.exportProperty(box2d.b2Joint.prototype,\"IsActive\",box2d.b2Joint.prototype.IsActive);\nbox2d.b2Joint.prototype.ShiftOrigin=function(a){};goog.exportProperty(box2d.b2Joint.prototype,\"ShiftOrigin\",box2d.b2Joint.prototype.ShiftOrigin);box2d.b2RevoluteJointDef=function(){box2d.b2JointDef.call(this,box2d.b2JointType.e_revoluteJoint);this.localAnchorA=new box2d.b2Vec2(0,0);this.localAnchorB=new box2d.b2Vec2(0,0)};goog.inherits(box2d.b2RevoluteJointDef,box2d.b2JointDef);goog.exportSymbol(\"box2d.b2RevoluteJointDef\",box2d.b2RevoluteJointDef);box2d.b2RevoluteJointDef.prototype.localAnchorA=null;goog.exportProperty(box2d.b2RevoluteJointDef.prototype,\"localAnchorA\",box2d.b2RevoluteJointDef.prototype.localAnchorA);\nbox2d.b2RevoluteJointDef.prototype.localAnchorB=null;goog.exportProperty(box2d.b2RevoluteJointDef.prototype,\"localAnchorB\",box2d.b2RevoluteJointDef.prototype.localAnchorB);box2d.b2RevoluteJointDef.prototype.referenceAngle=0;goog.exportProperty(box2d.b2RevoluteJointDef.prototype,\"referenceAngle\",box2d.b2RevoluteJointDef.prototype.referenceAngle);box2d.b2RevoluteJointDef.prototype.enableLimit=!1;goog.exportProperty(box2d.b2RevoluteJointDef.prototype,\"enableLimit\",box2d.b2RevoluteJointDef.prototype.enableLimit);\nbox2d.b2RevoluteJointDef.prototype.lowerAngle=0;goog.exportProperty(box2d.b2RevoluteJointDef.prototype,\"lowerAngle\",box2d.b2RevoluteJointDef.prototype.lowerAngle);box2d.b2RevoluteJointDef.prototype.upperAngle=0;goog.exportProperty(box2d.b2RevoluteJointDef.prototype,\"upperAngle\",box2d.b2RevoluteJointDef.prototype.upperAngle);box2d.b2RevoluteJointDef.prototype.enableMotor=!1;goog.exportProperty(box2d.b2RevoluteJointDef.prototype,\"enableMotor\",box2d.b2RevoluteJointDef.prototype.enableMotor);\nbox2d.b2RevoluteJointDef.prototype.motorSpeed=0;goog.exportProperty(box2d.b2RevoluteJointDef.prototype,\"motorSpeed\",box2d.b2RevoluteJointDef.prototype.motorSpeed);box2d.b2RevoluteJointDef.prototype.maxMotorTorque=0;goog.exportProperty(box2d.b2RevoluteJointDef.prototype,\"maxMotorTorque\",box2d.b2RevoluteJointDef.prototype.maxMotorTorque);\nbox2d.b2RevoluteJointDef.prototype.Initialize=function(a,b,c){this.bodyA=a;this.bodyB=b;this.bodyA.GetLocalPoint(c,this.localAnchorA);this.bodyB.GetLocalPoint(c,this.localAnchorB);this.referenceAngle=this.bodyB.GetAngleRadians()-this.bodyA.GetAngleRadians()};goog.exportProperty(box2d.b2RevoluteJointDef.prototype,\"Initialize\",box2d.b2RevoluteJointDef.prototype.Initialize);\nbox2d.b2RevoluteJoint=function(a){box2d.b2Joint.call(this,a);this.m_localAnchorA=new box2d.b2Vec2;this.m_localAnchorB=new box2d.b2Vec2;this.m_impulse=new box2d.b2Vec3;this.m_rA=new box2d.b2Vec2;this.m_rB=new box2d.b2Vec2;this.m_localCenterA=new box2d.b2Vec2;this.m_localCenterB=new box2d.b2Vec2;this.m_mass=new box2d.b2Mat33;this.m_qA=new box2d.b2Rot;this.m_qB=new box2d.b2Rot;this.m_lalcA=new box2d.b2Vec2;this.m_lalcB=new box2d.b2Vec2;this.m_K=new box2d.b2Mat22;this.m_localAnchorA.Copy(a.localAnchorA);\nthis.m_localAnchorB.Copy(a.localAnchorB);this.m_referenceAngle=a.referenceAngle;this.m_impulse.SetZero();this.m_motorImpulse=0;this.m_lowerAngle=a.lowerAngle;this.m_upperAngle=a.upperAngle;this.m_maxMotorTorque=a.maxMotorTorque;this.m_motorSpeed=a.motorSpeed;this.m_enableLimit=a.enableLimit;this.m_enableMotor=a.enableMotor;this.m_limitState=box2d.b2LimitState.e_inactiveLimit};goog.inherits(box2d.b2RevoluteJoint,box2d.b2Joint);goog.exportSymbol(\"box2d.b2RevoluteJoint\",box2d.b2RevoluteJoint);\nbox2d.b2RevoluteJoint.prototype.m_localAnchorA=null;goog.exportProperty(box2d.b2RevoluteJoint.prototype,\"m_localAnchorA\",box2d.b2RevoluteJoint.prototype.m_localAnchorA);box2d.b2RevoluteJoint.prototype.m_localAnchorB=null;goog.exportProperty(box2d.b2RevoluteJoint.prototype,\"m_localAnchorB\",box2d.b2RevoluteJoint.prototype.m_localAnchorB);box2d.b2RevoluteJoint.prototype.m_impulse=null;goog.exportProperty(box2d.b2RevoluteJoint.prototype,\"m_impulse\",box2d.b2RevoluteJoint.prototype.m_impulse);\nbox2d.b2RevoluteJoint.prototype.m_motorImpulse=0;goog.exportProperty(box2d.b2RevoluteJoint.prototype,\"m_motorImpulse\",box2d.b2RevoluteJoint.prototype.m_motorImpulse);box2d.b2RevoluteJoint.prototype.m_enableMotor=!1;goog.exportProperty(box2d.b2RevoluteJoint.prototype,\"m_enableMotor\",box2d.b2RevoluteJoint.prototype.m_enableMotor);box2d.b2RevoluteJoint.prototype.m_maxMotorTorque=0;goog.exportProperty(box2d.b2RevoluteJoint.prototype,\"m_maxMotorTorque\",box2d.b2RevoluteJoint.prototype.m_maxMotorTorque);\nbox2d.b2RevoluteJoint.prototype.m_motorSpeed=0;goog.exportProperty(box2d.b2RevoluteJoint.prototype,\"m_motorSpeed\",box2d.b2RevoluteJoint.prototype.m_motorSpeed);box2d.b2RevoluteJoint.prototype.m_enableLimit=!1;goog.exportProperty(box2d.b2RevoluteJoint.prototype,\"m_enableLimit\",box2d.b2RevoluteJoint.prototype.m_enableLimit);box2d.b2RevoluteJoint.prototype.m_referenceAngle=0;goog.exportProperty(box2d.b2RevoluteJoint.prototype,\"m_referenceAngle\",box2d.b2RevoluteJoint.prototype.m_referenceAngle);\nbox2d.b2RevoluteJoint.prototype.m_lowerAngle=0;goog.exportProperty(box2d.b2RevoluteJoint.prototype,\"m_lowerAngle\",box2d.b2RevoluteJoint.prototype.m_lowerAngle);box2d.b2RevoluteJoint.prototype.m_upperAngle=0;goog.exportProperty(box2d.b2RevoluteJoint.prototype,\"m_upperAngle\",box2d.b2RevoluteJoint.prototype.m_upperAngle);box2d.b2RevoluteJoint.prototype.m_indexA=0;goog.exportProperty(box2d.b2RevoluteJoint.prototype,\"m_indexA\",box2d.b2RevoluteJoint.prototype.m_indexA);\nbox2d.b2RevoluteJoint.prototype.m_indexB=0;goog.exportProperty(box2d.b2RevoluteJoint.prototype,\"m_indexB\",box2d.b2RevoluteJoint.prototype.m_indexB);box2d.b2RevoluteJoint.prototype.m_rA=null;goog.exportProperty(box2d.b2RevoluteJoint.prototype,\"m_rA\",box2d.b2RevoluteJoint.prototype.m_rA);box2d.b2RevoluteJoint.prototype.m_rB=null;goog.exportProperty(box2d.b2RevoluteJoint.prototype,\"m_rB\",box2d.b2RevoluteJoint.prototype.m_rB);box2d.b2RevoluteJoint.prototype.m_localCenterA=null;\ngoog.exportProperty(box2d.b2RevoluteJoint.prototype,\"m_localCenterA\",box2d.b2RevoluteJoint.prototype.m_localCenterA);box2d.b2RevoluteJoint.prototype.m_localCenterB=null;goog.exportProperty(box2d.b2RevoluteJoint.prototype,\"m_localCenterB\",box2d.b2RevoluteJoint.prototype.m_localCenterB);box2d.b2RevoluteJoint.prototype.m_invMassA=0;goog.exportProperty(box2d.b2RevoluteJoint.prototype,\"m_invMassA\",box2d.b2RevoluteJoint.prototype.m_invMassA);box2d.b2RevoluteJoint.prototype.m_invMassB=0;\ngoog.exportProperty(box2d.b2RevoluteJoint.prototype,\"m_invMassB\",box2d.b2RevoluteJoint.prototype.m_invMassB);box2d.b2RevoluteJoint.prototype.m_invIA=0;goog.exportProperty(box2d.b2RevoluteJoint.prototype,\"m_invIA\",box2d.b2RevoluteJoint.prototype.m_invIA);box2d.b2RevoluteJoint.prototype.m_invIB=0;goog.exportProperty(box2d.b2RevoluteJoint.prototype,\"m_invIB\",box2d.b2RevoluteJoint.prototype.m_invIB);box2d.b2RevoluteJoint.prototype.m_mass=null;\ngoog.exportProperty(box2d.b2RevoluteJoint.prototype,\"m_mass\",box2d.b2RevoluteJoint.prototype.m_mass);box2d.b2RevoluteJoint.prototype.m_motorMass=0;goog.exportProperty(box2d.b2RevoluteJoint.prototype,\"m_motorMass\",box2d.b2RevoluteJoint.prototype.m_motorMass);box2d.b2RevoluteJoint.prototype.m_limitState=box2d.b2LimitState.e_inactiveLimit;goog.exportProperty(box2d.b2RevoluteJoint.prototype,\"m_limitState\",box2d.b2RevoluteJoint.prototype.m_limitState);box2d.b2RevoluteJoint.prototype.m_qA=null;\ngoog.exportProperty(box2d.b2RevoluteJoint.prototype,\"m_qA\",box2d.b2RevoluteJoint.prototype.m_qA);box2d.b2RevoluteJoint.prototype.m_qB=null;goog.exportProperty(box2d.b2RevoluteJoint.prototype,\"m_qB\",box2d.b2RevoluteJoint.prototype.m_qB);box2d.b2RevoluteJoint.prototype.m_lalcA=null;goog.exportProperty(box2d.b2RevoluteJoint.prototype,\"m_lalcA\",box2d.b2RevoluteJoint.prototype.m_lalcA);box2d.b2RevoluteJoint.prototype.m_lalcB=null;goog.exportProperty(box2d.b2RevoluteJoint.prototype,\"m_lalcB\",box2d.b2RevoluteJoint.prototype.m_lalcB);\nbox2d.b2RevoluteJoint.prototype.m_K=null;goog.exportProperty(box2d.b2RevoluteJoint.prototype,\"m_K\",box2d.b2RevoluteJoint.prototype.m_K);\nbox2d.b2RevoluteJoint.prototype.InitVelocityConstraints=function(a){this.m_indexA=this.m_bodyA.m_islandIndex;this.m_indexB=this.m_bodyB.m_islandIndex;this.m_localCenterA.Copy(this.m_bodyA.m_sweep.localCenter);this.m_localCenterB.Copy(this.m_bodyB.m_sweep.localCenter);this.m_invMassA=this.m_bodyA.m_invMass;this.m_invMassB=this.m_bodyB.m_invMass;this.m_invIA=this.m_bodyA.m_invI;this.m_invIB=this.m_bodyB.m_invI;var b=a.positions[this.m_indexA].a,c=a.velocities[this.m_indexA].v,e=a.velocities[this.m_indexA].w,\nd=a.positions[this.m_indexB].a,f=a.velocities[this.m_indexB].v,g=a.velocities[this.m_indexB].w,h=this.m_qA.SetAngleRadians(b),l=this.m_qB.SetAngleRadians(d);box2d.b2SubVV(this.m_localAnchorA,this.m_localCenterA,this.m_lalcA);box2d.b2MulRV(h,this.m_lalcA,this.m_rA);box2d.b2SubVV(this.m_localAnchorB,this.m_localCenterB,this.m_lalcB);box2d.b2MulRV(l,this.m_lalcB,this.m_rB);var h=this.m_invMassA,l=this.m_invMassB,k=this.m_invIA,m=this.m_invIB,n=0===k+m;this.m_mass.ex.x=h+l+this.m_rA.y*this.m_rA.y*k+this.m_rB.y*\nthis.m_rB.y*m;this.m_mass.ey.x=-this.m_rA.y*this.m_rA.x*k-this.m_rB.y*this.m_rB.x*m;this.m_mass.ez.x=-this.m_rA.y*k-this.m_rB.y*m;this.m_mass.ex.y=this.m_mass.ey.x;this.m_mass.ey.y=h+l+this.m_rA.x*this.m_rA.x*k+this.m_rB.x*this.m_rB.x*m;this.m_mass.ez.y=this.m_rA.x*k+this.m_rB.x*m;this.m_mass.ex.z=this.m_mass.ez.x;this.m_mass.ey.z=this.m_mass.ez.y;this.m_mass.ez.z=k+m;this.m_motorMass=k+m;0<this.m_motorMass&&(this.m_motorMass=1/this.m_motorMass);if(!1===this.m_enableMotor||n)this.m_motorImpulse=0;\nthis.m_enableLimit&&!1===n?(b=d-b-this.m_referenceAngle,box2d.b2Abs(this.m_upperAngle-this.m_lowerAngle)<2*box2d.b2_angularSlop?this.m_limitState=box2d.b2LimitState.e_equalLimits:b<=this.m_lowerAngle?(this.m_limitState!==box2d.b2LimitState.e_atLowerLimit&&(this.m_impulse.z=0),this.m_limitState=box2d.b2LimitState.e_atLowerLimit):b>=this.m_upperAngle?(this.m_limitState!==box2d.b2LimitState.e_atUpperLimit&&(this.m_impulse.z=0),this.m_limitState=box2d.b2LimitState.e_atUpperLimit):(this.m_limitState=box2d.b2LimitState.e_inactiveLimit,\nthis.m_impulse.z=0)):this.m_limitState=box2d.b2LimitState.e_inactiveLimit;a.step.warmStarting?(this.m_impulse.SelfMul(a.step.dtRatio),this.m_motorImpulse*=a.step.dtRatio,b=box2d.b2RevoluteJoint.prototype.InitVelocityConstraints.s_P.SetXY(this.m_impulse.x,this.m_impulse.y),c.SelfMulSub(h,b),e-=k*(box2d.b2CrossVV(this.m_rA,b)+this.m_motorImpulse+this.m_impulse.z),f.SelfMulAdd(l,b),g+=m*(box2d.b2CrossVV(this.m_rB,b)+this.m_motorImpulse+this.m_impulse.z)):(this.m_impulse.SetZero(),this.m_motorImpulse=\n0);a.velocities[this.m_indexA].w=e;a.velocities[this.m_indexB].w=g};goog.exportProperty(box2d.b2RevoluteJoint.prototype,\"InitVelocityConstraints\",box2d.b2RevoluteJoint.prototype.InitVelocityConstraints);box2d.b2RevoluteJoint.prototype.InitVelocityConstraints.s_P=new box2d.b2Vec2;\nbox2d.b2RevoluteJoint.prototype.SolveVelocityConstraints=function(a){var b=a.velocities[this.m_indexA].v,c=a.velocities[this.m_indexA].w,e=a.velocities[this.m_indexB].v,d=a.velocities[this.m_indexB].w,f=this.m_invMassA,g=this.m_invMassB,h=this.m_invIA,l=this.m_invIB,k=0===h+l;if(this.m_enableMotor&&this.m_limitState!==box2d.b2LimitState.e_equalLimits&&!1===k){var m=d-c-this.m_motorSpeed,m=-this.m_motorMass*m,n=this.m_motorImpulse,p=a.step.dt*this.m_maxMotorTorque;this.m_motorImpulse=box2d.b2Clamp(this.m_motorImpulse+\nm,-p,p);m=this.m_motorImpulse-n;c-=h*m;d+=l*m}this.m_enableLimit&&this.m_limitState!==box2d.b2LimitState.e_inactiveLimit&&!1===k?(k=box2d.b2SubVV(box2d.b2AddVCrossSV(e,d,this.m_rB,box2d.b2Vec2.s_t0),box2d.b2AddVCrossSV(b,c,this.m_rA,box2d.b2Vec2.s_t1),box2d.b2RevoluteJoint.prototype.SolveVelocityConstraints.s_Cdot1),m=this.m_mass.Solve33(k.x,k.y,d-c,box2d.b2RevoluteJoint.prototype.SolveVelocityConstraints.s_impulse3).SelfNeg(),this.m_limitState===box2d.b2LimitState.e_equalLimits?this.m_impulse.SelfAdd(m):\nthis.m_limitState===box2d.b2LimitState.e_atLowerLimit?(n=this.m_impulse.z+m.z,0>n?(n=-k.x+this.m_impulse.z*this.m_mass.ez.x,k=-k.y+this.m_impulse.z*this.m_mass.ez.y,k=this.m_mass.Solve22(n,k,box2d.b2RevoluteJoint.prototype.SolveVelocityConstraints.s_reduced),m.x=k.x,m.y=k.y,m.z=-this.m_impulse.z,this.m_impulse.x+=k.x,this.m_impulse.y+=k.y,this.m_impulse.z=0):this.m_impulse.SelfAdd(m)):this.m_limitState===box2d.b2LimitState.e_atUpperLimit&&(n=this.m_impulse.z+m.z,0<n?(n=-k.x+this.m_impulse.z*this.m_mass.ez.x,\nk=-k.y+this.m_impulse.z*this.m_mass.ez.y,k=this.m_mass.Solve22(n,k,box2d.b2RevoluteJoint.prototype.SolveVelocityConstraints.s_reduced),m.x=k.x,m.y=k.y,m.z=-this.m_impulse.z,this.m_impulse.x+=k.x,this.m_impulse.y+=k.y,this.m_impulse.z=0):this.m_impulse.SelfAdd(m)),k=box2d.b2RevoluteJoint.prototype.SolveVelocityConstraints.s_P.SetXY(m.x,m.y),b.SelfMulSub(f,k),c-=h*(box2d.b2CrossVV(this.m_rA,k)+m.z),e.SelfMulAdd(g,k),d+=l*(box2d.b2CrossVV(this.m_rB,k)+m.z)):(m=box2d.b2SubVV(box2d.b2AddVCrossSV(e,d,this.m_rB,\nbox2d.b2Vec2.s_t0),box2d.b2AddVCrossSV(b,c,this.m_rA,box2d.b2Vec2.s_t1),box2d.b2RevoluteJoint.prototype.SolveVelocityConstraints.s_Cdot),m=this.m_mass.Solve22(-m.x,-m.y,box2d.b2RevoluteJoint.prototype.SolveVelocityConstraints.s_impulse2),this.m_impulse.x+=m.x,this.m_impulse.y+=m.y,b.SelfMulSub(f,m),c-=h*box2d.b2CrossVV(this.m_rA,m),e.SelfMulAdd(g,m),d+=l*box2d.b2CrossVV(this.m_rB,m));a.velocities[this.m_indexA].w=c;a.velocities[this.m_indexB].w=d};\ngoog.exportProperty(box2d.b2RevoluteJoint.prototype,\"SolveVelocityConstraints\",box2d.b2RevoluteJoint.prototype.SolveVelocityConstraints);box2d.b2RevoluteJoint.prototype.SolveVelocityConstraints.s_P=new box2d.b2Vec2;box2d.b2RevoluteJoint.prototype.SolveVelocityConstraints.s_Cdot=new box2d.b2Vec2;box2d.b2RevoluteJoint.prototype.SolveVelocityConstraints.s_Cdot1=new box2d.b2Vec2;box2d.b2RevoluteJoint.prototype.SolveVelocityConstraints.s_impulse3=new box2d.b2Vec3;\nbox2d.b2RevoluteJoint.prototype.SolveVelocityConstraints.s_reduced=new box2d.b2Vec2;box2d.b2RevoluteJoint.prototype.SolveVelocityConstraints.s_impulse2=new box2d.b2Vec2;\nbox2d.b2RevoluteJoint.prototype.SolvePositionConstraints=function(a){var b=a.positions[this.m_indexA].c,c=a.positions[this.m_indexA].a,e=a.positions[this.m_indexB].c,d=a.positions[this.m_indexB].a,f=this.m_qA.SetAngleRadians(c),g=this.m_qB.SetAngleRadians(d),h=0,l=0,l=0===this.m_invIA+this.m_invIB;if(this.m_enableLimit&&this.m_limitState!==box2d.b2LimitState.e_inactiveLimit&&!1===l){var k=d-c-this.m_referenceAngle,l=0;this.m_limitState===box2d.b2LimitState.e_equalLimits?(k=box2d.b2Clamp(k-this.m_lowerAngle,\n-box2d.b2_maxAngularCorrection,box2d.b2_maxAngularCorrection),l=-this.m_motorMass*k,h=box2d.b2Abs(k)):this.m_limitState===box2d.b2LimitState.e_atLowerLimit?(k-=this.m_lowerAngle,h=-k,k=box2d.b2Clamp(k+box2d.b2_angularSlop,-box2d.b2_maxAngularCorrection,0),l=-this.m_motorMass*k):this.m_limitState===box2d.b2LimitState.e_atUpperLimit&&(h=k-=this.m_upperAngle,k=box2d.b2Clamp(k-box2d.b2_angularSlop,0,box2d.b2_maxAngularCorrection),l=-this.m_motorMass*k);c-=this.m_invIA*l;d+=this.m_invIB*l}f.SetAngleRadians(c);\ng.SetAngleRadians(d);box2d.b2SubVV(this.m_localAnchorA,this.m_localCenterA,this.m_lalcA);f=box2d.b2MulRV(f,this.m_lalcA,this.m_rA);box2d.b2SubVV(this.m_localAnchorB,this.m_localCenterB,this.m_lalcB);var g=box2d.b2MulRV(g,this.m_lalcB,this.m_rB),k=box2d.b2SubVV(box2d.b2AddVV(e,g,box2d.b2Vec2.s_t0),box2d.b2AddVV(b,f,box2d.b2Vec2.s_t1),box2d.b2RevoluteJoint.prototype.SolvePositionConstraints.s_C),l=k.GetLength(),m=this.m_invMassA,n=this.m_invMassB,p=this.m_invIA,q=this.m_invIB,r=this.m_K;r.ex.x=m+n+\np*f.y*f.y+q*g.y*g.y;r.ex.y=-p*f.x*f.y-q*g.x*g.y;r.ey.x=r.ex.y;r.ey.y=m+n+p*f.x*f.x+q*g.x*g.x;k=r.Solve(k.x,k.y,box2d.b2RevoluteJoint.prototype.SolvePositionConstraints.s_impulse).SelfNeg();b.SelfMulSub(m,k);c-=p*box2d.b2CrossVV(f,k);e.SelfMulAdd(n,k);d+=q*box2d.b2CrossVV(g,k);a.positions[this.m_indexA].a=c;a.positions[this.m_indexB].a=d;return l<=box2d.b2_linearSlop&&h<=box2d.b2_angularSlop};goog.exportProperty(box2d.b2RevoluteJoint.prototype,\"SolvePositionConstraints\",box2d.b2RevoluteJoint.prototype.SolvePositionConstraints);\nbox2d.b2RevoluteJoint.prototype.SolvePositionConstraints.s_C=new box2d.b2Vec2;box2d.b2RevoluteJoint.prototype.SolvePositionConstraints.s_impulse=new box2d.b2Vec2;box2d.b2RevoluteJoint.prototype.GetAnchorA=function(a){return this.m_bodyA.GetWorldPoint(this.m_localAnchorA,a)};goog.exportProperty(box2d.b2RevoluteJoint.prototype,\"GetAnchorA\",box2d.b2RevoluteJoint.prototype.GetAnchorA);box2d.b2RevoluteJoint.prototype.GetAnchorB=function(a){return this.m_bodyB.GetWorldPoint(this.m_localAnchorB,a)};\ngoog.exportProperty(box2d.b2RevoluteJoint.prototype,\"GetAnchorB\",box2d.b2RevoluteJoint.prototype.GetAnchorB);box2d.b2RevoluteJoint.prototype.GetReactionForce=function(a,b){return b.SetXY(a*this.m_impulse.x,a*this.m_impulse.y)};goog.exportProperty(box2d.b2RevoluteJoint.prototype,\"GetReactionForce\",box2d.b2RevoluteJoint.prototype.GetReactionForce);box2d.b2RevoluteJoint.prototype.GetReactionTorque=function(a){return a*this.m_impulse.z};\ngoog.exportProperty(box2d.b2RevoluteJoint.prototype,\"GetReactionTorque\",box2d.b2RevoluteJoint.prototype.GetReactionTorque);box2d.b2RevoluteJoint.prototype.GetLocalAnchorA=function(a){return a.Copy(this.m_localAnchorA)};goog.exportProperty(box2d.b2RevoluteJoint.prototype,\"GetLocalAnchorA\",box2d.b2RevoluteJoint.prototype.GetLocalAnchorA);box2d.b2RevoluteJoint.prototype.GetLocalAnchorB=function(a){return a.Copy(this.m_localAnchorB)};\ngoog.exportProperty(box2d.b2RevoluteJoint.prototype,\"GetLocalAnchorB\",box2d.b2RevoluteJoint.prototype.GetLocalAnchorB);box2d.b2RevoluteJoint.prototype.GetReferenceAngle=function(){return this.m_referenceAngle};goog.exportProperty(box2d.b2RevoluteJoint.prototype,\"GetReferenceAngle\",box2d.b2RevoluteJoint.prototype.GetReferenceAngle);box2d.b2RevoluteJoint.prototype.GetJointAngleRadians=function(){return this.m_bodyB.m_sweep.a-this.m_bodyA.m_sweep.a-this.m_referenceAngle};\ngoog.exportProperty(box2d.b2RevoluteJoint.prototype,\"GetJointAngleRadians\",box2d.b2RevoluteJoint.prototype.GetJointAngleRadians);box2d.b2RevoluteJoint.prototype.GetJointSpeed=function(){return this.m_bodyB.m_angularVelocity-this.m_bodyA.m_angularVelocity};goog.exportProperty(box2d.b2RevoluteJoint.prototype,\"GetJointSpeed\",box2d.b2RevoluteJoint.prototype.GetJointSpeed);box2d.b2RevoluteJoint.prototype.IsMotorEnabled=function(){return this.m_enableMotor};\ngoog.exportProperty(box2d.b2RevoluteJoint.prototype,\"IsMotorEnabled\",box2d.b2RevoluteJoint.prototype.IsMotorEnabled);box2d.b2RevoluteJoint.prototype.EnableMotor=function(a){this.m_enableMotor!==a&&(this.m_bodyA.SetAwake(!0),this.m_bodyB.SetAwake(!0),this.m_enableMotor=a)};goog.exportProperty(box2d.b2RevoluteJoint.prototype,\"EnableMotor\",box2d.b2RevoluteJoint.prototype.EnableMotor);box2d.b2RevoluteJoint.prototype.GetMotorTorque=function(a){return a*this.m_motorImpulse};\ngoog.exportProperty(box2d.b2RevoluteJoint.prototype,\"GetMotorTorque\",box2d.b2RevoluteJoint.prototype.GetMotorTorque);box2d.b2RevoluteJoint.prototype.GetMotorSpeed=function(){return this.m_motorSpeed};goog.exportProperty(box2d.b2RevoluteJoint.prototype,\"GetMotorSpeed\",box2d.b2RevoluteJoint.prototype.GetMotorSpeed);box2d.b2RevoluteJoint.prototype.SetMaxMotorTorque=function(a){this.m_maxMotorTorque=a};goog.exportProperty(box2d.b2RevoluteJoint.prototype,\"SetMaxMotorTorque\",box2d.b2RevoluteJoint.prototype.SetMaxMotorTorque);\nbox2d.b2RevoluteJoint.prototype.GetMaxMotorTorque=function(){return this.m_maxMotorTorque};goog.exportProperty(box2d.b2RevoluteJoint.prototype,\"GetMaxMotorTorque\",box2d.b2RevoluteJoint.prototype.GetMaxMotorTorque);box2d.b2RevoluteJoint.prototype.IsLimitEnabled=function(){return this.m_enableLimit};goog.exportProperty(box2d.b2RevoluteJoint.prototype,\"IsLimitEnabled\",box2d.b2RevoluteJoint.prototype.IsLimitEnabled);\nbox2d.b2RevoluteJoint.prototype.EnableLimit=function(a){a!==this.m_enableLimit&&(this.m_bodyA.SetAwake(!0),this.m_bodyB.SetAwake(!0),this.m_enableLimit=a,this.m_impulse.z=0)};goog.exportProperty(box2d.b2RevoluteJoint.prototype,\"EnableLimit\",box2d.b2RevoluteJoint.prototype.EnableLimit);box2d.b2RevoluteJoint.prototype.GetLowerLimit=function(){return this.m_lowerAngle};goog.exportProperty(box2d.b2RevoluteJoint.prototype,\"GetLowerLimit\",box2d.b2RevoluteJoint.prototype.GetLowerLimit);\nbox2d.b2RevoluteJoint.prototype.GetUpperLimit=function(){return this.m_upperAngle};goog.exportProperty(box2d.b2RevoluteJoint.prototype,\"GetUpperLimit\",box2d.b2RevoluteJoint.prototype.GetUpperLimit);box2d.b2RevoluteJoint.prototype.SetLimits=function(a,b){if(a!==this.m_lowerAngle||b!==this.m_upperAngle)this.m_bodyA.SetAwake(!0),this.m_bodyB.SetAwake(!0),this.m_impulse.z=0,this.m_lowerAngle=a,this.m_upperAngle=b};goog.exportProperty(box2d.b2RevoluteJoint.prototype,\"SetLimits\",box2d.b2RevoluteJoint.prototype.SetLimits);\nbox2d.b2RevoluteJoint.prototype.SetMotorSpeed=function(a){this.m_motorSpeed!==a&&(this.m_bodyA.SetAwake(!0),this.m_bodyB.SetAwake(!0),this.m_motorSpeed=a)};goog.exportProperty(box2d.b2RevoluteJoint.prototype,\"SetMotorSpeed\",box2d.b2RevoluteJoint.prototype.SetMotorSpeed);\nbox2d.b2RevoluteJoint.prototype.Dump=function(){if(box2d.DEBUG){var a=this.m_bodyA.m_islandIndex,b=this.m_bodyB.m_islandIndex;box2d.b2Log(\"  /*box2d.b2RevoluteJointDef*/ var jd = new box2d.b2RevoluteJointDef();\\n\");box2d.b2Log(\"  jd.bodyA = bodies[%d];\\n\",a);box2d.b2Log(\"  jd.bodyB = bodies[%d];\\n\",b);box2d.b2Log(\"  jd.collideConnected = %s;\\n\",this.m_collideConnected?\"true\":\"false\");box2d.b2Log(\"  jd.localAnchorA.SetXY(%.15f, %.15f);\\n\",this.m_localAnchorA.x,this.m_localAnchorA.y);box2d.b2Log(\"  jd.localAnchorB.SetXY(%.15f, %.15f);\\n\",\nthis.m_localAnchorB.x,this.m_localAnchorB.y);box2d.b2Log(\"  jd.referenceAngle = %.15f;\\n\",this.m_referenceAngle);box2d.b2Log(\"  jd.enableLimit = %s;\\n\",this.m_enableLimit?\"true\":\"false\");box2d.b2Log(\"  jd.lowerAngle = %.15f;\\n\",this.m_lowerAngle);box2d.b2Log(\"  jd.upperAngle = %.15f;\\n\",this.m_upperAngle);box2d.b2Log(\"  jd.enableMotor = %s;\\n\",this.m_enableMotor?\"true\":\"false\");box2d.b2Log(\"  jd.motorSpeed = %.15f;\\n\",this.m_motorSpeed);box2d.b2Log(\"  jd.maxMotorTorque = %.15f;\\n\",this.m_maxMotorTorque);\nbox2d.b2Log(\"  joints[%d] = this.m_world.CreateJoint(jd);\\n\",this.m_index)}};goog.exportProperty(box2d.b2RevoluteJoint.prototype,\"Dump\",box2d.b2RevoluteJoint.prototype.Dump);box2d.b2PrismaticJointDef=function(){box2d.b2JointDef.call(this,box2d.b2JointType.e_prismaticJoint);this.localAnchorA=new box2d.b2Vec2;this.localAnchorB=new box2d.b2Vec2;this.localAxisA=new box2d.b2Vec2(1,0)};goog.inherits(box2d.b2PrismaticJointDef,box2d.b2JointDef);goog.exportSymbol(\"box2d.b2PrismaticJointDef\",box2d.b2PrismaticJointDef);box2d.b2PrismaticJointDef.prototype.localAnchorA=null;goog.exportProperty(box2d.b2PrismaticJointDef.prototype,\"localAnchorA\",box2d.b2PrismaticJointDef.prototype.localAnchorA);\nbox2d.b2PrismaticJointDef.prototype.localAnchorB=null;goog.exportProperty(box2d.b2PrismaticJointDef.prototype,\"localAnchorB\",box2d.b2PrismaticJointDef.prototype.localAnchorB);box2d.b2PrismaticJointDef.prototype.localAxisA=null;goog.exportProperty(box2d.b2PrismaticJointDef.prototype,\"localAxisA\",box2d.b2PrismaticJointDef.prototype.localAxisA);box2d.b2PrismaticJointDef.prototype.referenceAngle=0;goog.exportProperty(box2d.b2PrismaticJointDef.prototype,\"referenceAngle\",box2d.b2PrismaticJointDef.prototype.referenceAngle);\nbox2d.b2PrismaticJointDef.prototype.enableLimit=!1;goog.exportProperty(box2d.b2PrismaticJointDef.prototype,\"enableLimit\",box2d.b2PrismaticJointDef.prototype.enableLimit);box2d.b2PrismaticJointDef.prototype.lowerTranslation=0;goog.exportProperty(box2d.b2PrismaticJointDef.prototype,\"lowerTranslation\",box2d.b2PrismaticJointDef.prototype.lowerTranslation);box2d.b2PrismaticJointDef.prototype.upperTranslation=0;goog.exportProperty(box2d.b2PrismaticJointDef.prototype,\"upperTranslation\",box2d.b2PrismaticJointDef.prototype.upperTranslation);\nbox2d.b2PrismaticJointDef.prototype.enableMotor=!1;goog.exportProperty(box2d.b2PrismaticJointDef.prototype,\"enableMotor\",box2d.b2PrismaticJointDef.prototype.enableMotor);box2d.b2PrismaticJointDef.prototype.maxMotorForce=0;goog.exportProperty(box2d.b2PrismaticJointDef.prototype,\"maxMotorForce\",box2d.b2PrismaticJointDef.prototype.maxMotorForce);box2d.b2PrismaticJointDef.prototype.motorSpeed=0;goog.exportProperty(box2d.b2PrismaticJointDef.prototype,\"motorSpeed\",box2d.b2PrismaticJointDef.prototype.motorSpeed);\nbox2d.b2PrismaticJointDef.prototype.Initialize=function(a,b,c,e){this.bodyA=a;this.bodyB=b;this.bodyA.GetLocalPoint(c,this.localAnchorA);this.bodyB.GetLocalPoint(c,this.localAnchorB);this.bodyA.GetLocalVector(e,this.localAxisA);this.referenceAngle=this.bodyB.GetAngleRadians()-this.bodyA.GetAngleRadians()};goog.exportProperty(box2d.b2PrismaticJointDef.prototype,\"Initialize\",box2d.b2PrismaticJointDef.prototype.Initialize);\nbox2d.b2PrismaticJoint=function(a){box2d.b2Joint.call(this,a);this.m_localAnchorA=a.localAnchorA.Clone();this.m_localAnchorB=a.localAnchorB.Clone();this.m_localXAxisA=a.localAxisA.Clone().SelfNormalize();this.m_localYAxisA=box2d.b2CrossOneV(this.m_localXAxisA,new box2d.b2Vec2);this.m_referenceAngle=a.referenceAngle;this.m_impulse=new box2d.b2Vec3(0,0,0);this.m_lowerTranslation=a.lowerTranslation;this.m_upperTranslation=a.upperTranslation;this.m_maxMotorForce=a.maxMotorForce;this.m_motorSpeed=a.motorSpeed;\nthis.m_enableLimit=a.enableLimit;this.m_enableMotor=a.enableMotor;this.m_localCenterA=new box2d.b2Vec2;this.m_localCenterB=new box2d.b2Vec2;this.m_axis=new box2d.b2Vec2(0,0);this.m_perp=new box2d.b2Vec2(0,0);this.m_K=new box2d.b2Mat33;this.m_K3=new box2d.b2Mat33;this.m_K2=new box2d.b2Mat22;this.m_qA=new box2d.b2Rot;this.m_qB=new box2d.b2Rot;this.m_lalcA=new box2d.b2Vec2;this.m_lalcB=new box2d.b2Vec2;this.m_rA=new box2d.b2Vec2;this.m_rB=new box2d.b2Vec2};goog.inherits(box2d.b2PrismaticJoint,box2d.b2Joint);\ngoog.exportSymbol(\"box2d.b2PrismaticJoint\",box2d.b2PrismaticJoint);box2d.b2PrismaticJoint.prototype.m_localAnchorA=null;goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"m_localAnchorA\",box2d.b2PrismaticJoint.prototype.m_localAnchorA);box2d.b2PrismaticJoint.prototype.m_localAnchorB=null;goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"m_localAnchorB\",box2d.b2PrismaticJoint.prototype.m_localAnchorB);box2d.b2PrismaticJoint.prototype.m_localXAxisA=null;\ngoog.exportProperty(box2d.b2PrismaticJoint.prototype,\"m_localXAxisA\",box2d.b2PrismaticJoint.prototype.m_localXAxisA);box2d.b2PrismaticJoint.prototype.m_localYAxisA=null;goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"m_localYAxisA\",box2d.b2PrismaticJoint.prototype.m_localYAxisA);box2d.b2PrismaticJoint.prototype.m_referenceAngle=0;goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"m_referenceAngle\",box2d.b2PrismaticJoint.prototype.m_referenceAngle);\nbox2d.b2PrismaticJoint.prototype.m_impulse=null;goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"m_impulse\",box2d.b2PrismaticJoint.prototype.m_impulse);box2d.b2PrismaticJoint.prototype.m_motorImpulse=0;goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"m_motorImpulse\",box2d.b2PrismaticJoint.prototype.m_motorImpulse);box2d.b2PrismaticJoint.prototype.m_lowerTranslation=0;goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"m_lowerTranslation\",box2d.b2PrismaticJoint.prototype.m_lowerTranslation);\nbox2d.b2PrismaticJoint.prototype.m_upperTranslation=0;goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"m_upperTranslation\",box2d.b2PrismaticJoint.prototype.m_upperTranslation);box2d.b2PrismaticJoint.prototype.m_maxMotorForce=0;goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"m_maxMotorForce\",box2d.b2PrismaticJoint.prototype.m_maxMotorForce);box2d.b2PrismaticJoint.prototype.m_motorSpeed=0;goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"m_motorSpeed\",box2d.b2PrismaticJoint.prototype.m_motorSpeed);\nbox2d.b2PrismaticJoint.prototype.m_enableLimit=!1;goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"m_enableLimit\",box2d.b2PrismaticJoint.prototype.m_enableLimit);box2d.b2PrismaticJoint.prototype.m_enableMotor=!1;goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"m_enableMotor\",box2d.b2PrismaticJoint.prototype.m_enableMotor);box2d.b2PrismaticJoint.prototype.m_limitState=box2d.b2LimitState.e_inactiveLimit;goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"m_limitState\",box2d.b2PrismaticJoint.prototype.m_limitState);\nbox2d.b2PrismaticJoint.prototype.m_indexA=0;goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"m_indexA\",box2d.b2PrismaticJoint.prototype.m_indexA);box2d.b2PrismaticJoint.prototype.m_indexB=0;goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"m_indexB\",box2d.b2PrismaticJoint.prototype.m_indexB);box2d.b2PrismaticJoint.prototype.m_localCenterA=null;goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"m_localCenterA\",box2d.b2PrismaticJoint.prototype.m_localCenterA);\nbox2d.b2PrismaticJoint.prototype.m_localCenterB=null;goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"m_localCenterB\",box2d.b2PrismaticJoint.prototype.m_localCenterB);box2d.b2PrismaticJoint.prototype.m_invMassA=0;goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"m_invMassA\",box2d.b2PrismaticJoint.prototype.m_invMassA);box2d.b2PrismaticJoint.prototype.m_invMassB=0;goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"m_invMassB\",box2d.b2PrismaticJoint.prototype.m_invMassB);\nbox2d.b2PrismaticJoint.prototype.m_invIA=0;goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"m_invIA\",box2d.b2PrismaticJoint.prototype.m_invIA);box2d.b2PrismaticJoint.prototype.m_invIB=0;goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"m_invIB\",box2d.b2PrismaticJoint.prototype.m_invIB);box2d.b2PrismaticJoint.prototype.m_axis=null;goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"m_axis\",box2d.b2PrismaticJoint.prototype.m_axis);box2d.b2PrismaticJoint.prototype.m_perp=null;\ngoog.exportProperty(box2d.b2PrismaticJoint.prototype,\"m_perp\",box2d.b2PrismaticJoint.prototype.m_perp);box2d.b2PrismaticJoint.prototype.m_s1=0;goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"m_s1\",box2d.b2PrismaticJoint.prototype.m_s1);box2d.b2PrismaticJoint.prototype.m_s2=0;goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"m_s2\",box2d.b2PrismaticJoint.prototype.m_s2);box2d.b2PrismaticJoint.prototype.m_a1=0;goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"m_a1\",box2d.b2PrismaticJoint.prototype.m_a1);\nbox2d.b2PrismaticJoint.prototype.m_a2=0;goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"m_a2\",box2d.b2PrismaticJoint.prototype.m_a2);box2d.b2PrismaticJoint.prototype.m_K=null;goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"m_K\",box2d.b2PrismaticJoint.prototype.m_K);box2d.b2PrismaticJoint.prototype.m_K3=null;goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"m_K3\",box2d.b2PrismaticJoint.prototype.m_K3);box2d.b2PrismaticJoint.prototype.m_K2=null;\ngoog.exportProperty(box2d.b2PrismaticJoint.prototype,\"m_K2\",box2d.b2PrismaticJoint.prototype.m_K2);box2d.b2PrismaticJoint.prototype.m_motorMass=0;goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"m_motorMass\",box2d.b2PrismaticJoint.prototype.m_motorMass);box2d.b2PrismaticJoint.prototype.m_qA=null;goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"m_qA\",box2d.b2PrismaticJoint.prototype.m_qA);box2d.b2PrismaticJoint.prototype.m_qB=null;\ngoog.exportProperty(box2d.b2PrismaticJoint.prototype,\"m_qB\",box2d.b2PrismaticJoint.prototype.m_qB);box2d.b2PrismaticJoint.prototype.m_lalcA=null;goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"m_lalcA\",box2d.b2PrismaticJoint.prototype.m_lalcA);box2d.b2PrismaticJoint.prototype.m_lalcB=null;goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"m_lalcB\",box2d.b2PrismaticJoint.prototype.m_lalcB);box2d.b2PrismaticJoint.prototype.m_rA=null;\ngoog.exportProperty(box2d.b2PrismaticJoint.prototype,\"m_rA\",box2d.b2PrismaticJoint.prototype.m_rA);box2d.b2PrismaticJoint.prototype.m_rB=null;goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"m_rB\",box2d.b2PrismaticJoint.prototype.m_rB);\nbox2d.b2PrismaticJoint.prototype.InitVelocityConstraints=function(a){this.m_indexA=this.m_bodyA.m_islandIndex;this.m_indexB=this.m_bodyB.m_islandIndex;this.m_localCenterA.Copy(this.m_bodyA.m_sweep.localCenter);this.m_localCenterB.Copy(this.m_bodyB.m_sweep.localCenter);this.m_invMassA=this.m_bodyA.m_invMass;this.m_invMassB=this.m_bodyB.m_invMass;this.m_invIA=this.m_bodyA.m_invI;this.m_invIB=this.m_bodyB.m_invI;var b=a.positions[this.m_indexA].c,c=a.velocities[this.m_indexA].v,e=a.velocities[this.m_indexA].w,\nd=a.positions[this.m_indexB].c,f=a.positions[this.m_indexB].a,g=a.velocities[this.m_indexB].v,h=a.velocities[this.m_indexB].w,l=this.m_qA.SetAngleRadians(a.positions[this.m_indexA].a),f=this.m_qB.SetAngleRadians(f);box2d.b2SubVV(this.m_localAnchorA,this.m_localCenterA,this.m_lalcA);var k=box2d.b2MulRV(l,this.m_lalcA,this.m_rA);box2d.b2SubVV(this.m_localAnchorB,this.m_localCenterB,this.m_lalcB);var m=box2d.b2MulRV(f,this.m_lalcB,this.m_rB),n=box2d.b2AddVV(box2d.b2SubVV(d,b,box2d.b2Vec2.s_t0),box2d.b2SubVV(m,\nk,box2d.b2Vec2.s_t1),box2d.b2PrismaticJoint.prototype.InitVelocityConstraints.s_d),b=this.m_invMassA,d=this.m_invMassB,f=this.m_invIA,p=this.m_invIB;box2d.b2MulRV(l,this.m_localXAxisA,this.m_axis);this.m_a1=box2d.b2CrossVV(box2d.b2AddVV(n,k,box2d.b2Vec2.s_t0),this.m_axis);this.m_a2=box2d.b2CrossVV(m,this.m_axis);this.m_motorMass=b+d+f*this.m_a1*this.m_a1+p*this.m_a2*this.m_a2;0<this.m_motorMass&&(this.m_motorMass=1/this.m_motorMass);box2d.b2MulRV(l,this.m_localYAxisA,this.m_perp);this.m_s1=box2d.b2CrossVV(box2d.b2AddVV(n,\nk,box2d.b2Vec2.s_t0),this.m_perp);this.m_s2=box2d.b2CrossVV(m,this.m_perp);this.m_K.ex.x=b+d+f*this.m_s1*this.m_s1+p*this.m_s2*this.m_s2;this.m_K.ex.y=f*this.m_s1+p*this.m_s2;this.m_K.ex.z=f*this.m_s1*this.m_a1+p*this.m_s2*this.m_a2;this.m_K.ey.x=this.m_K.ex.y;this.m_K.ey.y=f+p;0===this.m_K.ey.y&&(this.m_K.ey.y=1);this.m_K.ey.z=f*this.m_a1+p*this.m_a2;this.m_K.ez.x=this.m_K.ex.z;this.m_K.ez.y=this.m_K.ey.z;this.m_K.ez.z=b+d+f*this.m_a1*this.m_a1+p*this.m_a2*this.m_a2;this.m_enableLimit?(l=box2d.b2DotVV(this.m_axis,\nn),box2d.b2Abs(this.m_upperTranslation-this.m_lowerTranslation)<2*box2d.b2_linearSlop?this.m_limitState=box2d.b2LimitState.e_equalLimits:l<=this.m_lowerTranslation?this.m_limitState!==box2d.b2LimitState.e_atLowerLimit&&(this.m_limitState=box2d.b2LimitState.e_atLowerLimit,this.m_impulse.z=0):l>=this.m_upperTranslation?this.m_limitState!==box2d.b2LimitState.e_atUpperLimit&&(this.m_limitState=box2d.b2LimitState.e_atUpperLimit,this.m_impulse.z=0):(this.m_limitState=box2d.b2LimitState.e_inactiveLimit,\nthis.m_impulse.z=0)):(this.m_limitState=box2d.b2LimitState.e_inactiveLimit,this.m_impulse.z=0);!1===this.m_enableMotor&&(this.m_motorImpulse=0);a.step.warmStarting?(this.m_impulse.SelfMul(a.step.dtRatio),this.m_motorImpulse*=a.step.dtRatio,l=box2d.b2AddVV(box2d.b2MulSV(this.m_impulse.x,this.m_perp,box2d.b2Vec2.s_t0),box2d.b2MulSV(this.m_motorImpulse+this.m_impulse.z,this.m_axis,box2d.b2Vec2.s_t1),box2d.b2PrismaticJoint.prototype.InitVelocityConstraints.s_P),k=this.m_impulse.x*this.m_s1+this.m_impulse.y+\n(this.m_motorImpulse+this.m_impulse.z)*this.m_a1,m=this.m_impulse.x*this.m_s2+this.m_impulse.y+(this.m_motorImpulse+this.m_impulse.z)*this.m_a2,c.SelfMulSub(b,l),e-=f*k,g.SelfMulAdd(d,l),h+=p*m):(this.m_impulse.SetZero(),this.m_motorImpulse=0);a.velocities[this.m_indexA].w=e;a.velocities[this.m_indexB].w=h};goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"InitVelocityConstraints\",box2d.b2PrismaticJoint.prototype.InitVelocityConstraints);\nbox2d.b2PrismaticJoint.prototype.InitVelocityConstraints.s_d=new box2d.b2Vec2;box2d.b2PrismaticJoint.prototype.InitVelocityConstraints.s_P=new box2d.b2Vec2;\nbox2d.b2PrismaticJoint.prototype.SolveVelocityConstraints=function(a){var b=a.velocities[this.m_indexA].v,c=a.velocities[this.m_indexA].w,e=a.velocities[this.m_indexB].v,d=a.velocities[this.m_indexB].w,f=this.m_invMassA,g=this.m_invMassB,h=this.m_invIA,l=this.m_invIB;if(this.m_enableMotor&&this.m_limitState!==box2d.b2LimitState.e_equalLimits){var k=box2d.b2DotVV(this.m_axis,box2d.b2SubVV(e,b,box2d.b2Vec2.s_t0))+this.m_a2*d-this.m_a1*c,k=this.m_motorMass*(this.m_motorSpeed-k),m=this.m_motorImpulse,\nn=a.step.dt*this.m_maxMotorForce;this.m_motorImpulse=box2d.b2Clamp(this.m_motorImpulse+k,-n,n);k=this.m_motorImpulse-m;m=box2d.b2MulSV(k,this.m_axis,box2d.b2PrismaticJoint.prototype.SolveVelocityConstraints.s_P);n=k*this.m_a1;k*=this.m_a2;b.SelfMulSub(f,m);c-=h*n;e.SelfMulAdd(g,m);d+=l*k}var n=box2d.b2DotVV(this.m_perp,box2d.b2SubVV(e,b,box2d.b2Vec2.s_t0))+this.m_s2*d-this.m_s1*c,p=d-c;this.m_enableLimit&&this.m_limitState!==box2d.b2LimitState.e_inactiveLimit?(k=box2d.b2DotVV(this.m_axis,box2d.b2SubVV(e,\nb,box2d.b2Vec2.s_t0))+this.m_a2*d-this.m_a1*c,m=box2d.b2PrismaticJoint.prototype.SolveVelocityConstraints.s_f1.Copy(this.m_impulse),k=this.m_K.Solve33(-n,-p,-k,box2d.b2PrismaticJoint.prototype.SolveVelocityConstraints.s_df3),this.m_impulse.SelfAdd(k),this.m_limitState===box2d.b2LimitState.e_atLowerLimit?this.m_impulse.z=box2d.b2Max(this.m_impulse.z,0):this.m_limitState===box2d.b2LimitState.e_atUpperLimit&&(this.m_impulse.z=box2d.b2Min(this.m_impulse.z,0)),n=this.m_K.Solve22(-n-(this.m_impulse.z-m.z)*\nthis.m_K.ez.x,-p-(this.m_impulse.z-m.z)*this.m_K.ez.y,box2d.b2PrismaticJoint.prototype.SolveVelocityConstraints.s_f2r),n.x+=m.x,n.y+=m.y,this.m_impulse.x=n.x,this.m_impulse.y=n.y,k.x=this.m_impulse.x-m.x,k.y=this.m_impulse.y-m.y,k.z=this.m_impulse.z-m.z,m=box2d.b2AddVV(box2d.b2MulSV(k.x,this.m_perp,box2d.b2Vec2.s_t0),box2d.b2MulSV(k.z,this.m_axis,box2d.b2Vec2.s_t1),box2d.b2PrismaticJoint.prototype.SolveVelocityConstraints.s_P),n=k.x*this.m_s1+k.y+k.z*this.m_a1,k=k.x*this.m_s2+k.y+k.z*this.m_a2):(k=\nthis.m_K.Solve22(-n,-p,box2d.b2PrismaticJoint.prototype.SolveVelocityConstraints.s_df2),this.m_impulse.x+=k.x,this.m_impulse.y+=k.y,m=box2d.b2MulSV(k.x,this.m_perp,box2d.b2PrismaticJoint.prototype.SolveVelocityConstraints.s_P),n=k.x*this.m_s1+k.y,k=k.x*this.m_s2+k.y);b.SelfMulSub(f,m);c-=h*n;e.SelfMulAdd(g,m);a.velocities[this.m_indexA].w=c;a.velocities[this.m_indexB].w=d+l*k};goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"SolveVelocityConstraints\",box2d.b2PrismaticJoint.prototype.SolveVelocityConstraints);\nbox2d.b2PrismaticJoint.prototype.SolveVelocityConstraints.s_P=new box2d.b2Vec2;box2d.b2PrismaticJoint.prototype.SolveVelocityConstraints.s_f2r=new box2d.b2Vec2;box2d.b2PrismaticJoint.prototype.SolveVelocityConstraints.s_f1=new box2d.b2Vec3;box2d.b2PrismaticJoint.prototype.SolveVelocityConstraints.s_df3=new box2d.b2Vec3;box2d.b2PrismaticJoint.prototype.SolveVelocityConstraints.s_df2=new box2d.b2Vec2;\nbox2d.b2PrismaticJoint.prototype.SolvePositionConstraints=function(a){var b=a.positions[this.m_indexA].c,c=a.positions[this.m_indexA].a,e=a.positions[this.m_indexB].c,d=a.positions[this.m_indexB].a,f=this.m_qA.SetAngleRadians(c),g=this.m_qB.SetAngleRadians(d),h=this.m_invMassA,l=this.m_invMassB,k=this.m_invIA,m=this.m_invIB,n=box2d.b2MulRV(f,this.m_lalcA,this.m_rA),p=box2d.b2MulRV(g,this.m_lalcB,this.m_rB),q=box2d.b2SubVV(box2d.b2AddVV(e,p,box2d.b2Vec2.s_t0),box2d.b2AddVV(b,n,box2d.b2Vec2.s_t1),box2d.b2PrismaticJoint.prototype.SolvePositionConstraints.s_d),\nr=box2d.b2MulRV(f,this.m_localXAxisA,this.m_axis),t=box2d.b2CrossVV(box2d.b2AddVV(q,n,box2d.b2Vec2.s_t0),r),g=box2d.b2CrossVV(p,r),f=box2d.b2MulRV(f,this.m_localYAxisA,this.m_perp),s=box2d.b2CrossVV(box2d.b2AddVV(q,n,box2d.b2Vec2.s_t0),f),u=box2d.b2CrossVV(p,f),v=box2d.b2PrismaticJoint.prototype.SolvePositionConstraints.s_impulse,y=box2d.b2DotVV(f,q),D=d-c-this.m_referenceAngle,n=box2d.b2Abs(y),p=box2d.b2Abs(D),x=!1,w=0;this.m_enableLimit&&(q=box2d.b2DotVV(r,q),box2d.b2Abs(this.m_upperTranslation-\nthis.m_lowerTranslation)<2*box2d.b2_linearSlop?(w=box2d.b2Clamp(q,-box2d.b2_maxLinearCorrection,box2d.b2_maxLinearCorrection),n=box2d.b2Max(n,box2d.b2Abs(q)),x=!0):q<=this.m_lowerTranslation?(w=box2d.b2Clamp(q-this.m_lowerTranslation+box2d.b2_linearSlop,-box2d.b2_maxLinearCorrection,0),n=box2d.b2Max(n,this.m_lowerTranslation-q),x=!0):q>=this.m_upperTranslation&&(w=box2d.b2Clamp(q-this.m_upperTranslation-box2d.b2_linearSlop,0,box2d.b2_maxLinearCorrection),n=box2d.b2Max(n,q-this.m_upperTranslation),\nx=!0));if(x){var q=k*s+m*u,C=k*s*t+m*u*g,x=k+m;0===x&&(x=1);var A=k*t+m*g,E=h+l+k*t*t+m*g*g,B=this.m_K3;B.ex.SetXYZ(h+l+k*s*s+m*u*u,q,C);B.ey.SetXYZ(q,x,A);B.ez.SetXYZ(C,A,E);v=B.Solve33(-y,-D,-w,v)}else q=k*s+m*u,x=k+m,0===x&&(x=1),w=this.m_K2,w.ex.SetXY(h+l+k*s*s+m*u*u,q),w.ey.SetXY(q,x),y=w.Solve(-y,-D,box2d.b2PrismaticJoint.prototype.SolvePositionConstraints.s_impulse1),v.x=y.x,v.y=y.y,v.z=0;r=box2d.b2AddVV(box2d.b2MulSV(v.x,f,box2d.b2Vec2.s_t0),box2d.b2MulSV(v.z,r,box2d.b2Vec2.s_t1),box2d.b2PrismaticJoint.prototype.SolvePositionConstraints.s_P);\nt=v.x*s+v.y+v.z*t;g=v.x*u+v.y+v.z*g;b.SelfMulSub(h,r);c-=k*t;e.SelfMulAdd(l,r);a.positions[this.m_indexA].a=c;a.positions[this.m_indexB].a=d+m*g;return n<=box2d.b2_linearSlop&&p<=box2d.b2_angularSlop};goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"SolvePositionConstraints\",box2d.b2PrismaticJoint.prototype.SolvePositionConstraints);box2d.b2PrismaticJoint.prototype.SolvePositionConstraints.s_d=new box2d.b2Vec2;box2d.b2PrismaticJoint.prototype.SolvePositionConstraints.s_impulse=new box2d.b2Vec3;\nbox2d.b2PrismaticJoint.prototype.SolvePositionConstraints.s_impulse1=new box2d.b2Vec2;box2d.b2PrismaticJoint.prototype.SolvePositionConstraints.s_P=new box2d.b2Vec2;box2d.b2PrismaticJoint.prototype.GetAnchorA=function(a){return this.m_bodyA.GetWorldPoint(this.m_localAnchorA,a)};goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"GetAnchorA\",box2d.b2PrismaticJoint.prototype.GetAnchorA);box2d.b2PrismaticJoint.prototype.GetAnchorB=function(a){return this.m_bodyB.GetWorldPoint(this.m_localAnchorB,a)};\ngoog.exportProperty(box2d.b2PrismaticJoint.prototype,\"GetAnchorB\",box2d.b2PrismaticJoint.prototype.GetAnchorB);box2d.b2PrismaticJoint.prototype.GetReactionForce=function(a,b){return b.SetXY(a*(this.m_impulse.x*this.m_perp.x+(this.m_motorImpulse+this.m_impulse.z)*this.m_axis.x),a*(this.m_impulse.x*this.m_perp.y+(this.m_motorImpulse+this.m_impulse.z)*this.m_axis.y))};goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"GetReactionForce\",box2d.b2PrismaticJoint.prototype.GetReactionForce);\nbox2d.b2PrismaticJoint.prototype.GetReactionTorque=function(a){return a*this.m_impulse.y};goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"GetReactionTorque\",box2d.b2PrismaticJoint.prototype.GetReactionTorque);box2d.b2PrismaticJoint.prototype.GetLocalAnchorA=function(a){return a.Copy(this.m_localAnchorA)};goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"GetLocalAnchorA\",box2d.b2PrismaticJoint.prototype.GetLocalAnchorA);box2d.b2PrismaticJoint.prototype.GetLocalAnchorB=function(a){return a.Copy(this.m_localAnchorB)};\ngoog.exportProperty(box2d.b2PrismaticJoint.prototype,\"GetLocalAnchorB\",box2d.b2PrismaticJoint.prototype.GetLocalAnchorB);box2d.b2PrismaticJoint.prototype.GetLocalAxisA=function(a){return a.Copy(this.m_localXAxisA)};goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"GetLocalAxisA\",box2d.b2PrismaticJoint.prototype.GetLocalAxisA);box2d.b2PrismaticJoint.prototype.GetReferenceAngle=function(){return this.m_referenceAngle};goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"GetReferenceAngle\",box2d.b2PrismaticJoint.prototype.GetReferenceAngle);\nbox2d.b2PrismaticJoint.prototype.GetJointTranslation=function(){var a=this.m_bodyA.GetWorldPoint(this.m_localAnchorA,box2d.b2PrismaticJoint.prototype.GetJointTranslation.s_pA),b=this.m_bodyB.GetWorldPoint(this.m_localAnchorB,box2d.b2PrismaticJoint.prototype.GetJointTranslation.s_pB),a=box2d.b2SubVV(b,a,box2d.b2PrismaticJoint.prototype.GetJointTranslation.s_d),b=this.m_bodyA.GetWorldVector(this.m_localXAxisA,box2d.b2PrismaticJoint.prototype.GetJointTranslation.s_axis);return box2d.b2DotVV(a,b)};\ngoog.exportProperty(box2d.b2PrismaticJoint.prototype,\"GetJointTranslation\",box2d.b2PrismaticJoint.prototype.GetJointTranslation);box2d.b2PrismaticJoint.prototype.GetJointTranslation.s_pA=new box2d.b2Vec2;box2d.b2PrismaticJoint.prototype.GetJointTranslation.s_pB=new box2d.b2Vec2;box2d.b2PrismaticJoint.prototype.GetJointTranslation.s_d=new box2d.b2Vec2;box2d.b2PrismaticJoint.prototype.GetJointTranslation.s_axis=new box2d.b2Vec2;\nbox2d.b2PrismaticJoint.prototype.GetJointSpeed=function(){var a=this.m_bodyA,b=this.m_bodyB;box2d.b2SubVV(this.m_localAnchorA,a.m_sweep.localCenter,this.m_lalcA);var c=box2d.b2MulRV(a.m_xf.q,this.m_lalcA,this.m_rA);box2d.b2SubVV(this.m_localAnchorB,b.m_sweep.localCenter,this.m_lalcB);var e=box2d.b2MulRV(b.m_xf.q,this.m_lalcB,this.m_rB),d=box2d.b2AddVV(a.m_sweep.c,c,box2d.b2Vec2.s_t0),f=box2d.b2AddVV(b.m_sweep.c,e,box2d.b2Vec2.s_t1),d=box2d.b2SubVV(f,d,box2d.b2Vec2.s_t2),f=a.GetWorldVector(this.m_localXAxisA,\nthis.m_axis),g=a.m_linearVelocity,h=b.m_linearVelocity,a=a.m_angularVelocity,b=b.m_angularVelocity;return box2d.b2DotVV(d,box2d.b2CrossSV(a,f,box2d.b2Vec2.s_t0))+box2d.b2DotVV(f,box2d.b2SubVV(box2d.b2AddVCrossSV(h,b,e,box2d.b2Vec2.s_t0),box2d.b2AddVCrossSV(g,a,c,box2d.b2Vec2.s_t1),box2d.b2Vec2.s_t0))};goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"GetJointSpeed\",box2d.b2PrismaticJoint.prototype.GetJointSpeed);box2d.b2PrismaticJoint.prototype.IsLimitEnabled=function(){return this.m_enableLimit};\ngoog.exportProperty(box2d.b2PrismaticJoint.prototype,\"IsLimitEnabled\",box2d.b2PrismaticJoint.prototype.IsLimitEnabled);box2d.b2PrismaticJoint.prototype.EnableLimit=function(a){a!==this.m_enableLimit&&(this.m_bodyA.SetAwake(!0),this.m_bodyB.SetAwake(!0),this.m_enableLimit=a,this.m_impulse.z=0)};goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"EnableLimit\",box2d.b2PrismaticJoint.prototype.EnableLimit);box2d.b2PrismaticJoint.prototype.GetLowerLimit=function(){return this.m_lowerTranslation};\ngoog.exportProperty(box2d.b2PrismaticJoint.prototype,\"GetLowerLimit\",box2d.b2PrismaticJoint.prototype.GetLowerLimit);box2d.b2PrismaticJoint.prototype.GetUpperLimit=function(){return this.m_upperTranslation};goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"GetUpperLimit\",box2d.b2PrismaticJoint.prototype.GetUpperLimit);\nbox2d.b2PrismaticJoint.prototype.SetLimits=function(a,b){if(a!==this.m_lowerTranslation||b!==this.m_upperTranslation)this.m_bodyA.SetAwake(!0),this.m_bodyB.SetAwake(!0),this.m_lowerTranslation=a,this.m_upperTranslation=b,this.m_impulse.z=0};goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"SetLimits\",box2d.b2PrismaticJoint.prototype.SetLimits);box2d.b2PrismaticJoint.prototype.IsMotorEnabled=function(){return this.m_enableMotor};\ngoog.exportProperty(box2d.b2PrismaticJoint.prototype,\"IsMotorEnabled\",box2d.b2PrismaticJoint.prototype.IsMotorEnabled);box2d.b2PrismaticJoint.prototype.EnableMotor=function(a){this.m_bodyA.SetAwake(!0);this.m_bodyB.SetAwake(!0);this.m_enableMotor=a};goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"EnableMotor\",box2d.b2PrismaticJoint.prototype.EnableMotor);box2d.b2PrismaticJoint.prototype.SetMotorSpeed=function(a){this.m_bodyA.SetAwake(!0);this.m_bodyB.SetAwake(!0);this.m_motorSpeed=a};\ngoog.exportProperty(box2d.b2PrismaticJoint.prototype,\"SetMotorSpeed\",box2d.b2PrismaticJoint.prototype.SetMotorSpeed);box2d.b2PrismaticJoint.prototype.GetMotorSpeed=function(){return this.m_motorSpeed};goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"GetMotorSpeed\",box2d.b2PrismaticJoint.prototype.GetMotorSpeed);box2d.b2PrismaticJoint.prototype.SetMaxMotorForce=function(a){this.m_bodyA.SetAwake(!0);this.m_bodyB.SetAwake(!0);this.m_maxMotorForce=a};\ngoog.exportProperty(box2d.b2PrismaticJoint.prototype,\"SetMaxMotorForce\",box2d.b2PrismaticJoint.prototype.SetMaxMotorForce);box2d.b2PrismaticJoint.prototype.GetMaxMotorForce=function(){return this.m_maxMotorForce};goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"GetMaxMotorForce\",box2d.b2PrismaticJoint.prototype.GetMaxMotorForce);box2d.b2PrismaticJoint.prototype.GetMotorForce=function(a){return a*this.m_motorImpulse};goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"GetMotorForce\",box2d.b2PrismaticJoint.prototype.GetMotorForce);\nbox2d.b2PrismaticJoint.prototype.Dump=function(){if(box2d.DEBUG){var a=this.m_bodyA.m_islandIndex,b=this.m_bodyB.m_islandIndex;box2d.b2Log(\"  /*box2d.b2PrismaticJointDef*/ var jd = new box2d.b2PrismaticJointDef();\\n\");box2d.b2Log(\"  jd.bodyA = bodies[%d];\\n\",a);box2d.b2Log(\"  jd.bodyB = bodies[%d];\\n\",b);box2d.b2Log(\"  jd.collideConnected = %s;\\n\",this.m_collideConnected?\"true\":\"false\");box2d.b2Log(\"  jd.localAnchorA.SetXY(%.15f, %.15f);\\n\",this.m_localAnchorA.x,this.m_localAnchorA.y);box2d.b2Log(\"  jd.localAnchorB.SetXY(%.15f, %.15f);\\n\",\nthis.m_localAnchorB.x,this.m_localAnchorB.y);box2d.b2Log(\"  jd.localAxisA.SetXY(%.15f, %.15f);\\n\",this.m_localXAxisA.x,this.m_localXAxisA.y);box2d.b2Log(\"  jd.referenceAngle = %.15f;\\n\",this.m_referenceAngle);box2d.b2Log(\"  jd.enableLimit = %s;\\n\",this.m_enableLimit?\"true\":\"false\");box2d.b2Log(\"  jd.lowerTranslation = %.15f;\\n\",this.m_lowerTranslation);box2d.b2Log(\"  jd.upperTranslation = %.15f;\\n\",this.m_upperTranslation);box2d.b2Log(\"  jd.enableMotor = %s;\\n\",this.m_enableMotor?\"true\":\"false\");\nbox2d.b2Log(\"  jd.motorSpeed = %.15f;\\n\",this.m_motorSpeed);box2d.b2Log(\"  jd.maxMotorForce = %.15f;\\n\",this.m_maxMotorForce);box2d.b2Log(\"  joints[%d] = this.m_world.CreateJoint(jd);\\n\",this.m_index)}};goog.exportProperty(box2d.b2PrismaticJoint.prototype,\"Dump\",box2d.b2PrismaticJoint.prototype.Dump);box2d.b2GearJointDef=function(){box2d.b2JointDef.call(this,box2d.b2JointType.e_gearJoint)};goog.inherits(box2d.b2GearJointDef,box2d.b2JointDef);goog.exportSymbol(\"box2d.b2GearJointDef\",box2d.b2GearJointDef);box2d.b2GearJointDef.prototype.joint1=null;goog.exportProperty(box2d.b2GearJointDef.prototype,\"joint1\",box2d.b2GearJointDef.prototype.joint1);box2d.b2GearJointDef.prototype.joint2=null;goog.exportProperty(box2d.b2GearJointDef.prototype,\"joint2\",box2d.b2GearJointDef.prototype.joint2);\nbox2d.b2GearJointDef.prototype.ratio=1;goog.exportProperty(box2d.b2GearJointDef.prototype,\"ratio\",box2d.b2GearJointDef.prototype.ratio);\nbox2d.b2GearJoint=function(a){box2d.b2Joint.call(this,a);this.m_joint1=a.joint1;this.m_joint2=a.joint2;this.m_localAnchorA=new box2d.b2Vec2;this.m_localAnchorB=new box2d.b2Vec2;this.m_localAnchorC=new box2d.b2Vec2;this.m_localAnchorD=new box2d.b2Vec2;this.m_localAxisC=new box2d.b2Vec2;this.m_localAxisD=new box2d.b2Vec2;this.m_lcA=new box2d.b2Vec2;this.m_lcB=new box2d.b2Vec2;this.m_lcC=new box2d.b2Vec2;this.m_lcD=new box2d.b2Vec2;this.m_JvAC=new box2d.b2Vec2;this.m_JvBD=new box2d.b2Vec2;this.m_qA=\nnew box2d.b2Rot;this.m_qB=new box2d.b2Rot;this.m_qC=new box2d.b2Rot;this.m_qD=new box2d.b2Rot;this.m_lalcA=new box2d.b2Vec2;this.m_lalcB=new box2d.b2Vec2;this.m_lalcC=new box2d.b2Vec2;this.m_lalcD=new box2d.b2Vec2;this.m_typeA=this.m_joint1.GetType();this.m_typeB=this.m_joint2.GetType();box2d.ENABLE_ASSERTS&&box2d.b2Assert(this.m_typeA===box2d.b2JointType.e_revoluteJoint||this.m_typeA===box2d.b2JointType.e_prismaticJoint);box2d.ENABLE_ASSERTS&&box2d.b2Assert(this.m_typeB===box2d.b2JointType.e_revoluteJoint||\nthis.m_typeB===box2d.b2JointType.e_prismaticJoint);var b,c;this.m_bodyC=this.m_joint1.GetBodyA();this.m_bodyA=this.m_joint1.GetBodyB();b=this.m_bodyA.m_xf;var e=this.m_bodyA.m_sweep.a;c=this.m_bodyC.m_xf;var d=this.m_bodyC.m_sweep.a;this.m_typeA===box2d.b2JointType.e_revoluteJoint?(c=a.joint1,this.m_localAnchorC.Copy(c.m_localAnchorA),this.m_localAnchorA.Copy(c.m_localAnchorB),this.m_referenceAngleA=c.m_referenceAngle,this.m_localAxisC.SetZero(),b=e-d-this.m_referenceAngleA):(d=a.joint1,this.m_localAnchorC.Copy(d.m_localAnchorA),\nthis.m_localAnchorA.Copy(d.m_localAnchorB),this.m_referenceAngleA=d.m_referenceAngle,this.m_localAxisC.Copy(d.m_localXAxisA),e=this.m_localAnchorC,b=box2d.b2MulTRV(c.q,box2d.b2AddVV(box2d.b2MulRV(b.q,this.m_localAnchorA,box2d.b2Vec2.s_t0),box2d.b2SubVV(b.p,c.p,box2d.b2Vec2.s_t1),box2d.b2Vec2.s_t0),box2d.b2Vec2.s_t0),b=box2d.b2DotVV(box2d.b2SubVV(b,e,box2d.b2Vec2.s_t0),this.m_localAxisC));this.m_bodyD=this.m_joint2.GetBodyA();this.m_bodyB=this.m_joint2.GetBodyB();c=this.m_bodyB.m_xf;var d=this.m_bodyB.m_sweep.a,\ne=this.m_bodyD.m_xf,f=this.m_bodyD.m_sweep.a;this.m_typeB===box2d.b2JointType.e_revoluteJoint?(c=a.joint2,this.m_localAnchorD.Copy(c.m_localAnchorA),this.m_localAnchorB.Copy(c.m_localAnchorB),this.m_referenceAngleB=c.m_referenceAngle,this.m_localAxisD.SetZero(),c=d-f-this.m_referenceAngleB):(d=a.joint2,this.m_localAnchorD.Copy(d.m_localAnchorA),this.m_localAnchorB.Copy(d.m_localAnchorB),this.m_referenceAngleB=d.m_referenceAngle,this.m_localAxisD.Copy(d.m_localXAxisA),d=this.m_localAnchorD,c=box2d.b2MulTRV(e.q,\nbox2d.b2AddVV(box2d.b2MulRV(c.q,this.m_localAnchorB,box2d.b2Vec2.s_t0),box2d.b2SubVV(c.p,e.p,box2d.b2Vec2.s_t1),box2d.b2Vec2.s_t0),box2d.b2Vec2.s_t0),c=box2d.b2DotVV(box2d.b2SubVV(c,d,box2d.b2Vec2.s_t0),this.m_localAxisD));this.m_ratio=a.ratio;this.m_constant=b+this.m_ratio*c;this.m_impulse=0};goog.inherits(box2d.b2GearJoint,box2d.b2Joint);goog.exportSymbol(\"box2d.b2GearJoint\",box2d.b2GearJoint);box2d.b2GearJoint.prototype.m_joint1=null;goog.exportProperty(box2d.b2GearJoint.prototype,\"m_joint1\",box2d.b2GearJoint.prototype.m_joint1);\nbox2d.b2GearJoint.prototype.m_joint2=null;goog.exportProperty(box2d.b2GearJoint.prototype,\"m_joint2\",box2d.b2GearJoint.prototype.m_joint2);box2d.b2GearJoint.prototype.m_typeA=box2d.b2JointType.e_unknownJoint;goog.exportProperty(box2d.b2GearJoint.prototype,\"m_typeA\",box2d.b2GearJoint.prototype.m_typeA);box2d.b2GearJoint.prototype.m_typeB=box2d.b2JointType.e_unknownJoint;goog.exportProperty(box2d.b2GearJoint.prototype,\"m_typeB\",box2d.b2GearJoint.prototype.m_typeB);\nbox2d.b2GearJoint.prototype.m_bodyC=null;goog.exportProperty(box2d.b2GearJoint.prototype,\"m_bodyC\",box2d.b2GearJoint.prototype.m_bodyC);box2d.b2GearJoint.prototype.m_bodyD=null;goog.exportProperty(box2d.b2GearJoint.prototype,\"m_bodyD\",box2d.b2GearJoint.prototype.m_bodyD);box2d.b2GearJoint.prototype.m_localAnchorA=null;goog.exportProperty(box2d.b2GearJoint.prototype,\"m_localAnchorA\",box2d.b2GearJoint.prototype.m_localAnchorA);box2d.b2GearJoint.prototype.m_localAnchorB=null;\ngoog.exportProperty(box2d.b2GearJoint.prototype,\"m_localAnchorB\",box2d.b2GearJoint.prototype.m_localAnchorB);box2d.b2GearJoint.prototype.m_localAnchorC=null;goog.exportProperty(box2d.b2GearJoint.prototype,\"m_localAnchorC\",box2d.b2GearJoint.prototype.m_localAnchorC);box2d.b2GearJoint.prototype.m_localAnchorD=null;goog.exportProperty(box2d.b2GearJoint.prototype,\"m_localAnchorD\",box2d.b2GearJoint.prototype.m_localAnchorD);box2d.b2GearJoint.prototype.m_localAxisC=null;\ngoog.exportProperty(box2d.b2GearJoint.prototype,\"m_localAxisC\",box2d.b2GearJoint.prototype.m_localAxisC);box2d.b2GearJoint.prototype.m_localAxisD=null;goog.exportProperty(box2d.b2GearJoint.prototype,\"m_localAxisD\",box2d.b2GearJoint.prototype.m_localAxisD);box2d.b2GearJoint.prototype.m_referenceAngleA=0;goog.exportProperty(box2d.b2GearJoint.prototype,\"m_referenceAngleA\",box2d.b2GearJoint.prototype.m_referenceAngleA);box2d.b2GearJoint.prototype.m_referenceAngleB=0;\ngoog.exportProperty(box2d.b2GearJoint.prototype,\"m_referenceAngleB\",box2d.b2GearJoint.prototype.m_referenceAngleB);box2d.b2GearJoint.prototype.m_constant=0;goog.exportProperty(box2d.b2GearJoint.prototype,\"m_constant\",box2d.b2GearJoint.prototype.m_constant);box2d.b2GearJoint.prototype.m_ratio=0;goog.exportProperty(box2d.b2GearJoint.prototype,\"m_ratio\",box2d.b2GearJoint.prototype.m_ratio);box2d.b2GearJoint.prototype.m_impulse=0;goog.exportProperty(box2d.b2GearJoint.prototype,\"m_impulse\",box2d.b2GearJoint.prototype.m_impulse);\nbox2d.b2GearJoint.prototype.m_indexA=0;goog.exportProperty(box2d.b2GearJoint.prototype,\"m_indexA\",box2d.b2GearJoint.prototype.m_indexA);box2d.b2GearJoint.prototype.m_indexB=0;goog.exportProperty(box2d.b2GearJoint.prototype,\"m_indexB\",box2d.b2GearJoint.prototype.m_indexB);box2d.b2GearJoint.prototype.m_indexC=0;goog.exportProperty(box2d.b2GearJoint.prototype,\"m_indexC\",box2d.b2GearJoint.prototype.m_indexC);box2d.b2GearJoint.prototype.m_indexD=0;\ngoog.exportProperty(box2d.b2GearJoint.prototype,\"m_indexD\",box2d.b2GearJoint.prototype.m_indexD);box2d.b2GearJoint.prototype.m_lcA=null;goog.exportProperty(box2d.b2GearJoint.prototype,\"m_lcA\",box2d.b2GearJoint.prototype.m_lcA);box2d.b2GearJoint.prototype.m_lcB=null;goog.exportProperty(box2d.b2GearJoint.prototype,\"m_lcB\",box2d.b2GearJoint.prototype.m_lcB);box2d.b2GearJoint.prototype.m_lcC=null;goog.exportProperty(box2d.b2GearJoint.prototype,\"m_lcC\",box2d.b2GearJoint.prototype.m_lcC);\nbox2d.b2GearJoint.prototype.m_lcD=null;goog.exportProperty(box2d.b2GearJoint.prototype,\"m_lcD\",box2d.b2GearJoint.prototype.m_lcD);box2d.b2GearJoint.prototype.m_mA=0;goog.exportProperty(box2d.b2GearJoint.prototype,\"m_mA\",box2d.b2GearJoint.prototype.m_mA);box2d.b2GearJoint.prototype.m_mB=0;goog.exportProperty(box2d.b2GearJoint.prototype,\"m_mB\",box2d.b2GearJoint.prototype.m_mB);box2d.b2GearJoint.prototype.m_mC=0;goog.exportProperty(box2d.b2GearJoint.prototype,\"m_mC\",box2d.b2GearJoint.prototype.m_mC);\nbox2d.b2GearJoint.prototype.m_mD=0;goog.exportProperty(box2d.b2GearJoint.prototype,\"m_mD\",box2d.b2GearJoint.prototype.m_mD);box2d.b2GearJoint.prototype.m_iA=0;goog.exportProperty(box2d.b2GearJoint.prototype,\"m_iA\",box2d.b2GearJoint.prototype.m_iA);box2d.b2GearJoint.prototype.m_iB=0;goog.exportProperty(box2d.b2GearJoint.prototype,\"m_iB\",box2d.b2GearJoint.prototype.m_iB);box2d.b2GearJoint.prototype.m_iC=0;goog.exportProperty(box2d.b2GearJoint.prototype,\"m_iC\",box2d.b2GearJoint.prototype.m_iC);\nbox2d.b2GearJoint.prototype.m_iD=0;goog.exportProperty(box2d.b2GearJoint.prototype,\"m_iD\",box2d.b2GearJoint.prototype.m_iD);box2d.b2GearJoint.prototype.m_JvAC=null;goog.exportProperty(box2d.b2GearJoint.prototype,\"m_JvAC\",box2d.b2GearJoint.prototype.m_JvAC);box2d.b2GearJoint.prototype.m_JvBD=null;goog.exportProperty(box2d.b2GearJoint.prototype,\"m_JvBD\",box2d.b2GearJoint.prototype.m_JvBD);box2d.b2GearJoint.prototype.m_JwA=0;goog.exportProperty(box2d.b2GearJoint.prototype,\"m_JwA\",box2d.b2GearJoint.prototype.m_JwA);\nbox2d.b2GearJoint.prototype.m_JwB=0;goog.exportProperty(box2d.b2GearJoint.prototype,\"m_JwB\",box2d.b2GearJoint.prototype.m_JwB);box2d.b2GearJoint.prototype.m_JwC=0;goog.exportProperty(box2d.b2GearJoint.prototype,\"m_JwC\",box2d.b2GearJoint.prototype.m_JwC);box2d.b2GearJoint.prototype.m_JwD=0;goog.exportProperty(box2d.b2GearJoint.prototype,\"m_JwD\",box2d.b2GearJoint.prototype.m_JwD);box2d.b2GearJoint.prototype.m_mass=0;goog.exportProperty(box2d.b2GearJoint.prototype,\"m_mass\",box2d.b2GearJoint.prototype.m_mass);\nbox2d.b2GearJoint.prototype.m_qA=null;goog.exportProperty(box2d.b2GearJoint.prototype,\"m_qA\",box2d.b2GearJoint.prototype.m_qA);box2d.b2GearJoint.prototype.m_qB=null;goog.exportProperty(box2d.b2GearJoint.prototype,\"m_qB\",box2d.b2GearJoint.prototype.m_qB);box2d.b2GearJoint.prototype.m_qC=null;goog.exportProperty(box2d.b2GearJoint.prototype,\"m_qC\",box2d.b2GearJoint.prototype.m_qC);box2d.b2GearJoint.prototype.m_qD=null;goog.exportProperty(box2d.b2GearJoint.prototype,\"m_qD\",box2d.b2GearJoint.prototype.m_qD);\nbox2d.b2GearJoint.prototype.m_lalcA=null;goog.exportProperty(box2d.b2GearJoint.prototype,\"m_lalcA\",box2d.b2GearJoint.prototype.m_lalcA);box2d.b2GearJoint.prototype.m_lalcB=null;goog.exportProperty(box2d.b2GearJoint.prototype,\"m_lalcB\",box2d.b2GearJoint.prototype.m_lalcB);box2d.b2GearJoint.prototype.m_lalcC=null;goog.exportProperty(box2d.b2GearJoint.prototype,\"m_lalcC\",box2d.b2GearJoint.prototype.m_lalcC);box2d.b2GearJoint.prototype.m_lalcD=null;\ngoog.exportProperty(box2d.b2GearJoint.prototype,\"m_lalcD\",box2d.b2GearJoint.prototype.m_lalcD);\nbox2d.b2GearJoint.prototype.InitVelocityConstraints=function(a){this.m_indexA=this.m_bodyA.m_islandIndex;this.m_indexB=this.m_bodyB.m_islandIndex;this.m_indexC=this.m_bodyC.m_islandIndex;this.m_indexD=this.m_bodyD.m_islandIndex;this.m_lcA.Copy(this.m_bodyA.m_sweep.localCenter);this.m_lcB.Copy(this.m_bodyB.m_sweep.localCenter);this.m_lcC.Copy(this.m_bodyC.m_sweep.localCenter);this.m_lcD.Copy(this.m_bodyD.m_sweep.localCenter);this.m_mA=this.m_bodyA.m_invMass;this.m_mB=this.m_bodyB.m_invMass;this.m_mC=\nthis.m_bodyC.m_invMass;this.m_mD=this.m_bodyD.m_invMass;this.m_iA=this.m_bodyA.m_invI;this.m_iB=this.m_bodyB.m_invI;this.m_iC=this.m_bodyC.m_invI;this.m_iD=this.m_bodyD.m_invI;var b=a.velocities[this.m_indexA].v,c=a.velocities[this.m_indexA].w,e=a.positions[this.m_indexB].a,d=a.velocities[this.m_indexB].v,f=a.velocities[this.m_indexB].w,g=a.positions[this.m_indexC].a,h=a.velocities[this.m_indexC].v,l=a.velocities[this.m_indexC].w,k=a.positions[this.m_indexD].a,m=a.velocities[this.m_indexD].v,n=a.velocities[this.m_indexD].w,\np=this.m_qA.SetAngleRadians(a.positions[this.m_indexA].a),e=this.m_qB.SetAngleRadians(e),q=this.m_qC.SetAngleRadians(g),g=this.m_qD.SetAngleRadians(k);this.m_mass=0;this.m_typeA===box2d.b2JointType.e_revoluteJoint?(this.m_JvAC.SetZero(),this.m_JwC=this.m_JwA=1,this.m_mass+=this.m_iA+this.m_iC):(k=box2d.b2MulRV(q,this.m_localAxisC,box2d.b2GearJoint.prototype.InitVelocityConstraints.s_u),box2d.b2SubVV(this.m_localAnchorC,this.m_lcC,this.m_lalcC),q=box2d.b2MulRV(q,this.m_lalcC,box2d.b2GearJoint.prototype.InitVelocityConstraints.s_rC),\nbox2d.b2SubVV(this.m_localAnchorA,this.m_lcA,this.m_lalcA),p=box2d.b2MulRV(p,this.m_lalcA,box2d.b2GearJoint.prototype.InitVelocityConstraints.s_rA),this.m_JvAC.Copy(k),this.m_JwC=box2d.b2CrossVV(q,k),this.m_JwA=box2d.b2CrossVV(p,k),this.m_mass+=this.m_mC+this.m_mA+this.m_iC*this.m_JwC*this.m_JwC+this.m_iA*this.m_JwA*this.m_JwA);this.m_typeB===box2d.b2JointType.e_revoluteJoint?(this.m_JvBD.SetZero(),this.m_JwD=this.m_JwB=this.m_ratio,this.m_mass+=this.m_ratio*this.m_ratio*(this.m_iB+this.m_iD)):(k=\nbox2d.b2MulRV(g,this.m_localAxisD,box2d.b2GearJoint.prototype.InitVelocityConstraints.s_u),box2d.b2SubVV(this.m_localAnchorD,this.m_lcD,this.m_lalcD),p=box2d.b2MulRV(g,this.m_lalcD,box2d.b2GearJoint.prototype.InitVelocityConstraints.s_rD),box2d.b2SubVV(this.m_localAnchorB,this.m_lcB,this.m_lalcB),e=box2d.b2MulRV(e,this.m_lalcB,box2d.b2GearJoint.prototype.InitVelocityConstraints.s_rB),box2d.b2MulSV(this.m_ratio,k,this.m_JvBD),this.m_JwD=this.m_ratio*box2d.b2CrossVV(p,k),this.m_JwB=this.m_ratio*box2d.b2CrossVV(e,\nk),this.m_mass+=this.m_ratio*this.m_ratio*(this.m_mD+this.m_mB)+this.m_iD*this.m_JwD*this.m_JwD+this.m_iB*this.m_JwB*this.m_JwB);this.m_mass=0<this.m_mass?1/this.m_mass:0;a.step.warmStarting?(b.SelfMulAdd(this.m_mA*this.m_impulse,this.m_JvAC),c+=this.m_iA*this.m_impulse*this.m_JwA,d.SelfMulAdd(this.m_mB*this.m_impulse,this.m_JvBD),f+=this.m_iB*this.m_impulse*this.m_JwB,h.SelfMulSub(this.m_mC*this.m_impulse,this.m_JvAC),l-=this.m_iC*this.m_impulse*this.m_JwC,m.SelfMulSub(this.m_mD*this.m_impulse,this.m_JvBD),\nn-=this.m_iD*this.m_impulse*this.m_JwD):this.m_impulse=0;a.velocities[this.m_indexA].w=c;a.velocities[this.m_indexB].w=f;a.velocities[this.m_indexC].w=l;a.velocities[this.m_indexD].w=n};box2d.b2GearJoint.prototype.InitVelocityConstraints.s_u=new box2d.b2Vec2;box2d.b2GearJoint.prototype.InitVelocityConstraints.s_rA=new box2d.b2Vec2;box2d.b2GearJoint.prototype.InitVelocityConstraints.s_rB=new box2d.b2Vec2;box2d.b2GearJoint.prototype.InitVelocityConstraints.s_rC=new box2d.b2Vec2;\nbox2d.b2GearJoint.prototype.InitVelocityConstraints.s_rD=new box2d.b2Vec2;\nbox2d.b2GearJoint.prototype.SolveVelocityConstraints=function(a){var b=a.velocities[this.m_indexA].v,c=a.velocities[this.m_indexA].w,e=a.velocities[this.m_indexB].v,d=a.velocities[this.m_indexB].w,f=a.velocities[this.m_indexC].v,g=a.velocities[this.m_indexC].w,h=a.velocities[this.m_indexD].v,l=a.velocities[this.m_indexD].w,k=box2d.b2DotVV(this.m_JvAC,box2d.b2SubVV(b,f,box2d.b2Vec2.s_t0))+box2d.b2DotVV(this.m_JvBD,box2d.b2SubVV(e,h,box2d.b2Vec2.s_t0)),k=k+(this.m_JwA*c-this.m_JwC*g+(this.m_JwB*d-this.m_JwD*\nl)),k=-this.m_mass*k;this.m_impulse+=k;b.SelfMulAdd(this.m_mA*k,this.m_JvAC);c+=this.m_iA*k*this.m_JwA;e.SelfMulAdd(this.m_mB*k,this.m_JvBD);d+=this.m_iB*k*this.m_JwB;f.SelfMulSub(this.m_mC*k,this.m_JvAC);g-=this.m_iC*k*this.m_JwC;h.SelfMulSub(this.m_mD*k,this.m_JvBD);l-=this.m_iD*k*this.m_JwD;a.velocities[this.m_indexA].w=c;a.velocities[this.m_indexB].w=d;a.velocities[this.m_indexC].w=g;a.velocities[this.m_indexD].w=l};\nbox2d.b2GearJoint.prototype.SolvePositionConstraints=function(a){var b=a.positions[this.m_indexA].c,c=a.positions[this.m_indexA].a,e=a.positions[this.m_indexB].c,d=a.positions[this.m_indexB].a,f=a.positions[this.m_indexC].c,g=a.positions[this.m_indexC].a,h=a.positions[this.m_indexD].c,l=a.positions[this.m_indexD].a,k=this.m_qA.SetAngleRadians(c),m=this.m_qB.SetAngleRadians(d),n=this.m_qC.SetAngleRadians(g),p=this.m_qD.SetAngleRadians(l),q=this.m_JvAC,r=this.m_JvBD,t,s,u=0;if(this.m_typeA===box2d.b2JointType.e_revoluteJoint)q.SetZero(),\nk=t=1,u+=this.m_iA+this.m_iC,n=c-g-this.m_referenceAngleA;else{s=box2d.b2MulRV(n,this.m_localAxisC,box2d.b2GearJoint.prototype.SolvePositionConstraints.s_u);t=box2d.b2MulRV(n,this.m_lalcC,box2d.b2GearJoint.prototype.SolvePositionConstraints.s_rC);var v=box2d.b2MulRV(k,this.m_lalcA,box2d.b2GearJoint.prototype.SolvePositionConstraints.s_rA);q.Copy(s);k=box2d.b2CrossVV(t,s);t=box2d.b2CrossVV(v,s);u+=this.m_mC+this.m_mA+this.m_iC*k*k+this.m_iA*t*t;s=this.m_lalcC;n=box2d.b2MulTRV(n,box2d.b2AddVV(v,box2d.b2SubVV(b,\nf,box2d.b2Vec2.s_t0),box2d.b2Vec2.s_t0),box2d.b2Vec2.s_t0);n=box2d.b2DotVV(box2d.b2SubVV(n,s,box2d.b2Vec2.s_t0),this.m_localAxisC)}if(this.m_typeB===box2d.b2JointType.e_revoluteJoint)r.SetZero(),m=s=this.m_ratio,u+=this.m_ratio*this.m_ratio*(this.m_iB+this.m_iD),p=d-l-this.m_referenceAngleB;else{s=box2d.b2MulRV(p,this.m_localAxisD,box2d.b2GearJoint.prototype.SolvePositionConstraints.s_u);var y=box2d.b2MulRV(p,this.m_lalcD,box2d.b2GearJoint.prototype.SolvePositionConstraints.s_rD),v=box2d.b2MulRV(m,\nthis.m_lalcB,box2d.b2GearJoint.prototype.SolvePositionConstraints.s_rB);box2d.b2MulSV(this.m_ratio,s,r);m=this.m_ratio*box2d.b2CrossVV(y,s);s=this.m_ratio*box2d.b2CrossVV(v,s);u+=this.m_ratio*this.m_ratio*(this.m_mD+this.m_mB)+this.m_iD*m*m+this.m_iB*s*s;y=this.m_lalcD;p=box2d.b2MulTRV(p,box2d.b2AddVV(v,box2d.b2SubVV(e,h,box2d.b2Vec2.s_t0),box2d.b2Vec2.s_t0),box2d.b2Vec2.s_t0);p=box2d.b2DotVV(box2d.b2SubVV(p,y,box2d.b2Vec2.s_t0),this.m_localAxisD)}p=n+this.m_ratio*p-this.m_constant;n=0;0<u&&(n=-p/\nu);b.SelfMulAdd(this.m_mA*n,q);c+=this.m_iA*n*t;e.SelfMulAdd(this.m_mB*n,r);d+=this.m_iB*n*s;f.SelfMulSub(this.m_mC*n,q);g-=this.m_iC*n*k;h.SelfMulSub(this.m_mD*n,r);l-=this.m_iD*n*m;a.positions[this.m_indexA].a=c;a.positions[this.m_indexB].a=d;a.positions[this.m_indexC].a=g;a.positions[this.m_indexD].a=l;return 0<box2d.b2_linearSlop};goog.exportProperty(box2d.b2GearJoint.prototype,\"SolvePositionConstraints\",box2d.b2GearJoint.prototype.SolvePositionConstraints);\nbox2d.b2GearJoint.prototype.SolvePositionConstraints.s_u=new box2d.b2Vec2;box2d.b2GearJoint.prototype.SolvePositionConstraints.s_rA=new box2d.b2Vec2;box2d.b2GearJoint.prototype.SolvePositionConstraints.s_rB=new box2d.b2Vec2;box2d.b2GearJoint.prototype.SolvePositionConstraints.s_rC=new box2d.b2Vec2;box2d.b2GearJoint.prototype.SolvePositionConstraints.s_rD=new box2d.b2Vec2;box2d.b2GearJoint.prototype.GetAnchorA=function(a){return this.m_bodyA.GetWorldPoint(this.m_localAnchorA,a)};\ngoog.exportProperty(box2d.b2GearJoint.prototype,\"GetAnchorA\",box2d.b2GearJoint.prototype.GetAnchorA);box2d.b2GearJoint.prototype.GetAnchorB=function(a){return this.m_bodyB.GetWorldPoint(this.m_localAnchorB,a)};goog.exportProperty(box2d.b2GearJoint.prototype,\"GetAnchorB\",box2d.b2GearJoint.prototype.GetAnchorB);box2d.b2GearJoint.prototype.GetReactionForce=function(a,b){return box2d.b2MulSV(a*this.m_impulse,this.m_JvAC,b)};goog.exportProperty(box2d.b2GearJoint.prototype,\"GetReactionForce\",box2d.b2GearJoint.prototype.GetReactionForce);\nbox2d.b2GearJoint.prototype.GetReactionTorque=function(a){return a*this.m_impulse*this.m_JwA};goog.exportProperty(box2d.b2GearJoint.prototype,\"GetReactionTorque\",box2d.b2GearJoint.prototype.GetReactionTorque);box2d.b2GearJoint.prototype.GetJoint1=function(){return this.m_joint1};goog.exportProperty(box2d.b2GearJoint.prototype,\"GetJoint1\",box2d.b2GearJoint.prototype.GetJoint1);box2d.b2GearJoint.prototype.GetJoint2=function(){return this.m_joint2};\ngoog.exportProperty(box2d.b2GearJoint.prototype,\"GetJoint2\",box2d.b2GearJoint.prototype.GetJoint2);box2d.b2GearJoint.prototype.GetRatio=function(){return this.m_ratio};goog.exportProperty(box2d.b2GearJoint.prototype,\"GetRatio\",box2d.b2GearJoint.prototype.GetRatio);box2d.b2GearJoint.prototype.SetRatio=function(a){box2d.ENABLE_ASSERTS&&box2d.b2Assert(box2d.b2IsValid(a));this.m_ratio=a};goog.exportProperty(box2d.b2GearJoint.prototype,\"SetRatio\",box2d.b2GearJoint.prototype.SetRatio);\nbox2d.b2GearJoint.prototype.Dump=function(){if(box2d.DEBUG){var a=this.m_bodyA.m_islandIndex,b=this.m_bodyB.m_islandIndex,c=this.m_joint1.m_index,e=this.m_joint2.m_index;box2d.b2Log(\"  /*box2d.b2GearJointDef*/ var jd = new box2d.b2GearJointDef();\\n\");box2d.b2Log(\"  jd.bodyA = bodies[%d];\\n\",a);box2d.b2Log(\"  jd.bodyB = bodies[%d];\\n\",b);box2d.b2Log(\"  jd.collideConnected = %s;\\n\",this.m_collideConnected?\"true\":\"false\");box2d.b2Log(\"  jd.joint1 = joints[%d];\\n\",c);box2d.b2Log(\"  jd.joint2 = joints[%d];\\n\",\ne);box2d.b2Log(\"  jd.ratio = %.15f;\\n\",this.m_ratio);box2d.b2Log(\"  joints[%d] = this.m_world.CreateJoint(jd);\\n\",this.m_index)}};goog.exportProperty(box2d.b2GearJoint.prototype,\"Dump\",box2d.b2GearJoint.prototype.Dump);box2d.b2DistanceProxy=function(){this.m_buffer=box2d.b2Vec2.MakeArray(2)};goog.exportSymbol(\"box2d.b2DistanceProxy\",box2d.b2DistanceProxy);box2d.b2DistanceProxy.prototype.m_buffer=null;goog.exportProperty(box2d.b2DistanceProxy.prototype,\"m_buffer\",box2d.b2DistanceProxy.prototype.m_buffer);box2d.b2DistanceProxy.prototype.m_vertices=null;goog.exportProperty(box2d.b2DistanceProxy.prototype,\"m_vertices\",box2d.b2DistanceProxy.prototype.m_vertices);box2d.b2DistanceProxy.prototype.m_count=0;\ngoog.exportProperty(box2d.b2DistanceProxy.prototype,\"m_count\",box2d.b2DistanceProxy.prototype.m_count);box2d.b2DistanceProxy.prototype.m_radius=0;goog.exportProperty(box2d.b2DistanceProxy.prototype,\"m_radius\",box2d.b2DistanceProxy.prototype.m_radius);box2d.b2DistanceProxy.prototype.Reset=function(){this.m_vertices=null;this.m_radius=this.m_count=0;return this};goog.exportProperty(box2d.b2DistanceProxy.prototype,\"Reset\",box2d.b2DistanceProxy.prototype.Reset);\nbox2d.b2DistanceProxy.prototype.SetShape=function(a,b){a.SetupDistanceProxy(this,b)};goog.exportProperty(box2d.b2DistanceProxy.prototype,\"SetShape\",box2d.b2DistanceProxy.prototype.SetShape);box2d.b2DistanceProxy.prototype.GetSupport=function(a){for(var b=0,c=box2d.b2DotVV(this.m_vertices[0],a),e=1;e<this.m_count;++e){var d=box2d.b2DotVV(this.m_vertices[e],a);d>c&&(b=e,c=d)}return b};goog.exportProperty(box2d.b2DistanceProxy.prototype,\"GetSupport\",box2d.b2DistanceProxy.prototype.GetSupport);\nbox2d.b2DistanceProxy.prototype.GetSupportVertex=function(a,b){for(var c=0,e=box2d.b2DotVV(this.m_vertices[0],a),d=1;d<this.m_count;++d){var f=box2d.b2DotVV(this.m_vertices[d],a);f>e&&(c=d,e=f)}return b.Copy(this.m_vertices[c])};goog.exportProperty(box2d.b2DistanceProxy.prototype,\"GetSupportVertex\",box2d.b2DistanceProxy.prototype.GetSupportVertex);box2d.b2DistanceProxy.prototype.GetVertexCount=function(){return this.m_count};goog.exportProperty(box2d.b2DistanceProxy.prototype,\"GetVertexCount\",box2d.b2DistanceProxy.prototype.GetVertexCount);\nbox2d.b2DistanceProxy.prototype.GetVertex=function(a){box2d.ENABLE_ASSERTS&&box2d.b2Assert(0<=a&&a<this.m_count);return this.m_vertices[a]};goog.exportProperty(box2d.b2DistanceProxy.prototype,\"GetVertex\",box2d.b2DistanceProxy.prototype.GetVertex);box2d.b2SimplexCache=function(){this.indexA=box2d.b2MakeNumberArray(3);this.indexB=box2d.b2MakeNumberArray(3)};goog.exportSymbol(\"box2d.b2SimplexCache\",box2d.b2SimplexCache);box2d.b2SimplexCache.prototype.metric=0;\ngoog.exportProperty(box2d.b2SimplexCache.prototype,\"metric\",box2d.b2SimplexCache.prototype.metric);box2d.b2SimplexCache.prototype.count=0;goog.exportProperty(box2d.b2SimplexCache.prototype,\"count\",box2d.b2SimplexCache.prototype.count);box2d.b2SimplexCache.prototype.indexA=null;goog.exportProperty(box2d.b2SimplexCache.prototype,\"indexA\",box2d.b2SimplexCache.prototype.indexA);box2d.b2SimplexCache.prototype.indexB=null;goog.exportProperty(box2d.b2SimplexCache.prototype,\"indexB\",box2d.b2SimplexCache.prototype.indexB);\nbox2d.b2SimplexCache.prototype.Reset=function(){this.count=this.metric=0;return this};goog.exportProperty(box2d.b2SimplexCache.prototype,\"Reset\",box2d.b2SimplexCache.prototype.Reset);box2d.b2DistanceInput=function(){this.proxyA=new box2d.b2DistanceProxy;this.proxyB=new box2d.b2DistanceProxy;this.transformA=new box2d.b2Transform;this.transformB=new box2d.b2Transform};goog.exportSymbol(\"box2d.b2DistanceInput\",box2d.b2DistanceInput);box2d.b2DistanceInput.prototype.proxyA=null;\ngoog.exportProperty(box2d.b2DistanceInput.prototype,\"proxyA\",box2d.b2DistanceInput.prototype.proxyA);box2d.b2DistanceInput.prototype.proxyB=null;goog.exportProperty(box2d.b2DistanceInput.prototype,\"proxyB\",box2d.b2DistanceInput.prototype.proxyB);box2d.b2DistanceInput.prototype.transformA=null;goog.exportProperty(box2d.b2DistanceInput.prototype,\"transformA\",box2d.b2DistanceInput.prototype.transformA);box2d.b2DistanceInput.prototype.transformB=null;\ngoog.exportProperty(box2d.b2DistanceInput.prototype,\"transformB\",box2d.b2DistanceInput.prototype.transformB);box2d.b2DistanceInput.prototype.useRadii=!1;goog.exportProperty(box2d.b2DistanceInput.prototype,\"useRadii\",box2d.b2DistanceInput.prototype.useRadii);box2d.b2DistanceInput.prototype.Reset=function(){this.proxyA.Reset();this.proxyB.Reset();this.transformA.SetIdentity();this.transformB.SetIdentity();this.useRadii=!1;return this};goog.exportProperty(box2d.b2DistanceInput.prototype,\"Reset\",box2d.b2DistanceInput.prototype.Reset);\nbox2d.b2DistanceOutput=function(){this.pointA=new box2d.b2Vec2;this.pointB=new box2d.b2Vec2};goog.exportSymbol(\"box2d.b2DistanceOutput\",box2d.b2DistanceOutput);box2d.b2DistanceOutput.prototype.pointA=null;goog.exportProperty(box2d.b2DistanceOutput.prototype,\"pointA\",box2d.b2DistanceOutput.prototype.pointA);box2d.b2DistanceOutput.prototype.pointB=null;goog.exportProperty(box2d.b2DistanceOutput.prototype,\"pointB\",box2d.b2DistanceOutput.prototype.pointB);box2d.b2DistanceOutput.prototype.distance=0;\ngoog.exportProperty(box2d.b2DistanceOutput.prototype,\"distance\",box2d.b2DistanceOutput.prototype.distance);box2d.b2DistanceOutput.prototype.iterations=0;goog.exportProperty(box2d.b2DistanceOutput.prototype,\"iterations\",box2d.b2DistanceOutput.prototype.iterations);box2d.b2DistanceOutput.prototype.Reset=function(){this.pointA.SetZero();this.pointB.SetZero();this.iterations=this.distance=0;return this};goog.exportProperty(box2d.b2DistanceOutput.prototype,\"Reset\",box2d.b2DistanceOutput.prototype.Reset);\nbox2d.b2_gjkCalls=0;goog.exportSymbol(\"box2d.b2_gjkCalls\",box2d.b2_gjkCalls);box2d.b2_gjkIters=0;goog.exportSymbol(\"box2d.b2_gjkIters\",box2d.b2_gjkIters);box2d.b2_gjkMaxIters=0;goog.exportSymbol(\"box2d.b2_gjkMaxIters\",box2d.b2_gjkMaxIters);box2d.b2SimplexVertex=function(){this.wA=new box2d.b2Vec2;this.wB=new box2d.b2Vec2;this.w=new box2d.b2Vec2};goog.exportSymbol(\"box2d.b2SimplexVertex\",box2d.b2SimplexVertex);box2d.b2SimplexVertex.prototype.wA=null;\ngoog.exportProperty(box2d.b2SimplexVertex.prototype,\"wA\",box2d.b2SimplexVertex.prototype.wA);box2d.b2SimplexVertex.prototype.wB=null;goog.exportProperty(box2d.b2SimplexVertex.prototype,\"wB\",box2d.b2SimplexVertex.prototype.wB);box2d.b2SimplexVertex.prototype.w=null;goog.exportProperty(box2d.b2SimplexVertex.prototype,\"w\",box2d.b2SimplexVertex.prototype.w);box2d.b2SimplexVertex.prototype.a=0;goog.exportProperty(box2d.b2SimplexVertex.prototype,\"a\",box2d.b2SimplexVertex.prototype.a);\nbox2d.b2SimplexVertex.prototype.indexA=0;goog.exportProperty(box2d.b2SimplexVertex.prototype,\"indexA\",box2d.b2SimplexVertex.prototype.indexA);box2d.b2SimplexVertex.prototype.indexB=0;goog.exportProperty(box2d.b2SimplexVertex.prototype,\"indexB\",box2d.b2SimplexVertex.prototype.indexB);box2d.b2SimplexVertex.prototype.Copy=function(a){this.wA.Copy(a.wA);this.wB.Copy(a.wB);this.w.Copy(a.w);this.a=a.a;this.indexA=a.indexA;this.indexB=a.indexB;return this};\ngoog.exportProperty(box2d.b2SimplexVertex.prototype,\"Copy\",box2d.b2SimplexVertex.prototype.Copy);box2d.b2Simplex=function(){this.m_v1=new box2d.b2SimplexVertex;this.m_v2=new box2d.b2SimplexVertex;this.m_v3=new box2d.b2SimplexVertex;this.m_vertices=Array(3);this.m_vertices[0]=this.m_v1;this.m_vertices[1]=this.m_v2;this.m_vertices[2]=this.m_v3};goog.exportSymbol(\"box2d.b2Simplex\",box2d.b2Simplex);box2d.b2Simplex.prototype.m_v1=null;goog.exportProperty(box2d.b2Simplex.prototype,\"m_v1\",box2d.b2Simplex.prototype.m_v1);\nbox2d.b2Simplex.prototype.m_v2=null;goog.exportProperty(box2d.b2Simplex.prototype,\"m_v2\",box2d.b2Simplex.prototype.m_v2);box2d.b2Simplex.prototype.m_v3=null;goog.exportProperty(box2d.b2Simplex.prototype,\"m_v3\",box2d.b2Simplex.prototype.m_v3);box2d.b2Simplex.prototype.m_vertices=null;goog.exportProperty(box2d.b2Simplex.prototype,\"m_vertices\",box2d.b2Simplex.prototype.m_vertices);box2d.b2Simplex.prototype.m_count=0;goog.exportProperty(box2d.b2Simplex.prototype,\"m_count\",box2d.b2Simplex.prototype.m_count);\nbox2d.b2Simplex.prototype.ReadCache=function(a,b,c,e,d){box2d.ENABLE_ASSERTS&&box2d.b2Assert(0<=a.count&&3>=a.count);this.m_count=a.count;for(var f=this.m_vertices,g=0;g<this.m_count;++g){var h=f[g];h.indexA=a.indexA[g];h.indexB=a.indexB[g];var l=b.GetVertex(h.indexA),k=e.GetVertex(h.indexB);box2d.b2MulXV(c,l,h.wA);box2d.b2MulXV(d,k,h.wB);box2d.b2SubVV(h.wB,h.wA,h.w);h.a=0}1<this.m_count&&(a=a.metric,g=this.GetMetric(),g<0.5*a||2*a<g||g<box2d.b2_epsilon)&&(this.m_count=0);0===this.m_count&&(h=f[0],\nh.indexA=0,h.indexB=0,l=b.GetVertex(0),k=e.GetVertex(0),box2d.b2MulXV(c,l,h.wA),box2d.b2MulXV(d,k,h.wB),box2d.b2SubVV(h.wB,h.wA,h.w),this.m_count=h.a=1)};goog.exportProperty(box2d.b2Simplex.prototype,\"ReadCache\",box2d.b2Simplex.prototype.ReadCache);box2d.b2Simplex.prototype.WriteCache=function(a){a.metric=this.GetMetric();a.count=this.m_count;for(var b=this.m_vertices,c=0;c<this.m_count;++c)a.indexA[c]=b[c].indexA,a.indexB[c]=b[c].indexB};\ngoog.exportProperty(box2d.b2Simplex.prototype,\"WriteCache\",box2d.b2Simplex.prototype.WriteCache);box2d.b2Simplex.prototype.GetSearchDirection=function(a){switch(this.m_count){case 1:return box2d.b2NegV(this.m_v1.w,a);case 2:var b=box2d.b2SubVV(this.m_v2.w,this.m_v1.w,a);return 0<box2d.b2CrossVV(b,box2d.b2NegV(this.m_v1.w,box2d.b2Vec2.s_t0))?box2d.b2CrossOneV(b,a):box2d.b2CrossVOne(b,a);default:return box2d.ENABLE_ASSERTS&&box2d.b2Assert(!1),a.SetZero()}};\ngoog.exportProperty(box2d.b2Simplex.prototype,\"GetSearchDirection\",box2d.b2Simplex.prototype.GetSearchDirection);box2d.b2Simplex.prototype.GetClosestPoint=function(a){switch(this.m_count){case 0:return box2d.ENABLE_ASSERTS&&box2d.b2Assert(!1),a.SetZero();case 1:return a.Copy(this.m_v1.w);case 2:return a.SetXY(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);case 3:return a.SetZero();default:return box2d.ENABLE_ASSERTS&&box2d.b2Assert(!1),a.SetZero()}};\ngoog.exportProperty(box2d.b2Simplex.prototype,\"GetClosestPoint\",box2d.b2Simplex.prototype.GetClosestPoint);\nbox2d.b2Simplex.prototype.GetWitnessPoints=function(a,b){switch(this.m_count){case 0:box2d.ENABLE_ASSERTS&&box2d.b2Assert(!1);break;case 1:a.Copy(this.m_v1.wA);b.Copy(this.m_v1.wB);break;case 2:a.x=this.m_v1.a*this.m_v1.wA.x+this.m_v2.a*this.m_v2.wA.x;a.y=this.m_v1.a*this.m_v1.wA.y+this.m_v2.a*this.m_v2.wA.y;b.x=this.m_v1.a*this.m_v1.wB.x+this.m_v2.a*this.m_v2.wB.x;b.y=this.m_v1.a*this.m_v1.wB.y+this.m_v2.a*this.m_v2.wB.y;break;case 3:b.x=a.x=this.m_v1.a*this.m_v1.wA.x+this.m_v2.a*this.m_v2.wA.x+\nthis.m_v3.a*this.m_v3.wA.x;b.y=a.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:box2d.ENABLE_ASSERTS&&box2d.b2Assert(!1)}};goog.exportProperty(box2d.b2Simplex.prototype,\"GetWitnessPoints\",box2d.b2Simplex.prototype.GetWitnessPoints);\nbox2d.b2Simplex.prototype.GetMetric=function(){switch(this.m_count){case 0:return box2d.ENABLE_ASSERTS&&box2d.b2Assert(!1),0;case 1:return 0;case 2:return box2d.b2DistanceVV(this.m_v1.w,this.m_v2.w);case 3:return box2d.b2CrossVV(box2d.b2SubVV(this.m_v2.w,this.m_v1.w,box2d.b2Vec2.s_t0),box2d.b2SubVV(this.m_v3.w,this.m_v1.w,box2d.b2Vec2.s_t1));default:return box2d.ENABLE_ASSERTS&&box2d.b2Assert(!1),0}};goog.exportProperty(box2d.b2Simplex.prototype,\"GetMetric\",box2d.b2Simplex.prototype.GetMetric);\nbox2d.b2Simplex.prototype.Solve2=function(){var a=this.m_v1.w,b=this.m_v2.w,c=box2d.b2SubVV(b,a,box2d.b2Simplex.s_e12),a=-box2d.b2DotVV(a,c);0>=a?this.m_count=this.m_v1.a=1:(b=box2d.b2DotVV(b,c),0>=b?(this.m_count=this.m_v2.a=1,this.m_v1.Copy(this.m_v2)):(c=1/(b+a),this.m_v1.a=b*c,this.m_v2.a=a*c,this.m_count=2))};goog.exportProperty(box2d.b2Simplex.prototype,\"Solve2\",box2d.b2Simplex.prototype.Solve2);\nbox2d.b2Simplex.prototype.Solve3=function(){var a=this.m_v1.w,b=this.m_v2.w,c=this.m_v3.w,e=box2d.b2SubVV(b,a,box2d.b2Simplex.s_e12),d=box2d.b2DotVV(a,e),f=box2d.b2DotVV(b,e),d=-d,g=box2d.b2SubVV(c,a,box2d.b2Simplex.s_e13),h=box2d.b2DotVV(a,g),l=box2d.b2DotVV(c,g),h=-h,k=box2d.b2SubVV(c,b,box2d.b2Simplex.s_e23),m=box2d.b2DotVV(b,k),k=box2d.b2DotVV(c,k),m=-m,g=box2d.b2CrossVV(e,g),e=g*box2d.b2CrossVV(b,c),c=g*box2d.b2CrossVV(c,a),a=g*box2d.b2CrossVV(a,b);0>=d&&0>=h?this.m_count=this.m_v1.a=1:0<f&&\n0<d&&0>=a?(l=1/(f+d),this.m_v1.a=f*l,this.m_v2.a=d*l,this.m_count=2):0<l&&0<h&&0>=c?(f=1/(l+h),this.m_v1.a=l*f,this.m_v3.a=h*f,this.m_count=2,this.m_v2.Copy(this.m_v3)):0>=f&&0>=m?(this.m_count=this.m_v2.a=1,this.m_v1.Copy(this.m_v2)):0>=l&&0>=k?(this.m_count=this.m_v3.a=1,this.m_v1.Copy(this.m_v3)):0<k&&0<m&&0>=e?(f=1/(k+m),this.m_v2.a=k*f,this.m_v3.a=m*f,this.m_count=2,this.m_v1.Copy(this.m_v3)):(f=1/(e+c+a),this.m_v1.a=e*f,this.m_v2.a=c*f,this.m_v3.a=a*f,this.m_count=3)};\ngoog.exportProperty(box2d.b2Simplex.prototype,\"Solve3\",box2d.b2Simplex.prototype.Solve3);box2d.b2Simplex.s_e12=new box2d.b2Vec2;box2d.b2Simplex.s_e13=new box2d.b2Vec2;box2d.b2Simplex.s_e23=new box2d.b2Vec2;\nbox2d.b2Distance=function(a,b,c){++box2d.b2_gjkCalls;var e=c.proxyA,d=c.proxyB,f=c.transformA,g=c.transformB,h=box2d.b2Distance.s_simplex;h.ReadCache(b,e,f,d,g);for(var l=h.m_vertices,k=box2d.b2Distance.s_saveA,m=box2d.b2Distance.s_saveB,n=0,p=0;20>p;){for(var n=h.m_count,q=0;q<n;++q)k[q]=l[q].indexA,m[q]=l[q].indexB;switch(h.m_count){case 1:break;case 2:h.Solve2();break;case 3:h.Solve3();break;default:box2d.ENABLE_ASSERTS&&box2d.b2Assert(!1)}if(3===h.m_count)break;var r=h.GetClosestPoint(box2d.b2Distance.s_p);\nr.GetLengthSquared();q=h.GetSearchDirection(box2d.b2Distance.s_d);if(q.GetLengthSquared()<box2d.b2_epsilon_sq)break;r=l[h.m_count];r.indexA=e.GetSupport(box2d.b2MulTRV(f.q,box2d.b2NegV(q,box2d.b2Vec2.s_t0),box2d.b2Distance.s_supportA));box2d.b2MulXV(f,e.GetVertex(r.indexA),r.wA);r.indexB=d.GetSupport(box2d.b2MulTRV(g.q,q,box2d.b2Distance.s_supportB));box2d.b2MulXV(g,d.GetVertex(r.indexB),r.wB);box2d.b2SubVV(r.wB,r.wA,r.w);++p;++box2d.b2_gjkIters;for(var t=!1,q=0;q<n;++q)if(r.indexA===k[q]&&r.indexB===\nm[q]){t=!0;break}if(t)break;++h.m_count}box2d.b2_gjkMaxIters=box2d.b2Max(box2d.b2_gjkMaxIters,p);h.GetWitnessPoints(a.pointA,a.pointB);a.distance=box2d.b2DistanceVV(a.pointA,a.pointB);a.iterations=p;h.WriteCache(b);c.useRadii&&(b=e.m_radius,d=d.m_radius,a.distance>b+d&&a.distance>box2d.b2_epsilon?(a.distance-=b+d,c=box2d.b2SubVV(a.pointB,a.pointA,box2d.b2Distance.s_normal),c.Normalize(),a.pointA.SelfMulAdd(b,c),a.pointB.SelfMulSub(d,c)):(r=box2d.b2MidVV(a.pointA,a.pointB,box2d.b2Distance.s_p),a.pointA.Copy(r),\na.pointB.Copy(r),a.distance=0))};goog.exportSymbol(\"box2d.b2Distance\",box2d.b2Distance);box2d.b2Distance.s_simplex=new box2d.b2Simplex;box2d.b2Distance.s_saveA=box2d.b2MakeNumberArray(3);box2d.b2Distance.s_saveB=box2d.b2MakeNumberArray(3);box2d.b2Distance.s_p=new box2d.b2Vec2;box2d.b2Distance.s_d=new box2d.b2Vec2;box2d.b2Distance.s_normal=new box2d.b2Vec2;box2d.b2Distance.s_supportA=new box2d.b2Vec2;box2d.b2Distance.s_supportB=new box2d.b2Vec2;box2d.b2WeldJointDef=function(){box2d.b2JointDef.call(this,box2d.b2JointType.e_weldJoint);this.localAnchorA=new box2d.b2Vec2;this.localAnchorB=new box2d.b2Vec2};goog.inherits(box2d.b2WeldJointDef,box2d.b2JointDef);goog.exportSymbol(\"box2d.b2WeldJointDef\",box2d.b2WeldJointDef);box2d.b2WeldJointDef.prototype.localAnchorA=null;goog.exportProperty(box2d.b2WeldJointDef.prototype,\"localAnchorA\",box2d.b2WeldJointDef.prototype.localAnchorA);box2d.b2WeldJointDef.prototype.localAnchorB=null;\ngoog.exportProperty(box2d.b2WeldJointDef.prototype,\"localAnchorB\",box2d.b2WeldJointDef.prototype.localAnchorB);box2d.b2WeldJointDef.prototype.referenceAngle=0;goog.exportProperty(box2d.b2WeldJointDef.prototype,\"referenceAngle\",box2d.b2WeldJointDef.prototype.referenceAngle);box2d.b2WeldJointDef.prototype.frequencyHz=0;goog.exportProperty(box2d.b2WeldJointDef.prototype,\"frequencyHz\",box2d.b2WeldJointDef.prototype.frequencyHz);box2d.b2WeldJointDef.prototype.dampingRatio=0;\ngoog.exportProperty(box2d.b2WeldJointDef.prototype,\"dampingRatio\",box2d.b2WeldJointDef.prototype.dampingRatio);box2d.b2WeldJointDef.prototype.Initialize=function(a,b,c){this.bodyA=a;this.bodyB=b;this.bodyA.GetLocalPoint(c,this.localAnchorA);this.bodyB.GetLocalPoint(c,this.localAnchorB);this.referenceAngle=this.bodyB.GetAngleRadians()-this.bodyA.GetAngleRadians()};goog.exportProperty(box2d.b2WeldJointDef.prototype,\"Initialize\",box2d.b2WeldJointDef.prototype.Initialize);\nbox2d.b2WeldJoint=function(a){box2d.b2Joint.call(this,a);this.m_frequencyHz=a.frequencyHz;this.m_dampingRatio=a.dampingRatio;this.m_localAnchorA=a.localAnchorA.Clone();this.m_localAnchorB=a.localAnchorB.Clone();this.m_referenceAngle=a.referenceAngle;this.m_impulse=new box2d.b2Vec3(0,0,0);this.m_rA=new box2d.b2Vec2;this.m_rB=new box2d.b2Vec2;this.m_localCenterA=new box2d.b2Vec2;this.m_localCenterB=new box2d.b2Vec2;this.m_mass=new box2d.b2Mat33;this.m_qA=new box2d.b2Rot;this.m_qB=new box2d.b2Rot;this.m_lalcA=\nnew box2d.b2Vec2;this.m_lalcB=new box2d.b2Vec2;this.m_K=new box2d.b2Mat33};goog.inherits(box2d.b2WeldJoint,box2d.b2Joint);goog.exportSymbol(\"box2d.b2WeldJoint\",box2d.b2WeldJoint);box2d.b2WeldJoint.prototype.m_frequencyHz=0;goog.exportProperty(box2d.b2WeldJoint.prototype,\"m_frequencyHz\",box2d.b2WeldJoint.prototype.m_frequencyHz);box2d.b2WeldJoint.prototype.m_dampingRatio=0;goog.exportProperty(box2d.b2WeldJoint.prototype,\"m_dampingRatio\",box2d.b2WeldJoint.prototype.m_dampingRatio);\nbox2d.b2WeldJoint.prototype.m_bias=0;goog.exportProperty(box2d.b2WeldJoint.prototype,\"m_bias\",box2d.b2WeldJoint.prototype.m_bias);box2d.b2WeldJoint.prototype.m_localAnchorA=null;goog.exportProperty(box2d.b2WeldJoint.prototype,\"m_localAnchorA\",box2d.b2WeldJoint.prototype.m_localAnchorA);box2d.b2WeldJoint.prototype.m_localAnchorB=null;goog.exportProperty(box2d.b2WeldJoint.prototype,\"m_localAnchorB\",box2d.b2WeldJoint.prototype.m_localAnchorB);box2d.b2WeldJoint.prototype.m_referenceAngle=0;\ngoog.exportProperty(box2d.b2WeldJoint.prototype,\"m_referenceAngle\",box2d.b2WeldJoint.prototype.m_referenceAngle);box2d.b2WeldJoint.prototype.m_gamma=0;goog.exportProperty(box2d.b2WeldJoint.prototype,\"m_gamma\",box2d.b2WeldJoint.prototype.m_gamma);box2d.b2WeldJoint.prototype.m_impulse=null;goog.exportProperty(box2d.b2WeldJoint.prototype,\"m_impulse\",box2d.b2WeldJoint.prototype.m_impulse);box2d.b2WeldJoint.prototype.m_indexA=0;goog.exportProperty(box2d.b2WeldJoint.prototype,\"m_indexA\",box2d.b2WeldJoint.prototype.m_indexA);\nbox2d.b2WeldJoint.prototype.m_indexB=0;goog.exportProperty(box2d.b2WeldJoint.prototype,\"m_indexB\",box2d.b2WeldJoint.prototype.m_indexB);box2d.b2WeldJoint.prototype.m_rA=null;goog.exportProperty(box2d.b2WeldJoint.prototype,\"m_rA\",box2d.b2WeldJoint.prototype.m_rA);box2d.b2WeldJoint.prototype.m_rB=null;goog.exportProperty(box2d.b2WeldJoint.prototype,\"m_rB\",box2d.b2WeldJoint.prototype.m_rB);box2d.b2WeldJoint.prototype.m_localCenterA=null;\ngoog.exportProperty(box2d.b2WeldJoint.prototype,\"m_localCenterA\",box2d.b2WeldJoint.prototype.m_localCenterA);box2d.b2WeldJoint.prototype.m_localCenterB=null;goog.exportProperty(box2d.b2WeldJoint.prototype,\"m_localCenterB\",box2d.b2WeldJoint.prototype.m_localCenterB);box2d.b2WeldJoint.prototype.m_invMassA=0;goog.exportProperty(box2d.b2WeldJoint.prototype,\"m_invMassA\",box2d.b2WeldJoint.prototype.m_invMassA);box2d.b2WeldJoint.prototype.m_invMassB=0;\ngoog.exportProperty(box2d.b2WeldJoint.prototype,\"m_invMassB\",box2d.b2WeldJoint.prototype.m_invMassB);box2d.b2WeldJoint.prototype.m_invIA=0;goog.exportProperty(box2d.b2WeldJoint.prototype,\"m_invIA\",box2d.b2WeldJoint.prototype.m_invIA);box2d.b2WeldJoint.prototype.m_invIB=0;goog.exportProperty(box2d.b2WeldJoint.prototype,\"m_invIB\",box2d.b2WeldJoint.prototype.m_invIB);box2d.b2WeldJoint.prototype.m_mass=null;goog.exportProperty(box2d.b2WeldJoint.prototype,\"m_mass\",box2d.b2WeldJoint.prototype.m_mass);\nbox2d.b2WeldJoint.prototype.m_qA=null;goog.exportProperty(box2d.b2WeldJoint.prototype,\"m_qA\",box2d.b2WeldJoint.prototype.m_qA);box2d.b2WeldJoint.prototype.m_qB=null;goog.exportProperty(box2d.b2WeldJoint.prototype,\"m_qB\",box2d.b2WeldJoint.prototype.m_qB);box2d.b2WeldJoint.prototype.m_lalcA=null;goog.exportProperty(box2d.b2WeldJoint.prototype,\"m_lalcA\",box2d.b2WeldJoint.prototype.m_lalcA);box2d.b2WeldJoint.prototype.m_lalcB=null;goog.exportProperty(box2d.b2WeldJoint.prototype,\"m_lalcB\",box2d.b2WeldJoint.prototype.m_lalcB);\nbox2d.b2WeldJoint.prototype.m_K=null;goog.exportProperty(box2d.b2WeldJoint.prototype,\"m_K\",box2d.b2WeldJoint.prototype.m_K);\nbox2d.b2WeldJoint.prototype.InitVelocityConstraints=function(a){this.m_indexA=this.m_bodyA.m_islandIndex;this.m_indexB=this.m_bodyB.m_islandIndex;this.m_localCenterA.Copy(this.m_bodyA.m_sweep.localCenter);this.m_localCenterB.Copy(this.m_bodyB.m_sweep.localCenter);this.m_invMassA=this.m_bodyA.m_invMass;this.m_invMassB=this.m_bodyB.m_invMass;this.m_invIA=this.m_bodyA.m_invI;this.m_invIB=this.m_bodyB.m_invI;var b=a.positions[this.m_indexA].a,c=a.velocities[this.m_indexA].v,e=a.velocities[this.m_indexA].w,\nd=a.positions[this.m_indexB].a,f=a.velocities[this.m_indexB].v,g=a.velocities[this.m_indexB].w,h=this.m_qA.SetAngleRadians(b),l=this.m_qB.SetAngleRadians(d);box2d.b2SubVV(this.m_localAnchorA,this.m_localCenterA,this.m_lalcA);box2d.b2MulRV(h,this.m_lalcA,this.m_rA);box2d.b2SubVV(this.m_localAnchorB,this.m_localCenterB,this.m_lalcB);box2d.b2MulRV(l,this.m_lalcB,this.m_rB);var h=this.m_invMassA,l=this.m_invMassB,k=this.m_invIA,m=this.m_invIB,n=this.m_K;n.ex.x=h+l+this.m_rA.y*this.m_rA.y*k+this.m_rB.y*\nthis.m_rB.y*m;n.ey.x=-this.m_rA.y*this.m_rA.x*k-this.m_rB.y*this.m_rB.x*m;n.ez.x=-this.m_rA.y*k-this.m_rB.y*m;n.ex.y=n.ey.x;n.ey.y=h+l+this.m_rA.x*this.m_rA.x*k+this.m_rB.x*this.m_rB.x*m;n.ez.y=this.m_rA.x*k+this.m_rB.x*m;n.ex.z=n.ez.x;n.ey.z=n.ez.y;n.ez.z=k+m;if(0<this.m_frequencyHz){n.GetInverse22(this.m_mass);var n=k+m,p=0<n?1/n:0,b=d-b-this.m_referenceAngle,d=2*box2d.b2_pi*this.m_frequencyHz,q=p*d*d,r=a.step.dt;this.m_gamma=r*(2*p*this.m_dampingRatio*d+r*q);this.m_gamma=0!==this.m_gamma?1/this.m_gamma:\n0;this.m_bias=b*r*q*this.m_gamma;n+=this.m_gamma;this.m_mass.ez.z=0!==n?1/n:0}else n.GetSymInverse33(this.m_mass),this.m_bias=this.m_gamma=0;a.step.warmStarting?(this.m_impulse.SelfMul(a.step.dtRatio),n=box2d.b2WeldJoint.prototype.InitVelocityConstraints.s_P.SetXY(this.m_impulse.x,this.m_impulse.y),c.SelfMulSub(h,n),e-=k*(box2d.b2CrossVV(this.m_rA,n)+this.m_impulse.z),f.SelfMulAdd(l,n),g+=m*(box2d.b2CrossVV(this.m_rB,n)+this.m_impulse.z)):this.m_impulse.SetZero();a.velocities[this.m_indexA].w=e;a.velocities[this.m_indexB].w=\ng};box2d.b2WeldJoint.prototype.InitVelocityConstraints.s_P=new box2d.b2Vec2;\nbox2d.b2WeldJoint.prototype.SolveVelocityConstraints=function(a){var b=a.velocities[this.m_indexA].v,c=a.velocities[this.m_indexA].w,e=a.velocities[this.m_indexB].v,d=a.velocities[this.m_indexB].w,f=this.m_invMassA,g=this.m_invMassB,h=this.m_invIA,l=this.m_invIB;if(0<this.m_frequencyHz){var k=-this.m_mass.ez.z*(d-c+this.m_bias+this.m_gamma*this.m_impulse.z);this.m_impulse.z+=k;c-=h*k;d+=l*k;k=box2d.b2SubVV(box2d.b2AddVCrossSV(e,d,this.m_rB,box2d.b2Vec2.s_t0),box2d.b2AddVCrossSV(b,c,this.m_rA,box2d.b2Vec2.s_t1),\nbox2d.b2WeldJoint.prototype.SolveVelocityConstraints.s_Cdot1);k=box2d.b2MulM33XY(this.m_mass,k.x,k.y,box2d.b2WeldJoint.prototype.SolveVelocityConstraints.s_impulse1).SelfNeg();this.m_impulse.x+=k.x;this.m_impulse.y+=k.y;b.SelfMulSub(f,k);c-=h*box2d.b2CrossVV(this.m_rA,k);e.SelfMulAdd(g,k);d+=l*box2d.b2CrossVV(this.m_rB,k)}else{var k=box2d.b2SubVV(box2d.b2AddVCrossSV(e,d,this.m_rB,box2d.b2Vec2.s_t0),box2d.b2AddVCrossSV(b,c,this.m_rA,box2d.b2Vec2.s_t1),box2d.b2WeldJoint.prototype.SolveVelocityConstraints.s_Cdot1),\nm=box2d.b2MulM33XYZ(this.m_mass,k.x,k.y,d-c,box2d.b2WeldJoint.prototype.SolveVelocityConstraints.s_impulse).SelfNeg();this.m_impulse.SelfAdd(m);k=box2d.b2WeldJoint.prototype.SolveVelocityConstraints.s_P.SetXY(m.x,m.y);b.SelfMulSub(f,k);c-=h*(box2d.b2CrossVV(this.m_rA,k)+m.z);e.SelfMulAdd(g,k);d+=l*(box2d.b2CrossVV(this.m_rB,k)+m.z)}a.velocities[this.m_indexA].w=c;a.velocities[this.m_indexB].w=d};goog.exportProperty(box2d.b2WeldJoint.prototype,\"SolveVelocityConstraints\",box2d.b2WeldJoint.prototype.SolveVelocityConstraints);\nbox2d.b2WeldJoint.prototype.SolveVelocityConstraints.s_Cdot1=new box2d.b2Vec2;box2d.b2WeldJoint.prototype.SolveVelocityConstraints.s_impulse1=new box2d.b2Vec2;box2d.b2WeldJoint.prototype.SolveVelocityConstraints.s_impulse=new box2d.b2Vec3;box2d.b2WeldJoint.prototype.SolveVelocityConstraints.s_P=new box2d.b2Vec2;\nbox2d.b2WeldJoint.prototype.SolvePositionConstraints=function(a){var b=a.positions[this.m_indexA].c,c=a.positions[this.m_indexA].a,e=a.positions[this.m_indexB].c,d=a.positions[this.m_indexB].a,f=this.m_qA.SetAngleRadians(c),g=this.m_qB.SetAngleRadians(d),h=this.m_invMassA,l=this.m_invMassB,k=this.m_invIA,m=this.m_invIB;box2d.b2SubVV(this.m_localAnchorA,this.m_localCenterA,this.m_lalcA);var n=box2d.b2MulRV(f,this.m_lalcA,this.m_rA);box2d.b2SubVV(this.m_localAnchorB,this.m_localCenterB,this.m_lalcB);\nvar p=box2d.b2MulRV(g,this.m_lalcB,this.m_rB),q=this.m_K;q.ex.x=h+l+n.y*n.y*k+p.y*p.y*m;q.ey.x=-n.y*n.x*k-p.y*p.x*m;q.ez.x=-n.y*k-p.y*m;q.ex.y=q.ey.x;q.ey.y=h+l+n.x*n.x*k+p.x*p.x*m;q.ez.y=n.x*k+p.x*m;q.ex.z=q.ez.x;q.ey.z=q.ez.y;q.ez.z=k+m;if(0<this.m_frequencyHz){var r=box2d.b2SubVV(box2d.b2AddVV(e,p,box2d.b2Vec2.s_t0),box2d.b2AddVV(b,n,box2d.b2Vec2.s_t1),box2d.b2WeldJoint.prototype.SolvePositionConstraints.s_C1),g=r.GetLength(),f=0,q=q.Solve22(r.x,r.y,box2d.b2WeldJoint.prototype.SolvePositionConstraints.s_P).SelfNeg();\nb.SelfMulSub(h,q);c-=k*box2d.b2CrossVV(n,q);e.SelfMulAdd(l,q);d+=m*box2d.b2CrossVV(p,q)}else r=box2d.b2SubVV(box2d.b2AddVV(e,p,box2d.b2Vec2.s_t0),box2d.b2AddVV(b,n,box2d.b2Vec2.s_t1),box2d.b2WeldJoint.prototype.SolvePositionConstraints.s_C1),n=d-c-this.m_referenceAngle,g=r.GetLength(),f=box2d.b2Abs(n),n=q.Solve33(r.x,r.y,n,box2d.b2WeldJoint.prototype.SolvePositionConstraints.s_impulse).SelfNeg(),q=box2d.b2WeldJoint.prototype.SolvePositionConstraints.s_P.SetXY(n.x,n.y),b.SelfMulSub(h,q),c-=k*(box2d.b2CrossVV(this.m_rA,\nq)+n.z),e.SelfMulAdd(l,q),d+=m*(box2d.b2CrossVV(this.m_rB,q)+n.z);a.positions[this.m_indexA].a=c;a.positions[this.m_indexB].a=d;return g<=box2d.b2_linearSlop&&f<=box2d.b2_angularSlop};goog.exportProperty(box2d.b2WeldJoint.prototype,\"SolvePositionConstraints\",box2d.b2WeldJoint.prototype.SolvePositionConstraints);box2d.b2WeldJoint.prototype.SolvePositionConstraints.s_C1=new box2d.b2Vec2;box2d.b2WeldJoint.prototype.SolvePositionConstraints.s_P=new box2d.b2Vec2;\nbox2d.b2WeldJoint.prototype.SolvePositionConstraints.s_impulse=new box2d.b2Vec3;box2d.b2WeldJoint.prototype.GetAnchorA=function(a){return this.m_bodyA.GetWorldPoint(this.m_localAnchorA,a)};goog.exportProperty(box2d.b2WeldJoint.prototype,\"GetAnchorA\",box2d.b2WeldJoint.prototype.GetAnchorA);box2d.b2WeldJoint.prototype.GetAnchorB=function(a){return this.m_bodyB.GetWorldPoint(this.m_localAnchorB,a)};goog.exportProperty(box2d.b2WeldJoint.prototype,\"GetAnchorB\",box2d.b2WeldJoint.prototype.GetAnchorB);\nbox2d.b2WeldJoint.prototype.GetReactionForce=function(a,b){return b.SetXY(a*this.m_impulse.x,a*this.m_impulse.y)};goog.exportProperty(box2d.b2WeldJoint.prototype,\"GetReactionForce\",box2d.b2WeldJoint.prototype.GetReactionForce);box2d.b2WeldJoint.prototype.GetReactionTorque=function(a){return a*this.m_impulse.z};goog.exportProperty(box2d.b2WeldJoint.prototype,\"GetReactionTorque\",box2d.b2WeldJoint.prototype.GetReactionTorque);box2d.b2WeldJoint.prototype.GetLocalAnchorA=function(a){return a.Copy(this.m_localAnchorA)};\ngoog.exportProperty(box2d.b2WeldJoint.prototype,\"GetLocalAnchorA\",box2d.b2WeldJoint.prototype.GetLocalAnchorA);box2d.b2WeldJoint.prototype.GetLocalAnchorB=function(a){return a.Copy(this.m_localAnchorB)};goog.exportProperty(box2d.b2WeldJoint.prototype,\"GetLocalAnchorB\",box2d.b2WeldJoint.prototype.GetLocalAnchorB);box2d.b2WeldJoint.prototype.GetReferenceAngle=function(){return this.m_referenceAngle};goog.exportProperty(box2d.b2WeldJoint.prototype,\"GetReferenceAngle\",box2d.b2WeldJoint.prototype.GetReferenceAngle);\nbox2d.b2WeldJoint.prototype.SetFrequency=function(a){this.m_frequencyHz=a};box2d.b2WeldJoint.prototype.GetFrequency=function(){return this.m_frequencyHz};goog.exportProperty(box2d.b2WeldJoint.prototype,\"GetFrequency\",box2d.b2WeldJoint.prototype.GetFrequency);box2d.b2WeldJoint.prototype.SetDampingRatio=function(a){this.m_dampingRatio=a};box2d.b2WeldJoint.prototype.GetDampingRatio=function(){return this.m_dampingRatio};goog.exportProperty(box2d.b2WeldJoint.prototype,\"GetDampingRatio\",box2d.b2WeldJoint.prototype.GetDampingRatio);\nbox2d.b2WeldJoint.prototype.Dump=function(){if(box2d.DEBUG){var a=this.m_bodyA.m_islandIndex,b=this.m_bodyB.m_islandIndex;box2d.b2Log(\"  /*box2d.b2WeldJointDef*/ var jd = new box2d.b2WeldJointDef();\\n\");box2d.b2Log(\"  jd.bodyA = bodies[%d];\\n\",a);box2d.b2Log(\"  jd.bodyB = bodies[%d];\\n\",b);box2d.b2Log(\"  jd.collideConnected = %s;\\n\",this.m_collideConnected?\"true\":\"false\");box2d.b2Log(\"  jd.localAnchorA.SetXY(%.15f, %.15f);\\n\",this.m_localAnchorA.x,this.m_localAnchorA.y);box2d.b2Log(\"  jd.localAnchorB.SetXY(%.15f, %.15f);\\n\",\nthis.m_localAnchorB.x,this.m_localAnchorB.y);box2d.b2Log(\"  jd.referenceAngle = %.15f;\\n\",this.m_referenceAngle);box2d.b2Log(\"  jd.frequencyHz = %.15f;\\n\",this.m_frequencyHz);box2d.b2Log(\"  jd.dampingRatio = %.15f;\\n\",this.m_dampingRatio);box2d.b2Log(\"  joints[%d] = this.m_world.CreateJoint(jd);\\n\",this.m_index)}};goog.exportProperty(box2d.b2WeldJoint.prototype,\"Dump\",box2d.b2WeldJoint.prototype.Dump);box2d.b2RopeJointDef=function(){box2d.b2JointDef.call(this,box2d.b2JointType.e_ropeJoint);this.localAnchorA=new box2d.b2Vec2(-1,0);this.localAnchorB=new box2d.b2Vec2(1,0)};goog.inherits(box2d.b2RopeJointDef,box2d.b2JointDef);goog.exportSymbol(\"box2d.b2RopeJointDef\",box2d.b2RopeJointDef);box2d.b2RopeJointDef.prototype.localAnchorA=null;goog.exportProperty(box2d.b2RopeJointDef.prototype,\"localAnchorA\",box2d.b2RopeJointDef.prototype.localAnchorA);box2d.b2RopeJointDef.prototype.localAnchorB=null;\ngoog.exportProperty(box2d.b2RopeJointDef.prototype,\"localAnchorB\",box2d.b2RopeJointDef.prototype.localAnchorB);box2d.b2RopeJointDef.prototype.maxLength=0;goog.exportProperty(box2d.b2RopeJointDef.prototype,\"maxLength\",box2d.b2RopeJointDef.prototype.maxLength);\nbox2d.b2RopeJoint=function(a){box2d.b2Joint.call(this,a);this.m_localAnchorA=a.localAnchorA.Clone();this.m_localAnchorB=a.localAnchorB.Clone();this.m_maxLength=a.maxLength;this.m_u=new box2d.b2Vec2;this.m_rA=new box2d.b2Vec2;this.m_rB=new box2d.b2Vec2;this.m_localCenterA=new box2d.b2Vec2;this.m_localCenterB=new box2d.b2Vec2;this.m_qA=new box2d.b2Rot;this.m_qB=new box2d.b2Rot;this.m_lalcA=new box2d.b2Vec2;this.m_lalcB=new box2d.b2Vec2};goog.inherits(box2d.b2RopeJoint,box2d.b2Joint);\ngoog.exportSymbol(\"box2d.b2RopeJoint\",box2d.b2RopeJoint);box2d.b2RopeJoint.prototype.m_localAnchorA=null;goog.exportProperty(box2d.b2RopeJoint.prototype,\"m_localAnchorA\",box2d.b2RopeJoint.prototype.m_localAnchorA);box2d.b2RopeJoint.prototype.m_localAnchorB=null;goog.exportProperty(box2d.b2RopeJoint.prototype,\"m_localAnchorB\",box2d.b2RopeJoint.prototype.m_localAnchorB);box2d.b2RopeJoint.prototype.m_maxLength=0;goog.exportProperty(box2d.b2RopeJoint.prototype,\"m_maxLength\",box2d.b2RopeJoint.prototype.m_maxLength);\nbox2d.b2RopeJoint.prototype.m_length=0;goog.exportProperty(box2d.b2RopeJoint.prototype,\"m_length\",box2d.b2RopeJoint.prototype.m_length);box2d.b2RopeJoint.prototype.m_impulse=0;goog.exportProperty(box2d.b2RopeJoint.prototype,\"m_impulse\",box2d.b2RopeJoint.prototype.m_impulse);box2d.b2RopeJoint.prototype.m_indexA=0;goog.exportProperty(box2d.b2RopeJoint.prototype,\"m_indexA\",box2d.b2RopeJoint.prototype.m_indexA);box2d.b2RopeJoint.prototype.m_indexB=0;\ngoog.exportProperty(box2d.b2RopeJoint.prototype,\"m_indexB\",box2d.b2RopeJoint.prototype.m_indexB);box2d.b2RopeJoint.prototype.m_u=null;goog.exportProperty(box2d.b2RopeJoint.prototype,\"m_u\",box2d.b2RopeJoint.prototype.m_u);box2d.b2RopeJoint.prototype.m_rA=null;goog.exportProperty(box2d.b2RopeJoint.prototype,\"m_rA\",box2d.b2RopeJoint.prototype.m_rA);box2d.b2RopeJoint.prototype.m_rB=null;goog.exportProperty(box2d.b2RopeJoint.prototype,\"m_rB\",box2d.b2RopeJoint.prototype.m_rB);\nbox2d.b2RopeJoint.prototype.m_localCenterA=null;goog.exportProperty(box2d.b2RopeJoint.prototype,\"m_localCenterA\",box2d.b2RopeJoint.prototype.m_localCenterA);box2d.b2RopeJoint.prototype.m_localCenterB=null;goog.exportProperty(box2d.b2RopeJoint.prototype,\"m_localCenterB\",box2d.b2RopeJoint.prototype.m_localCenterB);box2d.b2RopeJoint.prototype.m_invMassA=0;goog.exportProperty(box2d.b2RopeJoint.prototype,\"m_invMassA\",box2d.b2RopeJoint.prototype.m_invMassA);box2d.b2RopeJoint.prototype.m_invMassB=0;\ngoog.exportProperty(box2d.b2RopeJoint.prototype,\"m_invMassB\",box2d.b2RopeJoint.prototype.m_invMassB);box2d.b2RopeJoint.prototype.m_invIA=0;goog.exportProperty(box2d.b2RopeJoint.prototype,\"m_invIA\",box2d.b2RopeJoint.prototype.m_invIA);box2d.b2RopeJoint.prototype.m_invIB=0;goog.exportProperty(box2d.b2RopeJoint.prototype,\"m_invIB\",box2d.b2RopeJoint.prototype.m_invIB);box2d.b2RopeJoint.prototype.m_mass=0;goog.exportProperty(box2d.b2RopeJoint.prototype,\"m_mass\",box2d.b2RopeJoint.prototype.m_mass);\nbox2d.b2RopeJoint.prototype.m_state=box2d.b2LimitState.e_inactiveLimit;goog.exportProperty(box2d.b2RopeJoint.prototype,\"m_state\",box2d.b2RopeJoint.prototype.m_state);box2d.b2RopeJoint.prototype.m_qA=null;goog.exportProperty(box2d.b2RopeJoint.prototype,\"m_qA\",box2d.b2RopeJoint.prototype.m_qA);box2d.b2RopeJoint.prototype.m_qB=null;goog.exportProperty(box2d.b2RopeJoint.prototype,\"m_qB\",box2d.b2RopeJoint.prototype.m_qB);box2d.b2RopeJoint.prototype.m_lalcA=null;\ngoog.exportProperty(box2d.b2RopeJoint.prototype,\"m_lalcA\",box2d.b2RopeJoint.prototype.m_lalcA);box2d.b2RopeJoint.prototype.m_lalcB=null;goog.exportProperty(box2d.b2RopeJoint.prototype,\"m_lalcB\",box2d.b2RopeJoint.prototype.m_lalcB);\nbox2d.b2RopeJoint.prototype.InitVelocityConstraints=function(a){this.m_indexA=this.m_bodyA.m_islandIndex;this.m_indexB=this.m_bodyB.m_islandIndex;this.m_localCenterA.Copy(this.m_bodyA.m_sweep.localCenter);this.m_localCenterB.Copy(this.m_bodyB.m_sweep.localCenter);this.m_invMassA=this.m_bodyA.m_invMass;this.m_invMassB=this.m_bodyB.m_invMass;this.m_invIA=this.m_bodyA.m_invI;this.m_invIB=this.m_bodyB.m_invI;var b=a.positions[this.m_indexA].c,c=a.velocities[this.m_indexA].v,e=a.velocities[this.m_indexA].w,\nd=a.positions[this.m_indexB].c,f=a.positions[this.m_indexB].a,g=a.velocities[this.m_indexB].v,h=a.velocities[this.m_indexB].w,l=this.m_qA.SetAngleRadians(a.positions[this.m_indexA].a),f=this.m_qB.SetAngleRadians(f);box2d.b2SubVV(this.m_localAnchorA,this.m_localCenterA,this.m_lalcA);box2d.b2MulRV(l,this.m_lalcA,this.m_rA);box2d.b2SubVV(this.m_localAnchorB,this.m_localCenterB,this.m_lalcB);box2d.b2MulRV(f,this.m_lalcB,this.m_rB);this.m_u.Copy(d).SelfAdd(this.m_rB).SelfSub(b).SelfSub(this.m_rA);this.m_length=\nthis.m_u.GetLength();this.m_state=0<this.m_length-this.m_maxLength?box2d.b2LimitState.e_atUpperLimit:box2d.b2LimitState.e_inactiveLimit;this.m_length>box2d.b2_linearSlop?(this.m_u.SelfMul(1/this.m_length),b=box2d.b2CrossVV(this.m_rA,this.m_u),d=box2d.b2CrossVV(this.m_rB,this.m_u),b=this.m_invMassA+this.m_invIA*b*b+this.m_invMassB+this.m_invIB*d*d,this.m_mass=0!==b?1/b:0,a.step.warmStarting?(this.m_impulse*=a.step.dtRatio,b=box2d.b2MulSV(this.m_impulse,this.m_u,box2d.b2RopeJoint.prototype.InitVelocityConstraints.s_P),\nc.SelfMulSub(this.m_invMassA,b),e-=this.m_invIA*box2d.b2CrossVV(this.m_rA,b),g.SelfMulAdd(this.m_invMassB,b),h+=this.m_invIB*box2d.b2CrossVV(this.m_rB,b)):this.m_impulse=0,a.velocities[this.m_indexA].w=e,a.velocities[this.m_indexB].w=h):(this.m_u.SetZero(),this.m_impulse=this.m_mass=0)};goog.exportProperty(box2d.b2RopeJoint.prototype,\"InitVelocityConstraints\",box2d.b2RopeJoint.prototype.InitVelocityConstraints);box2d.b2RopeJoint.prototype.InitVelocityConstraints.s_P=new box2d.b2Vec2;\nbox2d.b2RopeJoint.prototype.SolveVelocityConstraints=function(a){var b=a.velocities[this.m_indexA].v,c=a.velocities[this.m_indexA].w,e=a.velocities[this.m_indexB].v,d=a.velocities[this.m_indexB].w,f=box2d.b2AddVCrossSV(b,c,this.m_rA,box2d.b2RopeJoint.prototype.SolveVelocityConstraints.s_vpA),g=box2d.b2AddVCrossSV(e,d,this.m_rB,box2d.b2RopeJoint.prototype.SolveVelocityConstraints.s_vpB),h=this.m_length-this.m_maxLength,f=box2d.b2DotVV(this.m_u,box2d.b2SubVV(g,f,box2d.b2Vec2.s_t0));0>h&&(f+=a.step.inv_dt*\nh);h=-this.m_mass*f;f=this.m_impulse;this.m_impulse=box2d.b2Min(0,this.m_impulse+h);h=this.m_impulse-f;h=box2d.b2MulSV(h,this.m_u,box2d.b2RopeJoint.prototype.SolveVelocityConstraints.s_P);b.SelfMulSub(this.m_invMassA,h);c-=this.m_invIA*box2d.b2CrossVV(this.m_rA,h);e.SelfMulAdd(this.m_invMassB,h);d+=this.m_invIB*box2d.b2CrossVV(this.m_rB,h);a.velocities[this.m_indexA].w=c;a.velocities[this.m_indexB].w=d};goog.exportProperty(box2d.b2RopeJoint.prototype,\"SolveVelocityConstraints\",box2d.b2RopeJoint.prototype.SolveVelocityConstraints);\nbox2d.b2RopeJoint.prototype.SolveVelocityConstraints.s_vpA=new box2d.b2Vec2;box2d.b2RopeJoint.prototype.SolveVelocityConstraints.s_vpB=new box2d.b2Vec2;box2d.b2RopeJoint.prototype.SolveVelocityConstraints.s_P=new box2d.b2Vec2;\nbox2d.b2RopeJoint.prototype.SolvePositionConstraints=function(a){var b=a.positions[this.m_indexA].c,c=a.positions[this.m_indexA].a,e=a.positions[this.m_indexB].c,d=a.positions[this.m_indexB].a,f=this.m_qA.SetAngleRadians(c),g=this.m_qB.SetAngleRadians(d);box2d.b2SubVV(this.m_localAnchorA,this.m_localCenterA,this.m_lalcA);f=box2d.b2MulRV(f,this.m_lalcA,this.m_rA);box2d.b2SubVV(this.m_localAnchorB,this.m_localCenterB,this.m_lalcB);var g=box2d.b2MulRV(g,this.m_lalcB,this.m_rB),h=this.m_u.Copy(e).SelfAdd(g).SelfSub(b).SelfSub(f),\nl=h.Normalize(),k=l-this.m_maxLength,k=box2d.b2Clamp(k,0,box2d.b2_maxLinearCorrection),h=box2d.b2MulSV(-this.m_mass*k,h,box2d.b2RopeJoint.prototype.SolvePositionConstraints.s_P);b.SelfMulSub(this.m_invMassA,h);c-=this.m_invIA*box2d.b2CrossVV(f,h);e.SelfMulAdd(this.m_invMassB,h);d+=this.m_invIB*box2d.b2CrossVV(g,h);a.positions[this.m_indexA].a=c;a.positions[this.m_indexB].a=d;return l-this.m_maxLength<box2d.b2_linearSlop};goog.exportProperty(box2d.b2RopeJoint.prototype,\"SolvePositionConstraints\",box2d.b2RopeJoint.prototype.SolvePositionConstraints);\nbox2d.b2RopeJoint.prototype.SolvePositionConstraints.s_P=new box2d.b2Vec2;box2d.b2RopeJoint.prototype.GetAnchorA=function(a){return this.m_bodyA.GetWorldPoint(this.m_localAnchorA,a)};goog.exportProperty(box2d.b2RopeJoint.prototype,\"GetAnchorA\",box2d.b2RopeJoint.prototype.GetAnchorA);box2d.b2RopeJoint.prototype.GetAnchorB=function(a){return this.m_bodyB.GetWorldPoint(this.m_localAnchorB,a)};goog.exportProperty(box2d.b2RopeJoint.prototype,\"GetAnchorB\",box2d.b2RopeJoint.prototype.GetAnchorB);\nbox2d.b2RopeJoint.prototype.GetReactionForce=function(a,b){return box2d.b2MulSV(a*this.m_impulse,this.m_u,b)};goog.exportProperty(box2d.b2RopeJoint.prototype,\"GetReactionForce\",box2d.b2RopeJoint.prototype.GetReactionForce);box2d.b2RopeJoint.prototype.GetReactionTorque=function(a){return 0};goog.exportProperty(box2d.b2RopeJoint.prototype,\"GetReactionTorque\",box2d.b2RopeJoint.prototype.GetReactionTorque);box2d.b2RopeJoint.prototype.GetLocalAnchorA=function(a){return a.Copy(this.m_localAnchorA)};\ngoog.exportProperty(box2d.b2RopeJoint.prototype,\"GetLocalAnchorA\",box2d.b2RopeJoint.prototype.GetLocalAnchorA);box2d.b2RopeJoint.prototype.GetLocalAnchorB=function(a){return a.Copy(this.m_localAnchorB)};goog.exportProperty(box2d.b2RopeJoint.prototype,\"GetLocalAnchorB\",box2d.b2RopeJoint.prototype.GetLocalAnchorB);box2d.b2RopeJoint.prototype.SetMaxLength=function(a){this.m_maxLength=a};goog.exportProperty(box2d.b2RopeJoint.prototype,\"SetMaxLength\",box2d.b2RopeJoint.prototype.SetMaxLength);\nbox2d.b2RopeJoint.prototype.GetMaxLength=function(){return this.m_maxLength};goog.exportProperty(box2d.b2RopeJoint.prototype,\"GetMaxLength\",box2d.b2RopeJoint.prototype.GetMaxLength);box2d.b2RopeJoint.prototype.GetLimitState=function(){return this.m_state};goog.exportProperty(box2d.b2RopeJoint.prototype,\"GetLimitState\",box2d.b2RopeJoint.prototype.GetLimitState);\nbox2d.b2RopeJoint.prototype.Dump=function(){if(box2d.DEBUG){var a=this.m_bodyA.m_islandIndex,b=this.m_bodyB.m_islandIndex;box2d.b2Log(\"  /*box2d.b2RopeJointDef*/ var jd = new box2d.b2RopeJointDef();\\n\");box2d.b2Log(\"  jd.bodyA = bodies[%d];\\n\",a);box2d.b2Log(\"  jd.bodyB = bodies[%d];\\n\",b);box2d.b2Log(\"  jd.collideConnected = %s;\\n\",this.m_collideConnected?\"true\":\"false\");box2d.b2Log(\"  jd.localAnchorA.SetXY(%.15f, %.15f);\\n\",this.m_localAnchorA.x,this.m_localAnchorA.y);box2d.b2Log(\"  jd.localAnchorB.SetXY(%.15f, %.15f);\\n\",\nthis.m_localAnchorB.x,this.m_localAnchorB.y);box2d.b2Log(\"  jd.maxLength = %.15f;\\n\",this.m_maxLength);box2d.b2Log(\"  joints[%d] = this.m_world.CreateJoint(jd);\\n\",this.m_index)}};goog.exportProperty(box2d.b2RopeJoint.prototype,\"Dump\",box2d.b2RopeJoint.prototype.Dump);box2d.b2GravityController=function(){box2d.b2Controller.call(this)};goog.inherits(box2d.b2GravityController,box2d.b2Controller);goog.exportSymbol(\"box2d.b2GravityController\",box2d.b2GravityController);box2d.b2GravityController.prototype.G=1;goog.exportProperty(box2d.b2GravityController.prototype,\"G\",box2d.b2GravityController.prototype.G);box2d.b2GravityController.prototype.invSqr=!0;goog.exportProperty(box2d.b2GravityController.prototype,\"invSqr\",box2d.b2GravityController.prototype.invSqr);\nbox2d.b2GravityController.prototype.Step=function(a){if(this.invSqr)for(a=this.m_bodyList;a;a=a.nextBody)for(var b=a.body,c=b.GetWorldCenter(),e=b.GetMass(),d=this.m_bodyList;d!==a;d=d.nextBody){var f=d.body,g=f.GetWorldCenter(),h=f.GetMass(),l=g.x-c.x,k=g.y-c.y,m=l*l+k*k;m<box2d.b2_epsilon||(l=box2d.b2GravityController.prototype.Step.s_f.SetXY(l,k),l.SelfMul(this.G/m/box2d.b2Sqrt(m)*e*h),b.IsAwake()&&b.ApplyForce(l,c),f.IsAwake()&&f.ApplyForce(l.SelfMul(-1),g))}else for(a=this.m_bodyList;a;a=a.nextBody)for(b=\na.body,c=b.GetWorldCenter(),e=b.GetMass(),d=this.m_bodyList;d!==a;d=d.nextBody)f=d.body,g=f.GetWorldCenter(),h=f.GetMass(),l=g.x-c.x,k=g.y-c.y,m=l*l+k*k,m<box2d.b2_epsilon||(l=box2d.b2GravityController.prototype.Step.s_f.SetXY(l,k),l.SelfMul(this.G/m*e*h),b.IsAwake()&&b.ApplyForce(l,c),f.IsAwake()&&f.ApplyForce(l.SelfMul(-1),g))};goog.exportProperty(box2d.b2GravityController.prototype,\"Step\",box2d.b2GravityController.prototype.Step);box2d.b2GravityController.prototype.Step.s_f=new box2d.b2Vec2;box2d.b2Profile=function(){};goog.exportSymbol(\"box2d.b2Profile\",box2d.b2Profile);box2d.b2Profile.prototype.step=0;goog.exportProperty(box2d.b2Profile.prototype,\"step\",box2d.b2Profile.prototype.step);box2d.b2Profile.prototype.collide=0;goog.exportProperty(box2d.b2Profile.prototype,\"collide\",box2d.b2Profile.prototype.collide);box2d.b2Profile.prototype.solve=0;goog.exportProperty(box2d.b2Profile.prototype,\"solve\",box2d.b2Profile.prototype.solve);box2d.b2Profile.prototype.solveInit=0;\ngoog.exportProperty(box2d.b2Profile.prototype,\"solveInit\",box2d.b2Profile.prototype.solveInit);box2d.b2Profile.prototype.solveVelocity=0;goog.exportProperty(box2d.b2Profile.prototype,\"solveVelocity\",box2d.b2Profile.prototype.solveVelocity);box2d.b2Profile.prototype.solvePosition=0;goog.exportProperty(box2d.b2Profile.prototype,\"solvePosition\",box2d.b2Profile.prototype.solvePosition);box2d.b2Profile.prototype.broadphase=0;goog.exportProperty(box2d.b2Profile.prototype,\"broadphase\",box2d.b2Profile.prototype.broadphase);\nbox2d.b2Profile.prototype.solveTOI=0;goog.exportProperty(box2d.b2Profile.prototype,\"solveTOI\",box2d.b2Profile.prototype.solveTOI);box2d.b2Profile.prototype.Reset=function(){this.solveTOI=this.broadphase=this.solvePosition=this.solveVelocity=this.solveInit=this.solve=this.collide=this.step=0;return this};goog.exportProperty(box2d.b2Profile.prototype,\"Reset\",box2d.b2Profile.prototype.Reset);box2d.b2TimeStep=function(){};goog.exportSymbol(\"box2d.b2TimeStep\",box2d.b2TimeStep);\nbox2d.b2TimeStep.prototype.dt=0;goog.exportProperty(box2d.b2TimeStep.prototype,\"dt\",box2d.b2TimeStep.prototype.dt);box2d.b2TimeStep.prototype.inv_dt=0;goog.exportProperty(box2d.b2TimeStep.prototype,\"inv_dt\",box2d.b2TimeStep.prototype.inv_dt);box2d.b2TimeStep.prototype.dtRatio=0;goog.exportProperty(box2d.b2TimeStep.prototype,\"dtRatio\",box2d.b2TimeStep.prototype.dtRatio);box2d.b2TimeStep.prototype.velocityIterations=0;goog.exportProperty(box2d.b2TimeStep.prototype,\"velocityIterations\",box2d.b2TimeStep.prototype.velocityIterations);\nbox2d.b2TimeStep.prototype.positionIterations=0;goog.exportProperty(box2d.b2TimeStep.prototype,\"positionIterations\",box2d.b2TimeStep.prototype.positionIterations);box2d.b2TimeStep.prototype.warmStarting=!1;goog.exportProperty(box2d.b2TimeStep.prototype,\"warmStarting\",box2d.b2TimeStep.prototype.warmStarting);\nbox2d.b2TimeStep.prototype.Copy=function(a){this.dt=a.dt;this.inv_dt=a.inv_dt;this.dtRatio=a.dtRatio;this.positionIterations=a.positionIterations;this.velocityIterations=a.velocityIterations;this.warmStarting=a.warmStarting;return this};goog.exportProperty(box2d.b2TimeStep.prototype,\"Copy\",box2d.b2TimeStep.prototype.Copy);box2d.b2Position=function(){this.c=new box2d.b2Vec2};goog.exportSymbol(\"box2d.b2Position\",box2d.b2Position);box2d.b2Position.prototype.c=null;\ngoog.exportProperty(box2d.b2Position.prototype,\"c\",box2d.b2Position.prototype.c);box2d.b2Position.prototype.a=0;goog.exportProperty(box2d.b2Position.prototype,\"a\",box2d.b2Position.prototype.a);box2d.b2Position.MakeArray=function(a){return box2d.b2MakeArray(a,function(a){return new box2d.b2Position})};goog.exportProperty(box2d.b2Position,\"MakeArray\",box2d.b2Position.MakeArray);box2d.b2Velocity=function(){this.v=new box2d.b2Vec2};goog.exportSymbol(\"box2d.b2Velocity\",box2d.b2Velocity);\nbox2d.b2Velocity.prototype.v=null;goog.exportProperty(box2d.b2Velocity.prototype,\"v\",box2d.b2Velocity.prototype.v);box2d.b2Velocity.prototype.w=0;goog.exportProperty(box2d.b2Velocity.prototype,\"w\",box2d.b2Velocity.prototype.w);box2d.b2Velocity.MakeArray=function(a){return box2d.b2MakeArray(a,function(a){return new box2d.b2Velocity})};goog.exportProperty(box2d.b2Velocity,\"MakeArray\",box2d.b2Velocity.MakeArray);box2d.b2SolverData=function(){this.step=new box2d.b2TimeStep};\ngoog.exportSymbol(\"box2d.b2SolverData\",box2d.b2SolverData);box2d.b2SolverData.prototype.step=null;goog.exportProperty(box2d.b2SolverData.prototype,\"step\",box2d.b2SolverData.prototype.step);box2d.b2SolverData.prototype.positions=null;goog.exportProperty(box2d.b2SolverData.prototype,\"positions\",box2d.b2SolverData.prototype.positions);box2d.b2SolverData.prototype.velocities=null;goog.exportProperty(box2d.b2SolverData.prototype,\"velocities\",box2d.b2SolverData.prototype.velocities);box2d.b2Collision={};box2d.b2ContactFeatureType={e_vertex:0,e_face:1};goog.exportSymbol(\"box2d.b2ContactFeatureType\",box2d.b2ContactFeatureType);goog.exportProperty(box2d.b2ContactFeatureType,\"e_vertex\",box2d.b2ContactFeatureType.e_vertex);goog.exportProperty(box2d.b2ContactFeatureType,\"e_face\",box2d.b2ContactFeatureType.e_face);box2d.b2ContactFeature=function(a){this._id=a};goog.exportSymbol(\"box2d.b2ContactFeature\",box2d.b2ContactFeature);box2d.b2ContactFeature.prototype._id=null;\ngoog.exportProperty(box2d.b2ContactFeature.prototype,\"_id\",box2d.b2ContactFeature.prototype._id);box2d.b2ContactFeature.prototype._indexA=0;goog.exportProperty(box2d.b2ContactFeature.prototype,\"_indexA\",box2d.b2ContactFeature.prototype._indexA);box2d.b2ContactFeature.prototype._indexB=0;goog.exportProperty(box2d.b2ContactFeature.prototype,\"_indexB\",box2d.b2ContactFeature.prototype._indexB);box2d.b2ContactFeature.prototype._typeA=0;goog.exportProperty(box2d.b2ContactFeature.prototype,\"_typeA\",box2d.b2ContactFeature.prototype._typeA);\nbox2d.b2ContactFeature.prototype._typeB=0;goog.exportProperty(box2d.b2ContactFeature.prototype,\"_typeB\",box2d.b2ContactFeature.prototype._typeB);Object.defineProperty(box2d.b2ContactFeature.prototype,\"indexA\",{enumerable:!1,configurable:!0,get:function(){return this._indexA},set:function(a){this._indexA=a;this._id._key=this._id._key&4294967040|this._indexA&255}});\nObject.defineProperty(box2d.b2ContactFeature.prototype,\"indexB\",{enumerable:!1,configurable:!0,get:function(){return this._indexB},set:function(a){this._indexB=a;this._id._key=this._id._key&4294902015|this._indexB<<8&65280}});Object.defineProperty(box2d.b2ContactFeature.prototype,\"typeA\",{enumerable:!1,configurable:!0,get:function(){return this._typeA},set:function(a){this._typeA=a;this._id._key=this._id._key&4278255615|this._typeA<<16&16711680}});\nObject.defineProperty(box2d.b2ContactFeature.prototype,\"typeB\",{enumerable:!1,configurable:!0,get:function(){return this._typeB},set:function(a){this._typeB=a;this._id._key=this._id._key&16777215|this._typeB<<24&4278190080}});box2d.b2ContactID=function(){this.cf=new box2d.b2ContactFeature(this)};goog.exportSymbol(\"box2d.b2ContactID\",box2d.b2ContactID);box2d.b2ContactID.prototype.cf=null;goog.exportProperty(box2d.b2ContactID.prototype,\"cf\",box2d.b2ContactID.prototype.cf);\nbox2d.b2ContactID.prototype.key=0;goog.exportProperty(box2d.b2ContactID.prototype,\"key\",box2d.b2ContactID.prototype.key);box2d.b2ContactID.prototype.Copy=function(a){this.key=a.key;return this};goog.exportProperty(box2d.b2ContactID.prototype,\"Copy\",box2d.b2ContactID.prototype.Copy);box2d.b2ContactID.prototype.Clone=function(){return(new box2d.b2ContactID).Copy(this)};goog.exportProperty(box2d.b2ContactID.prototype,\"Clone\",box2d.b2ContactID.prototype.Clone);\nObject.defineProperty(box2d.b2ContactID.prototype,\"key\",{enumerable:!1,configurable:!0,get:function(){return this._key},set:function(a){this._key=a;this.cf._indexA=this._key&255;this.cf._indexB=this._key>>8&255;this.cf._typeA=this._key>>16&255;this.cf._typeB=this._key>>24&255}});box2d.b2ManifoldPoint=function(){this.localPoint=new box2d.b2Vec2;this.id=new box2d.b2ContactID};goog.exportSymbol(\"box2d.b2ManifoldPoint\",box2d.b2ManifoldPoint);box2d.b2ManifoldPoint.prototype.localPoint=null;\ngoog.exportProperty(box2d.b2ManifoldPoint.prototype,\"localPoint\",box2d.b2ManifoldPoint.prototype.localPoint);box2d.b2ManifoldPoint.prototype.normalImpulse=0;goog.exportProperty(box2d.b2ManifoldPoint.prototype,\"normalImpulse\",box2d.b2ManifoldPoint.prototype.normalImpulse);box2d.b2ManifoldPoint.prototype.tangentImpulse=0;goog.exportProperty(box2d.b2ManifoldPoint.prototype,\"tangentImpulse\",box2d.b2ManifoldPoint.prototype.tangentImpulse);box2d.b2ManifoldPoint.prototype.id=null;\ngoog.exportProperty(box2d.b2ManifoldPoint.prototype,\"id\",box2d.b2ManifoldPoint.prototype.id);box2d.b2ManifoldPoint.MakeArray=function(a){return box2d.b2MakeArray(a,function(a){return new box2d.b2ManifoldPoint})};goog.exportProperty(box2d.b2ManifoldPoint,\"MakeArray\",box2d.b2ManifoldPoint.MakeArray);box2d.b2ManifoldPoint.prototype.Reset=function(){this.localPoint.SetZero();this.tangentImpulse=this.normalImpulse=0;this.id.key=0};goog.exportProperty(box2d.b2ManifoldPoint.prototype,\"Reset\",box2d.b2ManifoldPoint.prototype.Reset);\nbox2d.b2ManifoldPoint.prototype.Copy=function(a){this.localPoint.Copy(a.localPoint);this.normalImpulse=a.normalImpulse;this.tangentImpulse=a.tangentImpulse;this.id.Copy(a.id);return this};goog.exportProperty(box2d.b2ManifoldPoint.prototype,\"Copy\",box2d.b2ManifoldPoint.prototype.Copy);box2d.b2ManifoldType={e_unknown:-1,e_circles:0,e_faceA:1,e_faceB:2};goog.exportSymbol(\"box2d.b2ManifoldType\",box2d.b2ManifoldType);goog.exportProperty(box2d.b2ManifoldType,\"e_unknown\",box2d.b2ManifoldType.e_unknown);\ngoog.exportProperty(box2d.b2ManifoldType,\"e_circles\",box2d.b2ManifoldType.e_circles);goog.exportProperty(box2d.b2ManifoldType,\"e_faceA\",box2d.b2ManifoldType.e_faceA);goog.exportProperty(box2d.b2ManifoldType,\"e_faceB\",box2d.b2ManifoldType.e_faceB);box2d.b2Manifold=function(){this.points=box2d.b2ManifoldPoint.MakeArray(box2d.b2_maxManifoldPoints);this.localNormal=new box2d.b2Vec2;this.localPoint=new box2d.b2Vec2;this.type=box2d.b2ManifoldType.e_unknown;this.pointCount=0};\ngoog.exportSymbol(\"box2d.b2Manifold\",box2d.b2Manifold);box2d.b2Manifold.prototype.points=null;goog.exportProperty(box2d.b2Manifold.prototype,\"points\",box2d.b2Manifold.prototype.points);box2d.b2Manifold.prototype.localNormal=null;goog.exportProperty(box2d.b2Manifold.prototype,\"localNormal\",box2d.b2Manifold.prototype.localNormal);box2d.b2Manifold.prototype.localPoint=null;goog.exportProperty(box2d.b2Manifold.prototype,\"localPoint\",box2d.b2Manifold.prototype.localPoint);\nbox2d.b2Manifold.prototype.type=box2d.b2ManifoldType.e_unknown;goog.exportProperty(box2d.b2Manifold.prototype,\"type\",box2d.b2Manifold.prototype.type);box2d.b2Manifold.prototype.pointCount=0;goog.exportProperty(box2d.b2Manifold.prototype,\"pointCount\",box2d.b2Manifold.prototype.pointCount);\nbox2d.b2Manifold.prototype.Reset=function(){for(var a=0,b=box2d.b2_maxManifoldPoints;a<b;++a)this.points[a].Reset();this.localNormal.SetZero();this.localPoint.SetZero();this.type=box2d.b2ManifoldType.e_unknown;this.pointCount=0};goog.exportProperty(box2d.b2Manifold.prototype,\"Reset\",box2d.b2Manifold.prototype.Reset);\nbox2d.b2Manifold.prototype.Copy=function(a){this.pointCount=a.pointCount;for(var b=0,c=box2d.b2_maxManifoldPoints;b<c;++b)this.points[b].Copy(a.points[b]);this.localNormal.Copy(a.localNormal);this.localPoint.Copy(a.localPoint);this.type=a.type;return this};goog.exportProperty(box2d.b2Manifold.prototype,\"Copy\",box2d.b2Manifold.prototype.Copy);box2d.b2Manifold.prototype.Clone=function(){return(new box2d.b2Manifold).Copy(this)};goog.exportProperty(box2d.b2Manifold.prototype,\"Clone\",box2d.b2Manifold.prototype.Clone);\nbox2d.b2WorldManifold=function(){this.normal=new box2d.b2Vec2;this.points=box2d.b2Vec2.MakeArray(box2d.b2_maxManifoldPoints);this.separations=box2d.b2MakeNumberArray(box2d.b2_maxManifoldPoints)};goog.exportSymbol(\"box2d.b2WorldManifold\",box2d.b2WorldManifold);box2d.b2WorldManifold.prototype.normal=null;goog.exportProperty(box2d.b2WorldManifold.prototype,\"normal\",box2d.b2WorldManifold.prototype.normal);box2d.b2WorldManifold.prototype.points=null;\ngoog.exportProperty(box2d.b2WorldManifold.prototype,\"points\",box2d.b2WorldManifold.prototype.points);box2d.b2WorldManifold.prototype.separations=null;goog.exportProperty(box2d.b2WorldManifold.prototype,\"separations\",box2d.b2WorldManifold.prototype.separations);\nbox2d.b2WorldManifold.prototype.Initialize=function(a,b,c,e,d){if(0!==a.pointCount)switch(a.type){case box2d.b2ManifoldType.e_circles:this.normal.SetXY(1,0);b=box2d.b2MulXV(b,a.localPoint,box2d.b2WorldManifold.prototype.Initialize.s_pointA);a=box2d.b2MulXV(e,a.points[0].localPoint,box2d.b2WorldManifold.prototype.Initialize.s_pointB);box2d.b2DistanceSquaredVV(b,a)>box2d.b2_epsilon_sq&&box2d.b2SubVV(a,b,this.normal).SelfNormalize();var f=box2d.b2AddVMulSV(b,c,this.normal,box2d.b2WorldManifold.prototype.Initialize.s_cA),\ng=box2d.b2SubVMulSV(a,d,this.normal,box2d.b2WorldManifold.prototype.Initialize.s_cB);box2d.b2MidVV(f,g,this.points[0]);this.separations[0]=box2d.b2DotVV(box2d.b2SubVV(g,f,box2d.b2Vec2.s_t0),this.normal);break;case box2d.b2ManifoldType.e_faceA:box2d.b2MulRV(b.q,a.localNormal,this.normal);for(var h=box2d.b2MulXV(b,a.localPoint,box2d.b2WorldManifold.prototype.Initialize.s_planePoint),l=0,k=a.pointCount;l<k;++l){var m=box2d.b2MulXV(e,a.points[l].localPoint,box2d.b2WorldManifold.prototype.Initialize.s_clipPoint),\nf=c-box2d.b2DotVV(box2d.b2SubVV(m,h,box2d.b2Vec2.s_t0),this.normal),f=box2d.b2AddVMulSV(m,f,this.normal,box2d.b2WorldManifold.prototype.Initialize.s_cA),g=box2d.b2SubVMulSV(m,d,this.normal,box2d.b2WorldManifold.prototype.Initialize.s_cB);box2d.b2MidVV(f,g,this.points[l]);this.separations[l]=box2d.b2DotVV(box2d.b2SubVV(g,f,box2d.b2Vec2.s_t0),this.normal)}break;case box2d.b2ManifoldType.e_faceB:box2d.b2MulRV(e.q,a.localNormal,this.normal);h=box2d.b2MulXV(e,a.localPoint,box2d.b2WorldManifold.prototype.Initialize.s_planePoint);\nl=0;for(k=a.pointCount;l<k;++l)m=box2d.b2MulXV(b,a.points[l].localPoint,box2d.b2WorldManifold.prototype.Initialize.s_clipPoint),f=d-box2d.b2DotVV(box2d.b2SubVV(m,h,box2d.b2Vec2.s_t0),this.normal),g=box2d.b2AddVMulSV(m,f,this.normal,box2d.b2WorldManifold.prototype.Initialize.s_cB),f=box2d.b2SubVMulSV(m,c,this.normal,box2d.b2WorldManifold.prototype.Initialize.s_cA),box2d.b2MidVV(f,g,this.points[l]),this.separations[l]=box2d.b2DotVV(box2d.b2SubVV(f,g,box2d.b2Vec2.s_t0),this.normal);this.normal.SelfNeg()}};\ngoog.exportProperty(box2d.b2WorldManifold.prototype,\"Initialize\",box2d.b2WorldManifold.prototype.Initialize);box2d.b2WorldManifold.prototype.Initialize.s_pointA=new box2d.b2Vec2;box2d.b2WorldManifold.prototype.Initialize.s_pointB=new box2d.b2Vec2;box2d.b2WorldManifold.prototype.Initialize.s_cA=new box2d.b2Vec2;box2d.b2WorldManifold.prototype.Initialize.s_cB=new box2d.b2Vec2;box2d.b2WorldManifold.prototype.Initialize.s_planePoint=new box2d.b2Vec2;\nbox2d.b2WorldManifold.prototype.Initialize.s_clipPoint=new box2d.b2Vec2;box2d.b2PointState={b2_nullState:0,b2_addState:1,b2_persistState:2,b2_removeState:3};goog.exportSymbol(\"box2d.b2PointState\",box2d.b2PointState);goog.exportProperty(box2d.b2PointState,\"b2_nullState   \",box2d.b2PointState.b2_nullState);goog.exportProperty(box2d.b2PointState,\"b2_addState    \",box2d.b2PointState.b2_addState);goog.exportProperty(box2d.b2PointState,\"b2_persistState\",box2d.b2PointState.b2_persistState);\ngoog.exportProperty(box2d.b2PointState,\"b2_removeState \",box2d.b2PointState.b2_removeState);\nbox2d.b2GetPointStates=function(a,b,c,e){for(var d=0,f=c.pointCount;d<f;++d){var g=c.points[d].id,g=g.key;a[d]=box2d.b2PointState.b2_removeState;for(var h=0,l=e.pointCount;h<l;++h)if(e.points[h].id.key===g){a[d]=box2d.b2PointState.b2_persistState;break}}for(f=box2d.b2_maxManifoldPoints;d<f;++d)a[d]=box2d.b2PointState.b2_nullState;d=0;for(f=e.pointCount;d<f;++d)for(g=e.points[d].id,g=g.key,b[d]=box2d.b2PointState.b2_addState,h=0,l=c.pointCount;h<l;++h)if(c.points[h].id.key===g){b[d]=box2d.b2PointState.b2_persistState;\nbreak}for(f=box2d.b2_maxManifoldPoints;d<f;++d)b[d]=box2d.b2PointState.b2_nullState};goog.exportSymbol(\"box2d.b2GetPointStates\",box2d.b2GetPointStates);box2d.b2ClipVertex=function(){this.v=new box2d.b2Vec2;this.id=new box2d.b2ContactID};goog.exportSymbol(\"box2d.b2ClipVertex\",box2d.b2ClipVertex);box2d.b2ClipVertex.prototype.v=null;goog.exportProperty(box2d.b2ClipVertex.prototype,\"v\",box2d.b2ClipVertex.prototype.v);box2d.b2ClipVertex.prototype.id=null;\ngoog.exportProperty(box2d.b2ClipVertex.prototype,\"id\",box2d.b2ClipVertex.prototype.id);box2d.b2ClipVertex.MakeArray=function(a){return box2d.b2MakeArray(a,function(a){return new box2d.b2ClipVertex})};goog.exportProperty(box2d.b2ClipVertex,\"MakeArray\",box2d.b2ClipVertex.MakeArray);box2d.b2ClipVertex.prototype.Copy=function(a){this.v.Copy(a.v);this.id.Copy(a.id);return this};goog.exportProperty(box2d.b2ClipVertex.prototype,\"Copy\",box2d.b2ClipVertex.prototype.Copy);\nbox2d.b2RayCastInput=function(){this.p1=new box2d.b2Vec2;this.p2=new box2d.b2Vec2;this.maxFraction=1};goog.exportSymbol(\"box2d.b2RayCastInput\",box2d.b2RayCastInput);box2d.b2RayCastInput.prototype.p1=null;goog.exportProperty(box2d.b2RayCastInput.prototype,\"p1\",box2d.b2RayCastInput.prototype.p1);box2d.b2RayCastInput.prototype.p2=null;goog.exportProperty(box2d.b2RayCastInput.prototype,\"p2\",box2d.b2RayCastInput.prototype.p2);box2d.b2RayCastInput.prototype.maxFraction=1;\ngoog.exportProperty(box2d.b2RayCastInput.prototype,\"maxFraction\",box2d.b2RayCastInput.prototype.maxFraction);box2d.b2RayCastInput.prototype.Copy=function(a){this.p1.Copy(a.p1);this.p2.Copy(a.p2);this.maxFraction=a.maxFraction;return this};goog.exportProperty(box2d.b2RayCastInput.prototype,\"Copy\",box2d.b2RayCastInput.prototype.Copy);box2d.b2RayCastOutput=function(){this.normal=new box2d.b2Vec2;this.fraction=0};goog.exportSymbol(\"box2d.b2RayCastOutput\",box2d.b2RayCastOutput);\nbox2d.b2RayCastOutput.prototype.normal=null;goog.exportProperty(box2d.b2RayCastOutput.prototype,\"normal\",box2d.b2RayCastOutput.prototype.normal);box2d.b2RayCastOutput.prototype.fraction=0;goog.exportProperty(box2d.b2RayCastOutput.prototype,\"fraction\",box2d.b2RayCastOutput.prototype.fraction);box2d.b2RayCastOutput.prototype.Copy=function(a){this.normal.Copy(a.normal);this.fraction=a.fraction;return this};goog.exportProperty(box2d.b2RayCastOutput.prototype,\"Copy\",box2d.b2RayCastOutput.prototype.Copy);\nbox2d.b2AABB=function(){this.lowerBound=new box2d.b2Vec2;this.upperBound=new box2d.b2Vec2;this.m_out_center=new box2d.b2Vec2;this.m_out_extent=new box2d.b2Vec2};goog.exportSymbol(\"box2d.b2AABB\",box2d.b2AABB);box2d.b2AABB.prototype.lowerBound=null;goog.exportProperty(box2d.b2AABB.prototype,\"lowerBound\",box2d.b2AABB.prototype.lowerBound);box2d.b2AABB.prototype.upperBound=null;goog.exportProperty(box2d.b2AABB.prototype,\"upperBound\",box2d.b2AABB.prototype.upperBound);\nbox2d.b2AABB.prototype.m_out_center=null;goog.exportProperty(box2d.b2AABB.prototype,\"m_out_center\",box2d.b2AABB.prototype.m_out_center);box2d.b2AABB.prototype.m_out_extent=null;goog.exportProperty(box2d.b2AABB.prototype,\"m_out_extent\",box2d.b2AABB.prototype.m_out_extent);box2d.b2AABB.prototype.Copy=function(a){this.lowerBound.Copy(a.lowerBound);this.upperBound.Copy(a.upperBound);return this};goog.exportProperty(box2d.b2AABB.prototype,\"Copy\",box2d.b2AABB.prototype.Copy);\nbox2d.b2AABB.prototype.IsValid=function(){var a=this.upperBound.y-this.lowerBound.y;return a=(a=0<=this.upperBound.x-this.lowerBound.x&&0<=a)&&this.lowerBound.IsValid()&&this.upperBound.IsValid()};goog.exportProperty(box2d.b2AABB.prototype,\"IsValid\",box2d.b2AABB.prototype.IsValid);box2d.b2AABB.prototype.GetCenter=function(){return box2d.b2MidVV(this.lowerBound,this.upperBound,this.m_out_center)};goog.exportProperty(box2d.b2AABB.prototype,\"GetCenter\",box2d.b2AABB.prototype.GetCenter);\nbox2d.b2AABB.prototype.GetExtents=function(){return box2d.b2ExtVV(this.lowerBound,this.upperBound,this.m_out_extent)};goog.exportProperty(box2d.b2AABB.prototype,\"GetExtents\",box2d.b2AABB.prototype.GetExtents);box2d.b2AABB.prototype.GetPerimeter=function(){return 2*(this.upperBound.x-this.lowerBound.x+(this.upperBound.y-this.lowerBound.y))};goog.exportProperty(box2d.b2AABB.prototype,\"GetPerimeter\",box2d.b2AABB.prototype.GetPerimeter);\nbox2d.b2AABB.prototype.Combine1=function(a){this.lowerBound.x=box2d.b2Min(this.lowerBound.x,a.lowerBound.x);this.lowerBound.y=box2d.b2Min(this.lowerBound.y,a.lowerBound.y);this.upperBound.x=box2d.b2Max(this.upperBound.x,a.upperBound.x);this.upperBound.y=box2d.b2Max(this.upperBound.y,a.upperBound.y);return this};goog.exportProperty(box2d.b2AABB.prototype,\"Combine1\",box2d.b2AABB.prototype.Combine1);\nbox2d.b2AABB.prototype.Combine2=function(a,b){this.lowerBound.x=box2d.b2Min(a.lowerBound.x,b.lowerBound.x);this.lowerBound.y=box2d.b2Min(a.lowerBound.y,b.lowerBound.y);this.upperBound.x=box2d.b2Max(a.upperBound.x,b.upperBound.x);this.upperBound.y=box2d.b2Max(a.upperBound.y,b.upperBound.y);return this};goog.exportProperty(box2d.b2AABB.prototype,\"Combine2\",box2d.b2AABB.prototype.Combine2);box2d.b2AABB.Combine=function(a,b,c){c.Combine2(a,b);return c};goog.exportProperty(box2d.b2AABB,\"Combine\",box2d.b2AABB.Combine);\nbox2d.b2AABB.prototype.Contains=function(a){var b;return b=(b=(b=(b=this.lowerBound.x<=a.lowerBound.x)&&this.lowerBound.y<=a.lowerBound.y)&&a.upperBound.x<=this.upperBound.x)&&a.upperBound.y<=this.upperBound.y};goog.exportProperty(box2d.b2AABB.prototype,\"Contains\",box2d.b2AABB.prototype.Contains);\nbox2d.b2AABB.prototype.RayCast=function(a,b){var c=-box2d.b2_maxFloat,e=box2d.b2_maxFloat,d=b.p1.x,f=b.p1.y,g=b.p2.x-b.p1.x,h=b.p2.y-b.p1.y,l=box2d.b2Abs(g),k=box2d.b2Abs(h),m=a.normal;if(l<box2d.b2_epsilon){if(d<this.lowerBound.x||this.upperBound.x<d)return!1}else if(l=1/g,g=(this.lowerBound.x-d)*l,d=(this.upperBound.x-d)*l,l=-1,g>d&&(l=g,g=d,d=l,l=1),g>c&&(m.x=l,m.y=0,c=g),e=box2d.b2Min(e,d),c>e)return!1;if(k<box2d.b2_epsilon){if(f<this.lowerBound.y||this.upperBound.y<f)return!1}else if(l=1/h,g=\n(this.lowerBound.y-f)*l,d=(this.upperBound.y-f)*l,l=-1,g>d&&(l=g,g=d,d=l,l=1),g>c&&(m.x=0,m.y=l,c=g),e=box2d.b2Min(e,d),c>e)return!1;if(0>c||b.maxFraction<c)return!1;a.fraction=c;return!0};goog.exportProperty(box2d.b2AABB.prototype,\"RayCast\",box2d.b2AABB.prototype.RayCast);box2d.b2AABB.prototype.TestOverlap=function(a){var b=a.lowerBound.y-this.upperBound.y,c=this.lowerBound.y-a.upperBound.y;return 0<a.lowerBound.x-this.upperBound.x||0<b||0<this.lowerBound.x-a.upperBound.x||0<c?!1:!0};\ngoog.exportProperty(box2d.b2AABB.prototype,\"TestOverlap\",box2d.b2AABB.prototype.TestOverlap);box2d.b2TestOverlapAABB=function(a,b){var c=b.lowerBound.y-a.upperBound.y,e=a.lowerBound.y-b.upperBound.y;return 0<b.lowerBound.x-a.upperBound.x||0<c||0<a.lowerBound.x-b.upperBound.x||0<e?!1:!0};goog.exportSymbol(\"box2d.b2TestOverlapAABB\",box2d.b2TestOverlapAABB);\nbox2d.b2ClipSegmentToLine=function(a,b,c,e,d){var f=0,g=b[0];b=b[1];var h=box2d.b2DotVV(c,g.v)-e;c=box2d.b2DotVV(c,b.v)-e;0>=h&&a[f++].Copy(g);0>=c&&a[f++].Copy(b);0>h*c&&(c=h/(h-c),e=a[f].v,e.x=g.v.x+c*(b.v.x-g.v.x),e.y=g.v.y+c*(b.v.y-g.v.y),a=a[f].id,a.cf.indexA=d,a.cf.indexB=g.id.cf.indexB,a.cf.typeA=box2d.b2ContactFeatureType.e_vertex,a.cf.typeB=box2d.b2ContactFeatureType.e_face,++f);return f};goog.exportSymbol(\"box2d.b2ClipSegmentToLine\",box2d.b2ClipSegmentToLine);\nbox2d.b2TestOverlapShape=function(a,b,c,e,d,f){var g=box2d.b2TestOverlapShape.s_input.Reset();g.proxyA.SetShape(a,b);g.proxyB.SetShape(c,e);g.transformA.Copy(d);g.transformB.Copy(f);g.useRadii=!0;a=box2d.b2TestOverlapShape.s_simplexCache.Reset();a.count=0;b=box2d.b2TestOverlapShape.s_output.Reset();box2d.b2Distance(b,a,g);return b.distance<10*box2d.b2_epsilon};goog.exportSymbol(\"box2d.b2TestOverlapShape\",box2d.b2TestOverlapShape);box2d.b2TestOverlapShape.s_input=new box2d.b2DistanceInput;\nbox2d.b2TestOverlapShape.s_simplexCache=new box2d.b2SimplexCache;box2d.b2TestOverlapShape.s_output=new box2d.b2DistanceOutput;box2d.b2Timer=function(){this.m_start=(new Date).getTime()};goog.exportSymbol(\"box2d.b2Timer\",box2d.b2Timer);box2d.b2Timer.prototype.m_start=0;goog.exportProperty(box2d.b2Timer.prototype,\"m_start\",box2d.b2Timer.prototype.m_start);box2d.b2Timer.prototype.Reset=function(){this.m_start=(new Date).getTime();return this};goog.exportProperty(box2d.b2Timer.prototype,\"Reset\",box2d.b2Timer.prototype.Reset);box2d.b2Timer.prototype.GetMilliseconds=function(){return(new Date).getTime()-this.m_start};\ngoog.exportProperty(box2d.b2Timer.prototype,\"GetMilliseconds\",box2d.b2Timer.prototype.GetMilliseconds);box2d.b2Counter=function(){};goog.exportSymbol(\"box2d.b2Counter\",box2d.b2Counter);box2d.b2Counter.prototype.m_count=0;goog.exportProperty(box2d.b2Counter.prototype,\"m_count\",box2d.b2Counter.prototype.m_count);box2d.b2Counter.prototype.m_min_count=0;goog.exportProperty(box2d.b2Counter.prototype,\"m_min_count\",box2d.b2Counter.prototype.m_min_count);box2d.b2Counter.prototype.m_max_count=0;\ngoog.exportProperty(box2d.b2Counter.prototype,\"m_max_count\",box2d.b2Counter.prototype.m_max_count);box2d.b2Counter.prototype.GetCount=function(){return this.m_count};goog.exportProperty(box2d.b2Counter.prototype,\"GetCount\",box2d.b2Counter.prototype.GetCount);box2d.b2Counter.prototype.GetMinCount=function(){return this.m_min_count};goog.exportProperty(box2d.b2Counter.prototype,\"GetMinCount\",box2d.b2Counter.prototype.GetMinCount);box2d.b2Counter.prototype.GetMaxCount=function(){return this.m_max_count};\ngoog.exportProperty(box2d.b2Counter.prototype,\"GetMaxCount\",box2d.b2Counter.prototype.GetMaxCount);box2d.b2Counter.prototype.ResetCount=function(){var a=this.m_count;this.m_count=0;return a};goog.exportProperty(box2d.b2Counter.prototype,\"ResetCount\",box2d.b2Counter.prototype.ResetCount);box2d.b2Counter.prototype.ResetMinCount=function(){this.m_min_count=0};goog.exportProperty(box2d.b2Counter.prototype,\"ResetMinCount\",box2d.b2Counter.prototype.ResetMinCount);\nbox2d.b2Counter.prototype.ResetMaxCount=function(){this.m_max_count=0};goog.exportProperty(box2d.b2Counter.prototype,\"ResetMaxCount\",box2d.b2Counter.prototype.ResetMaxCount);box2d.b2Counter.prototype.Increment=function(){this.m_count++;this.m_max_count<this.m_count&&(this.m_max_count=this.m_count)};goog.exportProperty(box2d.b2Counter.prototype,\"Increment\",box2d.b2Counter.prototype.Increment);\nbox2d.b2Counter.prototype.Decrement=function(){this.m_count--;this.m_min_count>this.m_count&&(this.m_min_count=this.m_count)};goog.exportProperty(box2d.b2Counter.prototype,\"Decrement\",box2d.b2Counter.prototype.Decrement);box2d.b2_toiTime=0;goog.exportSymbol(\"box2d.b2_toiTime\",box2d.b2_toiTime);box2d.b2_toiMaxTime=0;goog.exportSymbol(\"box2d.b2_toiMaxTime\",box2d.b2_toiMaxTime);box2d.b2_toiCalls=0;goog.exportSymbol(\"box2d.b2_toiCalls\",box2d.b2_toiCalls);box2d.b2_toiIters=0;goog.exportSymbol(\"box2d.b2_toiIters\",box2d.b2_toiIters);box2d.b2_toiMaxIters=0;goog.exportSymbol(\"box2d.b2_toiMaxIters\",box2d.b2_toiMaxIters);box2d.b2_toiRootIters=0;goog.exportSymbol(\"box2d.b2_toiRootIters\",box2d.b2_toiRootIters);\nbox2d.b2_toiMaxRootIters=0;goog.exportSymbol(\"box2d.b2_toiMaxRootIters\",box2d.b2_toiMaxRootIters);box2d.b2TOIInput=function(){this.proxyA=new box2d.b2DistanceProxy;this.proxyB=new box2d.b2DistanceProxy;this.sweepA=new box2d.b2Sweep;this.sweepB=new box2d.b2Sweep};goog.exportSymbol(\"box2d.b2TOIInput\",box2d.b2TOIInput);box2d.b2TOIInput.prototype.proxyA=null;goog.exportProperty(box2d.b2TOIInput.prototype,\"proxyA\",box2d.b2TOIInput.prototype.proxyA);box2d.b2TOIInput.prototype.proxyB=null;\ngoog.exportProperty(box2d.b2TOIInput.prototype,\"proxyB\",box2d.b2TOIInput.prototype.proxyB);box2d.b2TOIInput.prototype.sweepA=null;goog.exportProperty(box2d.b2TOIInput.prototype,\"sweepA\",box2d.b2TOIInput.prototype.sweepA);box2d.b2TOIInput.prototype.sweepB=null;goog.exportProperty(box2d.b2TOIInput.prototype,\"sweepB\",box2d.b2TOIInput.prototype.sweepB);box2d.b2TOIInput.prototype.tMax=0;goog.exportProperty(box2d.b2TOIInput.prototype,\"tMax\",box2d.b2TOIInput.prototype.tMax);\nbox2d.b2TOIOutputState={e_unknown:0,e_failed:1,e_overlapped:2,e_touching:3,e_separated:4};goog.exportSymbol(\"box2d.b2TOIOutputState\",box2d.b2TOIOutputState);goog.exportProperty(box2d.b2TOIOutputState,\"e_unknown\",box2d.b2TOIOutputState.e_unknown);goog.exportProperty(box2d.b2TOIOutputState,\"e_failed\",box2d.b2TOIOutputState.e_failed);goog.exportProperty(box2d.b2TOIOutputState,\"e_overlapped\",box2d.b2TOIOutputState.e_overlapped);goog.exportProperty(box2d.b2TOIOutputState,\"e_touching\",box2d.b2TOIOutputState.e_touching);\ngoog.exportProperty(box2d.b2TOIOutputState,\"e_separated\",box2d.b2TOIOutputState.e_separated);box2d.b2TOIOutput=function(){};goog.exportSymbol(\"box2d.b2TOIOutput\",box2d.b2TOIOutput);box2d.b2TOIOutput.prototype.state=box2d.b2TOIOutputState.e_unknown;goog.exportProperty(box2d.b2TOIOutput.prototype,\"state\",box2d.b2TOIOutput.prototype.state);box2d.b2TOIOutput.prototype.t=0;goog.exportProperty(box2d.b2TOIOutput.prototype,\"t\",box2d.b2TOIOutput.prototype.t);\nbox2d.b2SeparationFunctionType={e_unknown:-1,e_points:0,e_faceA:1,e_faceB:2};goog.exportSymbol(\"box2d.b2SeparationFunctionType\",box2d.b2SeparationFunctionType);goog.exportProperty(box2d.b2SeparationFunctionType,\"e_unknown\",box2d.b2SeparationFunctionType.e_unknown);goog.exportProperty(box2d.b2SeparationFunctionType,\"e_points\",box2d.b2SeparationFunctionType.e_points);goog.exportProperty(box2d.b2SeparationFunctionType,\"e_faceA\",box2d.b2SeparationFunctionType.e_faceA);\ngoog.exportProperty(box2d.b2SeparationFunctionType,\"e_faceB\",box2d.b2SeparationFunctionType.e_faceB);box2d.b2SeparationFunction=function(){this.m_sweepA=new box2d.b2Sweep;this.m_sweepB=new box2d.b2Sweep;this.m_localPoint=new box2d.b2Vec2;this.m_axis=new box2d.b2Vec2};goog.exportSymbol(\"box2d.b2SeparationFunction\",box2d.b2SeparationFunction);box2d.b2SeparationFunction.prototype.m_proxyA=null;goog.exportProperty(box2d.b2SeparationFunction.prototype,\"m_proxyA\",box2d.b2SeparationFunction.prototype.m_proxyA);\nbox2d.b2SeparationFunction.prototype.m_proxyB=null;goog.exportProperty(box2d.b2SeparationFunction.prototype,\"m_proxyB\",box2d.b2SeparationFunction.prototype.m_proxyB);box2d.b2SeparationFunction.prototype.m_sweepA=null;goog.exportProperty(box2d.b2SeparationFunction.prototype,\"m_sweepA\",box2d.b2SeparationFunction.prototype.m_sweepA);box2d.b2SeparationFunction.prototype.m_sweepB=null;goog.exportProperty(box2d.b2SeparationFunction.prototype,\"m_sweepB\",box2d.b2SeparationFunction.prototype.m_sweepB);\nbox2d.b2SeparationFunction.prototype.m_type=box2d.b2SeparationFunctionType.e_unknown;goog.exportProperty(box2d.b2SeparationFunction.prototype,\"m_type\",box2d.b2SeparationFunction.prototype.m_type);box2d.b2SeparationFunction.prototype.m_localPoint=null;goog.exportProperty(box2d.b2SeparationFunction.prototype,\"m_localPoint\",box2d.b2SeparationFunction.prototype.m_localPoint);box2d.b2SeparationFunction.prototype.m_axis=null;goog.exportProperty(box2d.b2SeparationFunction.prototype,\"m_axis\",box2d.b2SeparationFunction.prototype.m_axis);\nbox2d.b2SeparationFunction.prototype.Initialize=function(a,b,c,e,d,f){this.m_proxyA=b;this.m_proxyB=e;b=a.count;box2d.ENABLE_ASSERTS&&box2d.b2Assert(0<b&&3>b);this.m_sweepA.Copy(c);this.m_sweepB.Copy(d);c=box2d.b2TimeOfImpact.s_xfA;d=box2d.b2TimeOfImpact.s_xfB;this.m_sweepA.GetTransform(c,f);this.m_sweepB.GetTransform(d,f);1===b?(this.m_type=box2d.b2SeparationFunctionType.e_points,b=this.m_proxyA.GetVertex(a.indexA[0]),a=this.m_proxyB.GetVertex(a.indexB[0]),c=box2d.b2MulXV(c,b,box2d.b2TimeOfImpact.s_pointA),\nd=box2d.b2MulXV(d,a,box2d.b2TimeOfImpact.s_pointB),box2d.b2SubVV(d,c,this.m_axis),a=this.m_axis.Normalize()):(a.indexA[0]===a.indexA[1]?(this.m_type=box2d.b2SeparationFunctionType.e_faceB,b=this.m_proxyB.GetVertex(a.indexB[0]),e=this.m_proxyB.GetVertex(a.indexB[1]),box2d.b2CrossVOne(box2d.b2SubVV(e,b,box2d.b2Vec2.s_t0),this.m_axis).SelfNormalize(),f=box2d.b2MulRV(d.q,this.m_axis,box2d.b2TimeOfImpact.s_normal),box2d.b2MidVV(b,e,this.m_localPoint),d=box2d.b2MulXV(d,this.m_localPoint,box2d.b2TimeOfImpact.s_pointB),\nb=this.m_proxyA.GetVertex(a.indexA[0]),c=box2d.b2MulXV(c,b,box2d.b2TimeOfImpact.s_pointA),a=box2d.b2DotVV(box2d.b2SubVV(c,d,box2d.b2Vec2.s_t0),f)):(this.m_type=box2d.b2SeparationFunctionType.e_faceA,b=this.m_proxyA.GetVertex(a.indexA[0]),e=this.m_proxyA.GetVertex(a.indexA[1]),box2d.b2CrossVOne(box2d.b2SubVV(e,b,box2d.b2Vec2.s_t0),this.m_axis).SelfNormalize(),f=box2d.b2MulRV(c.q,this.m_axis,box2d.b2TimeOfImpact.s_normal),box2d.b2MidVV(b,e,this.m_localPoint),c=box2d.b2MulXV(c,this.m_localPoint,box2d.b2TimeOfImpact.s_pointA),\na=this.m_proxyB.GetVertex(a.indexB[0]),d=box2d.b2MulXV(d,a,box2d.b2TimeOfImpact.s_pointB),a=box2d.b2DotVV(box2d.b2SubVV(d,c,box2d.b2Vec2.s_t0),f)),0>a&&(this.m_axis.SelfNeg(),a=-a));return a};goog.exportProperty(box2d.b2SeparationFunction.prototype,\"Initialize\",box2d.b2SeparationFunction.prototype.Initialize);\nbox2d.b2SeparationFunction.prototype.FindMinSeparation=function(a,b,c){var e=box2d.b2TimeOfImpact.s_xfA,d=box2d.b2TimeOfImpact.s_xfB;this.m_sweepA.GetTransform(e,c);this.m_sweepB.GetTransform(d,c);switch(this.m_type){case box2d.b2SeparationFunctionType.e_points:var f=box2d.b2MulTRV(e.q,this.m_axis,box2d.b2TimeOfImpact.s_axisA),g=box2d.b2MulTRV(d.q,box2d.b2NegV(this.m_axis,box2d.b2Vec2.s_t0),box2d.b2TimeOfImpact.s_axisB);a[0]=this.m_proxyA.GetSupport(f);b[0]=this.m_proxyB.GetSupport(g);a=this.m_proxyA.GetVertex(a[0]);\nb=this.m_proxyB.GetVertex(b[0]);e=box2d.b2MulXV(e,a,box2d.b2TimeOfImpact.s_pointA);d=box2d.b2MulXV(d,b,box2d.b2TimeOfImpact.s_pointB);return b=box2d.b2DotVV(box2d.b2SubVV(d,e,box2d.b2Vec2.s_t0),this.m_axis);case box2d.b2SeparationFunctionType.e_faceA:return c=box2d.b2MulRV(e.q,this.m_axis,box2d.b2TimeOfImpact.s_normal),e=box2d.b2MulXV(e,this.m_localPoint,box2d.b2TimeOfImpact.s_pointA),g=box2d.b2MulTRV(d.q,box2d.b2NegV(c,box2d.b2Vec2.s_t0),box2d.b2TimeOfImpact.s_axisB),a[0]=-1,b[0]=this.m_proxyB.GetSupport(g),\nb=this.m_proxyB.GetVertex(b[0]),d=box2d.b2MulXV(d,b,box2d.b2TimeOfImpact.s_pointB),b=box2d.b2DotVV(box2d.b2SubVV(d,e,box2d.b2Vec2.s_t0),c);case box2d.b2SeparationFunctionType.e_faceB:return c=box2d.b2MulRV(d.q,this.m_axis,box2d.b2TimeOfImpact.s_normal),d=box2d.b2MulXV(d,this.m_localPoint,box2d.b2TimeOfImpact.s_pointB),f=box2d.b2MulTRV(e.q,box2d.b2NegV(c,box2d.b2Vec2.s_t0),box2d.b2TimeOfImpact.s_axisA),b[0]=-1,a[0]=this.m_proxyA.GetSupport(f),a=this.m_proxyA.GetVertex(a[0]),e=box2d.b2MulXV(e,a,box2d.b2TimeOfImpact.s_pointA),\nb=box2d.b2DotVV(box2d.b2SubVV(e,d,box2d.b2Vec2.s_t0),c);default:return box2d.ENABLE_ASSERTS&&box2d.b2Assert(!1),a[0]=-1,b[0]=-1,0}};goog.exportProperty(box2d.b2SeparationFunction.prototype,\"FindMinSeparation\",box2d.b2SeparationFunction.prototype.FindMinSeparation);\nbox2d.b2SeparationFunction.prototype.Evaluate=function(a,b,c){var e=box2d.b2TimeOfImpact.s_xfA,d=box2d.b2TimeOfImpact.s_xfB;this.m_sweepA.GetTransform(e,c);this.m_sweepB.GetTransform(d,c);switch(this.m_type){case box2d.b2SeparationFunctionType.e_points:return a=this.m_proxyA.GetVertex(a),b=this.m_proxyB.GetVertex(b),e=box2d.b2MulXV(e,a,box2d.b2TimeOfImpact.s_pointA),d=box2d.b2MulXV(d,b,box2d.b2TimeOfImpact.s_pointB),e=box2d.b2DotVV(box2d.b2SubVV(d,e,box2d.b2Vec2.s_t0),this.m_axis);case box2d.b2SeparationFunctionType.e_faceA:return c=\nbox2d.b2MulRV(e.q,this.m_axis,box2d.b2TimeOfImpact.s_normal),e=box2d.b2MulXV(e,this.m_localPoint,box2d.b2TimeOfImpact.s_pointA),b=this.m_proxyB.GetVertex(b),d=box2d.b2MulXV(d,b,box2d.b2TimeOfImpact.s_pointB),e=box2d.b2DotVV(box2d.b2SubVV(d,e,box2d.b2Vec2.s_t0),c);case box2d.b2SeparationFunctionType.e_faceB:return c=box2d.b2MulRV(d.q,this.m_axis,box2d.b2TimeOfImpact.s_normal),d=box2d.b2MulXV(d,this.m_localPoint,box2d.b2TimeOfImpact.s_pointB),a=this.m_proxyA.GetVertex(a),e=box2d.b2MulXV(e,a,box2d.b2TimeOfImpact.s_pointA),\ne=box2d.b2DotVV(box2d.b2SubVV(e,d,box2d.b2Vec2.s_t0),c);default:return box2d.ENABLE_ASSERTS&&box2d.b2Assert(!1),0}};goog.exportProperty(box2d.b2SeparationFunction.prototype,\"Evaluate\",box2d.b2SeparationFunction.prototype.Evaluate);\nbox2d.b2TimeOfImpact=function(a,b){var c=box2d.b2TimeOfImpact.s_timer.Reset();++box2d.b2_toiCalls;a.state=box2d.b2TOIOutputState.e_unknown;a.t=b.tMax;var e=b.proxyA,d=b.proxyB,f=box2d.b2TimeOfImpact.s_sweepA.Copy(b.sweepA),g=box2d.b2TimeOfImpact.s_sweepB.Copy(b.sweepB);f.Normalize();g.Normalize();var h=b.tMax,l=box2d.b2Max(box2d.b2_linearSlop,e.m_radius+d.m_radius-3*box2d.b2_linearSlop),k=0.25*box2d.b2_linearSlop;box2d.ENABLE_ASSERTS&&box2d.b2Assert(l>k);var m=0,n=0,p=box2d.b2TimeOfImpact.s_cache;\np.count=0;var q=box2d.b2TimeOfImpact.s_distanceInput;q.proxyA=b.proxyA;q.proxyB=b.proxyB;for(q.useRadii=!1;;){var r=box2d.b2TimeOfImpact.s_xfA,t=box2d.b2TimeOfImpact.s_xfB;f.GetTransform(r,m);g.GetTransform(t,m);q.transformA.Copy(r);q.transformB.Copy(t);r=box2d.b2TimeOfImpact.s_distanceOutput;box2d.b2Distance(r,p,q);if(0>=r.distance){a.state=box2d.b2TOIOutputState.e_overlapped;a.t=0;break}if(r.distance<l+k){a.state=box2d.b2TOIOutputState.e_touching;a.t=m;break}r=box2d.b2TimeOfImpact.s_fcn;r.Initialize(p,\ne,f,d,g,m);for(var t=!1,s=h,u=0;;){var v=box2d.b2TimeOfImpact.s_indexA,y=box2d.b2TimeOfImpact.s_indexB,D=r.FindMinSeparation(v,y,s);if(D>l+k){a.state=box2d.b2TOIOutputState.e_separated;a.t=h;t=!0;break}if(D>l-k){m=s;break}var x=r.Evaluate(v[0],y[0],m);if(x<l-k){a.state=box2d.b2TOIOutputState.e_failed;a.t=m;t=!0;break}if(x<=l+k){a.state=box2d.b2TOIOutputState.e_touching;a.t=m;t=!0;break}for(var w=0,C=m,A=s;;){var E=0,E=w&1?C+(l-x)*(A-C)/(D-x):0.5*(C+A);++w;++box2d.b2_toiRootIters;var B=r.Evaluate(v[0],\ny[0],E);if(box2d.b2Abs(B-l)<k){s=E;break}B>l?(C=E,x=B):(A=E,D=B);if(50===w)break}box2d.b2_toiMaxRootIters=box2d.b2Max(box2d.b2_toiMaxRootIters,w);++u;if(u===box2d.b2_maxPolygonVertices)break}++n;++box2d.b2_toiIters;if(t)break;if(20===n){a.state=box2d.b2TOIOutputState.e_failed;a.t=m;break}}box2d.b2_toiMaxIters=box2d.b2Max(box2d.b2_toiMaxIters,n);c=c.GetMilliseconds();box2d.b2_toiMaxTime=box2d.b2Max(box2d.b2_toiMaxTime,c);box2d.b2_toiTime+=c};goog.exportSymbol(\"box2d.b2TimeOfImpact\",box2d.b2TimeOfImpact);\nbox2d.b2TimeOfImpact.s_timer=new box2d.b2Timer;box2d.b2TimeOfImpact.s_cache=new box2d.b2SimplexCache;box2d.b2TimeOfImpact.s_distanceInput=new box2d.b2DistanceInput;box2d.b2TimeOfImpact.s_distanceOutput=new box2d.b2DistanceOutput;box2d.b2TimeOfImpact.s_xfA=new box2d.b2Transform;box2d.b2TimeOfImpact.s_xfB=new box2d.b2Transform;box2d.b2TimeOfImpact.s_indexA=box2d.b2MakeNumberArray(1);box2d.b2TimeOfImpact.s_indexB=box2d.b2MakeNumberArray(1);box2d.b2TimeOfImpact.s_fcn=new box2d.b2SeparationFunction;\nbox2d.b2TimeOfImpact.s_sweepA=new box2d.b2Sweep;box2d.b2TimeOfImpact.s_sweepB=new box2d.b2Sweep;box2d.b2TimeOfImpact.s_pointA=new box2d.b2Vec2;box2d.b2TimeOfImpact.s_pointB=new box2d.b2Vec2;box2d.b2TimeOfImpact.s_normal=new box2d.b2Vec2;box2d.b2TimeOfImpact.s_axisA=new box2d.b2Vec2;box2d.b2TimeOfImpact.s_axisB=new box2d.b2Vec2;box2d.b2MixFriction=function(a,b){return box2d.b2Sqrt(a*b)};goog.exportSymbol(\"box2d.b2MixFriction\",box2d.b2MixFriction);box2d.b2MixRestitution=function(a,b){return a>b?a:b};goog.exportSymbol(\"box2d.b2MixRestitution\",box2d.b2MixRestitution);box2d.b2ContactEdge=function(){};goog.exportSymbol(\"box2d.b2ContactEdge\",box2d.b2ContactEdge);box2d.b2ContactEdge.prototype.other=null;goog.exportProperty(box2d.b2ContactEdge.prototype,\"other\",box2d.b2ContactEdge.prototype.other);\nbox2d.b2ContactEdge.prototype.contact=null;goog.exportProperty(box2d.b2ContactEdge.prototype,\"contact\",box2d.b2ContactEdge.prototype.contact);box2d.b2ContactEdge.prototype.prev=null;goog.exportProperty(box2d.b2ContactEdge.prototype,\"prev\",box2d.b2ContactEdge.prototype.prev);box2d.b2ContactEdge.prototype.next=null;goog.exportProperty(box2d.b2ContactEdge.prototype,\"next\",box2d.b2ContactEdge.prototype.next);\nbox2d.b2ContactFlag={e_none:0,e_islandFlag:1,e_touchingFlag:2,e_enabledFlag:4,e_filterFlag:8,e_bulletHitFlag:16,e_toiFlag:32};goog.exportProperty(box2d.b2ContactFlag,\"e_none\",box2d.b2ContactFlag.e_none);goog.exportProperty(box2d.b2ContactFlag,\"e_islandFlag\",box2d.b2ContactFlag.e_islandFlag);goog.exportProperty(box2d.b2ContactFlag,\"e_touchingFlag\",box2d.b2ContactFlag.e_touchingFlag);goog.exportProperty(box2d.b2ContactFlag,\"e_enabledFlag\",box2d.b2ContactFlag.e_enabledFlag);\ngoog.exportProperty(box2d.b2ContactFlag,\"e_filterFlag\",box2d.b2ContactFlag.e_filterFlag);goog.exportProperty(box2d.b2ContactFlag,\"e_bulletHitFlag\",box2d.b2ContactFlag.e_bulletHitFlag);goog.exportProperty(box2d.b2ContactFlag,\"e_toiFlag\",box2d.b2ContactFlag.e_toiFlag);box2d.b2Contact=function(){this.m_nodeA=new box2d.b2ContactEdge;this.m_nodeB=new box2d.b2ContactEdge;this.m_manifold=new box2d.b2Manifold;this.m_oldManifold=new box2d.b2Manifold};goog.exportSymbol(\"box2d.b2Contact\",box2d.b2Contact);\nbox2d.b2Contact.prototype.m_flags=box2d.b2ContactFlag.e_none;goog.exportProperty(box2d.b2Contact.prototype,\"m_flags\",box2d.b2Contact.prototype.m_flags);box2d.b2Contact.prototype.m_prev=null;goog.exportProperty(box2d.b2Contact.prototype,\"m_prev\",box2d.b2Contact.prototype.m_prev);box2d.b2Contact.prototype.m_next=null;goog.exportProperty(box2d.b2Contact.prototype,\"m_next\",box2d.b2Contact.prototype.m_next);box2d.b2Contact.prototype.m_nodeA=null;\ngoog.exportProperty(box2d.b2Contact.prototype,\"m_nodeA\",box2d.b2Contact.prototype.m_nodeA);box2d.b2Contact.prototype.m_nodeB=null;goog.exportProperty(box2d.b2Contact.prototype,\"m_nodeB\",box2d.b2Contact.prototype.m_nodeB);box2d.b2Contact.prototype.m_fixtureA=null;goog.exportProperty(box2d.b2Contact.prototype,\"m_fixtureA\",box2d.b2Contact.prototype.m_fixtureA);box2d.b2Contact.prototype.m_fixtureB=null;goog.exportProperty(box2d.b2Contact.prototype,\"m_fixtureB\",box2d.b2Contact.prototype.m_fixtureB);\nbox2d.b2Contact.prototype.m_indexA=0;goog.exportProperty(box2d.b2Contact.prototype,\"m_indexA\",box2d.b2Contact.prototype.m_indexA);box2d.b2Contact.prototype.m_indexB=0;goog.exportProperty(box2d.b2Contact.prototype,\"m_indexB\",box2d.b2Contact.prototype.m_indexB);box2d.b2Contact.prototype.m_manifold=null;goog.exportProperty(box2d.b2Contact.prototype,\"m_manifold\",box2d.b2Contact.prototype.m_manifold);box2d.b2Contact.prototype.m_toiCount=0;goog.exportProperty(box2d.b2Contact.prototype,\"m_toiCount\",box2d.b2Contact.prototype.m_toiCount);\nbox2d.b2Contact.prototype.m_toi=0;goog.exportProperty(box2d.b2Contact.prototype,\"m_toi\",box2d.b2Contact.prototype.m_toi);box2d.b2Contact.prototype.m_friction=0;goog.exportProperty(box2d.b2Contact.prototype,\"m_friction\",box2d.b2Contact.prototype.m_friction);box2d.b2Contact.prototype.m_restitution=0;goog.exportProperty(box2d.b2Contact.prototype,\"m_restitution\",box2d.b2Contact.prototype.m_restitution);box2d.b2Contact.prototype.m_tangentSpeed=0;\ngoog.exportProperty(box2d.b2Contact.prototype,\"m_tangentSpeed\",box2d.b2Contact.prototype.m_tangentSpeed);box2d.b2Contact.prototype.m_oldManifold=null;goog.exportProperty(box2d.b2Contact.prototype,\"m_oldManifold\",box2d.b2Contact.prototype.m_oldManifold);box2d.b2Contact.prototype.GetManifold=function(){return this.m_manifold};goog.exportProperty(box2d.b2Contact.prototype,\"GetManifold\",box2d.b2Contact.prototype.GetManifold);\nbox2d.b2Contact.prototype.GetWorldManifold=function(a){var b=this.m_fixtureA.GetBody(),c=this.m_fixtureB.GetBody(),e=this.m_fixtureA.GetShape(),d=this.m_fixtureB.GetShape();a.Initialize(this.m_manifold,b.GetTransform(),e.m_radius,c.GetTransform(),d.m_radius)};goog.exportProperty(box2d.b2Contact.prototype,\"GetWorldManifold\",box2d.b2Contact.prototype.GetWorldManifold);box2d.b2Contact.prototype.IsTouching=function(){return(this.m_flags&box2d.b2ContactFlag.e_touchingFlag)===box2d.b2ContactFlag.e_touchingFlag};\ngoog.exportProperty(box2d.b2Contact.prototype,\"IsTouching\",box2d.b2Contact.prototype.IsTouching);box2d.b2Contact.prototype.SetEnabled=function(a){this.m_flags=a?this.m_flags|box2d.b2ContactFlag.e_enabledFlag:this.m_flags&~box2d.b2ContactFlag.e_enabledFlag};goog.exportProperty(box2d.b2Contact.prototype,\"SetEnabled\",box2d.b2Contact.prototype.SetEnabled);box2d.b2Contact.prototype.IsEnabled=function(){return(this.m_flags&box2d.b2ContactFlag.e_enabledFlag)===box2d.b2ContactFlag.e_enabledFlag};\ngoog.exportProperty(box2d.b2Contact.prototype,\"IsEnabled\",box2d.b2Contact.prototype.IsEnabled);box2d.b2Contact.prototype.GetNext=function(){return this.m_next};goog.exportProperty(box2d.b2Contact.prototype,\"GetNext\",box2d.b2Contact.prototype.GetNext);box2d.b2Contact.prototype.GetFixtureA=function(){return this.m_fixtureA};goog.exportProperty(box2d.b2Contact.prototype,\"GetFixtureA\",box2d.b2Contact.prototype.GetFixtureA);box2d.b2Contact.prototype.GetChildIndexA=function(){return this.m_indexA};\ngoog.exportProperty(box2d.b2Contact.prototype,\"GetChildIndexA\",box2d.b2Contact.prototype.GetChildIndexA);box2d.b2Contact.prototype.GetFixtureB=function(){return this.m_fixtureB};goog.exportProperty(box2d.b2Contact.prototype,\"GetFixtureB\",box2d.b2Contact.prototype.GetFixtureB);box2d.b2Contact.prototype.GetChildIndexB=function(){return this.m_indexB};goog.exportProperty(box2d.b2Contact.prototype,\"GetChildIndexB\",box2d.b2Contact.prototype.GetChildIndexB);\nbox2d.b2Contact.prototype.Evaluate=function(a,b,c){};goog.exportProperty(box2d.b2Contact.prototype,\"Evaluate\",box2d.b2Contact.prototype.Evaluate);box2d.b2Contact.prototype.FlagForFiltering=function(){this.m_flags|=box2d.b2ContactFlag.e_filterFlag};goog.exportProperty(box2d.b2Contact.prototype,\"FlagForFiltering\",box2d.b2Contact.prototype.FlagForFiltering);box2d.b2Contact.prototype.SetFriction=function(a){this.m_friction=a};goog.exportProperty(box2d.b2Contact.prototype,\"SetFriction\",box2d.b2Contact.prototype.SetFriction);\nbox2d.b2Contact.prototype.GetFriction=function(){return this.m_friction};goog.exportProperty(box2d.b2Contact.prototype,\"GetFriction\",box2d.b2Contact.prototype.GetFriction);box2d.b2Contact.prototype.ResetFriction=function(){this.m_friction=box2d.b2MixFriction(this.m_fixtureA.m_friction,this.m_fixtureB.m_friction)};goog.exportProperty(box2d.b2Contact.prototype,\"ResetFriction\",box2d.b2Contact.prototype.ResetFriction);box2d.b2Contact.prototype.SetRestitution=function(a){this.m_restitution=a};\ngoog.exportProperty(box2d.b2Contact.prototype,\"SetRestitution\",box2d.b2Contact.prototype.SetRestitution);box2d.b2Contact.prototype.GetRestitution=function(){return this.m_restitution};goog.exportProperty(box2d.b2Contact.prototype,\"GetRestitution\",box2d.b2Contact.prototype.GetRestitution);box2d.b2Contact.prototype.ResetRestitution=function(){this.m_restitution=box2d.b2MixRestitution(this.m_fixtureA.m_restitution,this.m_fixtureB.m_restitution)};\ngoog.exportProperty(box2d.b2Contact.prototype,\"ResetRestitution\",box2d.b2Contact.prototype.ResetRestitution);box2d.b2Contact.prototype.SetTangentSpeed=function(a){this.m_tangentSpeed=a};goog.exportProperty(box2d.b2Contact.prototype,\"SetTangentSpeed\",box2d.b2Contact.prototype.SetTangentSpeed);box2d.b2Contact.prototype.GetTangentSpeed=function(){return this.m_tangentSpeed};goog.exportProperty(box2d.b2Contact.prototype,\"GetTangentSpeed\",box2d.b2Contact.prototype.GetTangentSpeed);\nbox2d.b2Contact.prototype.Reset=function(a,b,c,e){this.m_flags=box2d.b2ContactFlag.e_enabledFlag;this.m_fixtureA=a;this.m_fixtureB=c;this.m_indexA=b;this.m_indexB=e;this.m_manifold.pointCount=0;this.m_next=this.m_prev=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;this.m_toiCount=0;this.m_friction=box2d.b2MixFriction(this.m_fixtureA.m_friction,this.m_fixtureB.m_friction);\nthis.m_restitution=box2d.b2MixRestitution(this.m_fixtureA.m_restitution,this.m_fixtureB.m_restitution)};goog.exportProperty(box2d.b2Contact.prototype,\"Reset\",box2d.b2Contact.prototype.Reset);\nbox2d.b2Contact.prototype.Update=function(a){var b=this.m_oldManifold;this.m_oldManifold=this.m_manifold;this.m_manifold=b;this.m_flags|=box2d.b2ContactFlag.e_enabledFlag;var c=!1,b=(this.m_flags&box2d.b2ContactFlag.e_touchingFlag)===box2d.b2ContactFlag.e_touchingFlag,e=this.m_fixtureA.IsSensor(),d=this.m_fixtureB.IsSensor(),e=e||d,d=this.m_fixtureA.GetBody(),f=this.m_fixtureB.GetBody(),c=d.GetTransform(),g=f.GetTransform();if(e)d=this.m_fixtureA.GetShape(),f=this.m_fixtureB.GetShape(),c=box2d.b2TestOverlapShape(d,\nthis.m_indexA,f,this.m_indexB,c,g),this.m_manifold.pointCount=0;else{this.Evaluate(this.m_manifold,c,g);c=0<this.m_manifold.pointCount;for(g=0;g<this.m_manifold.pointCount;++g){var h=this.m_manifold.points[g];h.normalImpulse=0;h.tangentImpulse=0;for(var l=h.id,k=0;k<this.m_oldManifold.pointCount;++k){var m=this.m_oldManifold.points[k];if(m.id.key===l.key){h.normalImpulse=m.normalImpulse;h.tangentImpulse=m.tangentImpulse;break}}}c!==b&&(d.SetAwake(!0),f.SetAwake(!0))}this.m_flags=c?this.m_flags|box2d.b2ContactFlag.e_touchingFlag:\nthis.m_flags&~box2d.b2ContactFlag.e_touchingFlag;!1===b&&!0===c&&a&&a.BeginContact(this);!0===b&&!1===c&&a&&a.EndContact(this);!1===e&&c&&a&&a.PreSolve(this,this.m_oldManifold)};goog.exportProperty(box2d.b2Contact.prototype,\"Update\",box2d.b2Contact.prototype.Update);\nbox2d.b2Contact.prototype.ComputeTOI=function(a,b){var c=box2d.b2Contact.prototype.ComputeTOI.s_input;c.proxyA.SetShape(this.m_fixtureA.GetShape(),this.m_indexA);c.proxyB.SetShape(this.m_fixtureB.GetShape(),this.m_indexB);c.sweepA.Copy(a);c.sweepB.Copy(b);c.tMax=box2d.b2_linearSlop;var e=box2d.b2Contact.prototype.ComputeTOI.s_output;box2d.b2TimeOfImpact(e,c);return e.t};goog.exportProperty(box2d.b2Contact.prototype,\"ComputeTOI\",box2d.b2Contact.prototype.ComputeTOI);\nbox2d.b2Contact.prototype.ComputeTOI.s_input=new box2d.b2TOIInput;box2d.b2Contact.prototype.ComputeTOI.s_output=new box2d.b2TOIOutput;box2d.b2PolygonAndCircleContact=function(){box2d.b2Contact.call(this)};goog.inherits(box2d.b2PolygonAndCircleContact,box2d.b2Contact);goog.exportSymbol(\"box2d.b2PolygonAndCircleContact\",box2d.b2PolygonAndCircleContact);box2d.b2PolygonAndCircleContact.Create=function(a){return new box2d.b2PolygonAndCircleContact};goog.exportProperty(box2d.b2PolygonAndCircleContact,\"Create\",box2d.b2PolygonAndCircleContact.Create);box2d.b2PolygonAndCircleContact.Destroy=function(a,b){};\ngoog.exportProperty(box2d.b2PolygonAndCircleContact,\"Destroy\",box2d.b2PolygonAndCircleContact.Destroy);box2d.b2PolygonAndCircleContact.prototype.Reset=function(a,b,c,e){box2d.b2PolygonAndCircleContact.superClass_.Reset.call(this,a,b,c,e);box2d.ENABLE_ASSERTS&&box2d.b2Assert(a.GetType()===box2d.b2ShapeType.e_polygonShape);box2d.ENABLE_ASSERTS&&box2d.b2Assert(c.GetType()===box2d.b2ShapeType.e_circleShape)};goog.exportProperty(box2d.b2PolygonAndCircleContact.prototype,\"Reset\",box2d.b2PolygonAndCircleContact.prototype.Reset);\nbox2d.b2PolygonAndCircleContact.prototype.Evaluate=function(a,b,c){var e=this.m_fixtureA.GetShape(),d=this.m_fixtureB.GetShape();box2d.ENABLE_ASSERTS&&box2d.b2Assert(e instanceof box2d.b2PolygonShape);box2d.ENABLE_ASSERTS&&box2d.b2Assert(d instanceof box2d.b2CircleShape);box2d.b2CollidePolygonAndCircle(a,e instanceof box2d.b2PolygonShape?e:null,b,d instanceof box2d.b2CircleShape?d:null,c)};goog.exportProperty(box2d.b2PolygonAndCircleContact.prototype,\"Evaluate\",box2d.b2PolygonAndCircleContact.prototype.Evaluate);box2d.b2EdgeAndPolygonContact=function(){box2d.b2Contact.call(this)};goog.inherits(box2d.b2EdgeAndPolygonContact,box2d.b2Contact);goog.exportSymbol(\"box2d.b2EdgeAndPolygonContact\",box2d.b2EdgeAndPolygonContact);box2d.b2EdgeAndPolygonContact.Create=function(a){return new box2d.b2EdgeAndPolygonContact};goog.exportProperty(box2d.b2EdgeAndPolygonContact,\"Create\",box2d.b2EdgeAndPolygonContact.Create);box2d.b2EdgeAndPolygonContact.Destroy=function(a,b){};\ngoog.exportProperty(box2d.b2EdgeAndPolygonContact,\"Destroy\",box2d.b2EdgeAndPolygonContact.Destroy);box2d.b2EdgeAndPolygonContact.prototype.Reset=function(a,b,c,e){box2d.b2EdgeAndPolygonContact.superClass_.Reset.call(this,a,b,c,e);box2d.ENABLE_ASSERTS&&box2d.b2Assert(a.GetType()===box2d.b2ShapeType.e_edgeShape);box2d.ENABLE_ASSERTS&&box2d.b2Assert(c.GetType()===box2d.b2ShapeType.e_polygonShape)};goog.exportProperty(box2d.b2EdgeAndPolygonContact.prototype,\"Reset\",box2d.b2EdgeAndPolygonContact.prototype.Reset);\nbox2d.b2EdgeAndPolygonContact.prototype.Evaluate=function(a,b,c){var e=this.m_fixtureA.GetShape(),d=this.m_fixtureB.GetShape();box2d.ENABLE_ASSERTS&&box2d.b2Assert(e instanceof box2d.b2EdgeShape);box2d.ENABLE_ASSERTS&&box2d.b2Assert(d instanceof box2d.b2PolygonShape);box2d.b2CollideEdgeAndPolygon(a,e instanceof box2d.b2EdgeShape?e:null,b,d instanceof box2d.b2PolygonShape?d:null,c)};goog.exportProperty(box2d.b2EdgeAndPolygonContact.prototype,\"Evaluate\",box2d.b2EdgeAndPolygonContact.prototype.Evaluate);box2d.b2MassData=function(){this.center=new box2d.b2Vec2(0,0)};goog.exportSymbol(\"box2d.b2MassData\",box2d.b2MassData);box2d.b2MassData.prototype.mass=0;goog.exportProperty(box2d.b2MassData.prototype,\"mass\",box2d.b2MassData.prototype.mass);box2d.b2MassData.prototype.center=null;goog.exportProperty(box2d.b2MassData.prototype,\"center\",box2d.b2MassData.prototype.center);box2d.b2MassData.prototype.I=0;goog.exportProperty(box2d.b2MassData.prototype,\"I\",box2d.b2MassData.prototype.I);\nbox2d.b2ShapeType={e_unknown:-1,e_circleShape:0,e_edgeShape:1,e_polygonShape:2,e_chainShape:3,e_shapeTypeCount:4};goog.exportSymbol(\"box2d.b2ShapeType\",box2d.b2ShapeType);goog.exportProperty(box2d.b2ShapeType,\"e_unknown\",box2d.b2ShapeType.e_unknown);goog.exportProperty(box2d.b2ShapeType,\"e_circleShape\",box2d.b2ShapeType.e_circleShape);goog.exportProperty(box2d.b2ShapeType,\"e_edgeShape\",box2d.b2ShapeType.e_edgeShape);goog.exportProperty(box2d.b2ShapeType,\"e_polygonShape\",box2d.b2ShapeType.e_polygonShape);\ngoog.exportProperty(box2d.b2ShapeType,\"e_chainShape\",box2d.b2ShapeType.e_chainShape);goog.exportProperty(box2d.b2ShapeType,\"e_shapeTypeCount\",box2d.b2ShapeType.e_shapeTypeCount);box2d.b2Shape=function(a,b){this.m_type=a;this.m_radius=b};goog.exportSymbol(\"box2d.b2Shape\",box2d.b2Shape);box2d.b2Shape.prototype.m_type=box2d.b2ShapeType.e_unknown;goog.exportProperty(box2d.b2Shape.prototype,\"m_type\",box2d.b2Shape.prototype.m_type);box2d.b2Shape.prototype.m_radius=0;\ngoog.exportProperty(box2d.b2Shape.prototype,\"m_radius\",box2d.b2Shape.prototype.m_radius);box2d.b2Shape.prototype.Clone=function(){box2d.ENABLE_ASSERTS&&box2d.b2Assert(!1);return null};goog.exportProperty(box2d.b2Shape.prototype,\"Clone\",box2d.b2Shape.prototype.Clone);box2d.b2Shape.prototype.Copy=function(a){box2d.ENABLE_ASSERTS&&box2d.b2Assert(this.m_type===a.m_type);this.m_radius=a.m_radius;return this};goog.exportProperty(box2d.b2Shape.prototype,\"Copy\",box2d.b2Shape.prototype.Copy);\nbox2d.b2Shape.prototype.GetType=function(){return this.m_type};goog.exportProperty(box2d.b2Shape.prototype,\"GetType\",box2d.b2Shape.prototype.GetType);box2d.b2Shape.prototype.GetChildCount=function(){box2d.ENABLE_ASSERTS&&box2d.b2Assert(!1,\"pure virtual\");return 0};goog.exportProperty(box2d.b2Shape.prototype,\"GetChildCount\",box2d.b2Shape.prototype.GetChildCount);box2d.b2Shape.prototype.TestPoint=function(a,b){box2d.ENABLE_ASSERTS&&box2d.b2Assert(!1,\"pure virtual\");return!1};\ngoog.exportProperty(box2d.b2Shape.prototype,\"TestPoint\",box2d.b2Shape.prototype.TestPoint);box2d.b2Shape.prototype.RayCast=function(a,b,c,e){box2d.ENABLE_ASSERTS&&box2d.b2Assert(!1,\"pure virtual\");return!1};goog.exportProperty(box2d.b2Shape.prototype,\"RayCast\",box2d.b2Shape.prototype.RayCast);box2d.b2Shape.prototype.ComputeAABB=function(a,b,c){box2d.ENABLE_ASSERTS&&box2d.b2Assert(!1,\"pure virtual\")};goog.exportProperty(box2d.b2Shape.prototype,\"ComputeAABB\",box2d.b2Shape.prototype.ComputeAABB);\nbox2d.b2Shape.prototype.ComputeMass=function(a,b){box2d.ENABLE_ASSERTS&&box2d.b2Assert(!1,\"pure virtual\")};goog.exportProperty(box2d.b2Shape.prototype,\"ComputeMass\",box2d.b2Shape.prototype.ComputeMass);box2d.b2Shape.prototype.SetupDistanceProxy=function(a,b){box2d.ENABLE_ASSERTS&&box2d.b2Assert(!1,\"pure virtual\")};box2d.b2Shape.prototype.ComputeSubmergedArea=function(a,b,c,e){box2d.ENABLE_ASSERTS&&box2d.b2Assert(!1,\"pure virtual\");return 0};\ngoog.exportProperty(box2d.b2Shape.prototype,\"ComputeSubmergedArea\",box2d.b2Shape.prototype.ComputeSubmergedArea);box2d.b2Shape.prototype.Dump=function(){box2d.ENABLE_ASSERTS&&box2d.b2Assert(!1,\"pure virtual\")};goog.exportProperty(box2d.b2Shape.prototype,\"Dump\",box2d.b2Shape.prototype.Dump);box2d.b2PolygonShape=function(){box2d.b2Shape.call(this,box2d.b2ShapeType.e_polygonShape,box2d.b2_polygonRadius);this.m_centroid=new box2d.b2Vec2(0,0);this.m_vertices=box2d.b2Vec2.MakeArray(box2d.b2_maxPolygonVertices);this.m_normals=box2d.b2Vec2.MakeArray(box2d.b2_maxPolygonVertices)};goog.inherits(box2d.b2PolygonShape,box2d.b2Shape);goog.exportSymbol(\"box2d.b2PolygonShape\",box2d.b2PolygonShape);box2d.b2PolygonShape.prototype.m_centroid=null;\ngoog.exportProperty(box2d.b2PolygonShape.prototype,\"m_centroid\",box2d.b2PolygonShape.prototype.m_centroid);box2d.b2PolygonShape.prototype.m_vertices=null;goog.exportProperty(box2d.b2PolygonShape.prototype,\"m_vertices\",box2d.b2PolygonShape.prototype.m_vertices);box2d.b2PolygonShape.prototype.m_normals=null;goog.exportProperty(box2d.b2PolygonShape.prototype,\"m_normals\",box2d.b2PolygonShape.prototype.m_normals);box2d.b2PolygonShape.prototype.m_count=0;\ngoog.exportProperty(box2d.b2PolygonShape.prototype,\"m_count\",box2d.b2PolygonShape.prototype.m_count);box2d.b2PolygonShape.prototype.Clone=function(){return(new box2d.b2PolygonShape).Copy(this)};goog.exportProperty(box2d.b2PolygonShape.prototype,\"Clone\",box2d.b2PolygonShape.prototype.Clone);\nbox2d.b2PolygonShape.prototype.Copy=function(a){box2d.b2PolygonShape.superClass_.Copy.call(this,a);box2d.ENABLE_ASSERTS&&box2d.b2Assert(a instanceof box2d.b2PolygonShape);this.m_centroid.Copy(a.m_centroid);this.m_count=a.m_count;for(var b=0,c=this.m_count;b<c;++b)this.m_vertices[b].Copy(a.m_vertices[b]),this.m_normals[b].Copy(a.m_normals[b]);return this};goog.exportProperty(box2d.b2PolygonShape.prototype,\"Copy\",box2d.b2PolygonShape.prototype.Copy);\nbox2d.b2PolygonShape.prototype.SetAsBox=function(a,b){this.m_count=4;this.m_vertices[0].SetXY(-a,-b);this.m_vertices[1].SetXY(a,-b);this.m_vertices[2].SetXY(a,b);this.m_vertices[3].SetXY(-a,b);this.m_normals[0].SetXY(0,-1);this.m_normals[1].SetXY(1,0);this.m_normals[2].SetXY(0,1);this.m_normals[3].SetXY(-1,0);this.m_centroid.SetZero();return this};goog.exportProperty(box2d.b2PolygonShape.prototype,\"SetAsBox\",box2d.b2PolygonShape.prototype.SetAsBox);\nbox2d.b2PolygonShape.prototype.SetAsOrientedBox=function(a,b,c,e){this.m_count=4;this.m_vertices[0].SetXY(-a,-b);this.m_vertices[1].SetXY(a,-b);this.m_vertices[2].SetXY(a,b);this.m_vertices[3].SetXY(-a,b);this.m_normals[0].SetXY(0,-1);this.m_normals[1].SetXY(1,0);this.m_normals[2].SetXY(0,1);this.m_normals[3].SetXY(-1,0);this.m_centroid.Copy(c);a=new box2d.b2Transform;a.SetPosition(c);a.SetRotationAngleRadians(e);c=0;for(e=this.m_count;c<e;++c)box2d.b2MulXV(a,this.m_vertices[c],this.m_vertices[c]),\nbox2d.b2MulRV(a.q,this.m_normals[c],this.m_normals[c]);return this};goog.exportProperty(box2d.b2PolygonShape.prototype,\"SetAsOrientedBox\",box2d.b2PolygonShape.prototype.SetAsOrientedBox);\nbox2d.b2PolygonShape.prototype.Set=function(a,b){void 0===b&&(b=a.length);box2d.ENABLE_ASSERTS&&box2d.b2Assert(3<=b&&b<=box2d.b2_maxPolygonVertices);if(3>b)return this.SetAsBox(1,1);for(var c=box2d.b2Min(b,box2d.b2_maxPolygonVertices),e=box2d.b2PolygonShape.prototype.Set.s_ps,d=0,f=0;f<c;++f){for(var g=a[f],h=!0,l=0;l<d;++l)if(box2d.b2DistanceSquaredVV(g,e[l])<0.5*box2d.b2_linearSlop){h=!1;break}h&&e[d++].Copy(g)}c=d;if(3>c)return box2d.ENABLE_ASSERTS&&box2d.b2Assert(!1),this.SetAsBox(1,1);d=0;g=\ne[0].x;for(f=1;f<c;++f)if(l=e[f].x,l>g||l===g&&e[f].y<e[d].y)d=f,g=l;for(var k=box2d.b2PolygonShape.prototype.Set.s_hull,h=0,f=d;;){k[h]=f;for(var m=0,l=1;l<c;++l)if(m===f)m=l;else{var n=box2d.b2SubVV(e[m],e[k[h]],box2d.b2PolygonShape.prototype.Set.s_r),g=box2d.b2SubVV(e[l],e[k[h]],box2d.b2PolygonShape.prototype.Set.s_v),p=box2d.b2CrossVV(n,g);0>p&&(m=l);0===p&&g.GetLengthSquared()>n.GetLengthSquared()&&(m=l)}++h;f=m;if(m===d)break}this.m_count=h;for(f=0;f<h;++f)this.m_vertices[f].Copy(e[k[f]]);f=\n0;for(c=h;f<c;++f)e=box2d.b2SubVV(this.m_vertices[(f+1)%c],this.m_vertices[f],box2d.b2Vec2.s_t0),box2d.ENABLE_ASSERTS&&box2d.b2Assert(e.GetLengthSquared()>box2d.b2_epsilon_sq),box2d.b2CrossVOne(e,this.m_normals[f]).SelfNormalize();box2d.b2PolygonShape.ComputeCentroid(this.m_vertices,h,this.m_centroid);return this};goog.exportProperty(box2d.b2PolygonShape.prototype,\"Set\",box2d.b2PolygonShape.prototype.Set);box2d.b2PolygonShape.prototype.Set.s_ps=box2d.b2Vec2.MakeArray(box2d.b2_maxPolygonVertices);\nbox2d.b2PolygonShape.prototype.Set.s_hull=box2d.b2MakeNumberArray(box2d.b2_maxPolygonVertices);box2d.b2PolygonShape.prototype.Set.s_r=new box2d.b2Vec2;box2d.b2PolygonShape.prototype.Set.s_v=new box2d.b2Vec2;box2d.b2PolygonShape.prototype.SetAsVector=function(a,b){this.Set(a,b);return this};goog.exportProperty(box2d.b2PolygonShape.prototype,\"SetAsVector\",box2d.b2PolygonShape.prototype.SetAsVector);box2d.b2PolygonShape.prototype.SetAsArray=function(a,b){this.Set(a,b);return this};\ngoog.exportProperty(box2d.b2PolygonShape.prototype,\"SetAsArray\",box2d.b2PolygonShape.prototype.SetAsArray);box2d.b2PolygonShape.prototype.GetChildCount=function(){return 1};goog.exportProperty(box2d.b2PolygonShape.prototype,\"GetChildCount\",box2d.b2PolygonShape.prototype.GetChildCount);\nbox2d.b2PolygonShape.prototype.TestPoint=function(a,b){for(var c=box2d.b2MulTXV(a,b,box2d.b2PolygonShape.prototype.TestPoint.s_pLocal),e=0,d=this.m_count;e<d;++e)if(0<box2d.b2DotVV(this.m_normals[e],box2d.b2SubVV(c,this.m_vertices[e],box2d.b2Vec2.s_t0)))return!1;return!0};goog.exportProperty(box2d.b2PolygonShape.prototype,\"TestPoint\",box2d.b2PolygonShape.prototype.TestPoint);box2d.b2PolygonShape.prototype.TestPoint.s_pLocal=new box2d.b2Vec2;\nbox2d.b2PolygonShape.prototype.RayCast=function(a,b,c,e){e=box2d.b2MulTXV(c,b.p1,box2d.b2PolygonShape.prototype.RayCast.s_p1);for(var d=box2d.b2MulTXV(c,b.p2,box2d.b2PolygonShape.prototype.RayCast.s_p2),d=box2d.b2SubVV(d,e,box2d.b2PolygonShape.prototype.RayCast.s_d),f=0,g=b.maxFraction,h=-1,l=0,k=this.m_count;l<k;++l){var m=box2d.b2DotVV(this.m_normals[l],box2d.b2SubVV(this.m_vertices[l],e,box2d.b2Vec2.s_t0)),n=box2d.b2DotVV(this.m_normals[l],d);if(0===n){if(0>m)return!1}else 0>n&&m<f*n?(f=m/n,h=\nl):0<n&&m<g*n&&(g=m/n);if(g<f)return!1}box2d.ENABLE_ASSERTS&&box2d.b2Assert(0<=f&&f<=b.maxFraction);return 0<=h?(a.fraction=f,box2d.b2MulRV(c.q,this.m_normals[h],a.normal),!0):!1};goog.exportProperty(box2d.b2PolygonShape.prototype,\"RayCast\",box2d.b2PolygonShape.prototype.RayCast);box2d.b2PolygonShape.prototype.RayCast.s_p1=new box2d.b2Vec2;box2d.b2PolygonShape.prototype.RayCast.s_p2=new box2d.b2Vec2;box2d.b2PolygonShape.prototype.RayCast.s_d=new box2d.b2Vec2;\nbox2d.b2PolygonShape.prototype.ComputeAABB=function(a,b,c){c=box2d.b2MulXV(b,this.m_vertices[0],a.lowerBound);a=a.upperBound.Copy(c);for(var e=0,d=this.m_count;e<d;++e){var f=box2d.b2MulXV(b,this.m_vertices[e],box2d.b2PolygonShape.prototype.ComputeAABB.s_v);box2d.b2MinV(f,c,c);box2d.b2MaxV(f,a,a)}b=this.m_radius;c.SelfSubXY(b,b);a.SelfAddXY(b,b)};goog.exportProperty(box2d.b2PolygonShape.prototype,\"ComputeAABB\",box2d.b2PolygonShape.prototype.ComputeAABB);\nbox2d.b2PolygonShape.prototype.ComputeAABB.s_v=new box2d.b2Vec2;\nbox2d.b2PolygonShape.prototype.ComputeMass=function(a,b){box2d.ENABLE_ASSERTS&&box2d.b2Assert(3<=this.m_count);for(var c=box2d.b2PolygonShape.prototype.ComputeMass.s_center.SetZero(),e=0,d=0,f=box2d.b2PolygonShape.prototype.ComputeMass.s_s.SetZero(),g=0,h=this.m_count;g<h;++g)f.SelfAdd(this.m_vertices[g]);f.SelfMul(1/this.m_count);for(var l=1/3,g=0,h=this.m_count;g<h;++g){var k=box2d.b2SubVV(this.m_vertices[g],f,box2d.b2PolygonShape.prototype.ComputeMass.s_e1),m=box2d.b2SubVV(this.m_vertices[(g+1)%\nh],f,box2d.b2PolygonShape.prototype.ComputeMass.s_e2),n=box2d.b2CrossVV(k,m),p=0.5*n,e=e+p;c.SelfAdd(box2d.b2MulSV(p*l,box2d.b2AddVV(k,m,box2d.b2Vec2.s_t0),box2d.b2Vec2.s_t1));var p=k.x,k=k.y,q=m.x,m=m.y,d=d+0.25*l*n*(p*p+q*p+q*q+(k*k+m*k+m*m))}a.mass=b*e;box2d.ENABLE_ASSERTS&&box2d.b2Assert(e>box2d.b2_epsilon);c.SelfMul(1/e);box2d.b2AddVV(c,f,a.center);a.I=b*d;a.I+=a.mass*(box2d.b2DotVV(a.center,a.center)-box2d.b2DotVV(c,c))};goog.exportProperty(box2d.b2PolygonShape.prototype,\"ComputeMass\",box2d.b2PolygonShape.prototype.ComputeMass);\nbox2d.b2PolygonShape.prototype.ComputeMass.s_center=new box2d.b2Vec2;box2d.b2PolygonShape.prototype.ComputeMass.s_s=new box2d.b2Vec2;box2d.b2PolygonShape.prototype.ComputeMass.s_e1=new box2d.b2Vec2;box2d.b2PolygonShape.prototype.ComputeMass.s_e2=new box2d.b2Vec2;\nbox2d.b2PolygonShape.prototype.Validate=function(){for(var a=0;a<this.m_count;++a)for(var b=a,c=(a+1)%this.m_count,e=this.m_vertices[b],d=box2d.b2SubVV(this.m_vertices[c],e,box2d.b2PolygonShape.prototype.Validate.s_e),f=0;f<this.m_count;++f)if(f!==b&&f!==c){var g=box2d.b2SubVV(this.m_vertices[f],e,box2d.b2PolygonShape.prototype.Validate.s_v);if(0>box2d.b2CrossVV(d,g))return!1}return!0};goog.exportProperty(box2d.b2PolygonShape.prototype,\"Validate\",box2d.b2PolygonShape.prototype.Validate);\nbox2d.b2PolygonShape.prototype.Validate.s_e=new box2d.b2Vec2;box2d.b2PolygonShape.prototype.Validate.s_v=new box2d.b2Vec2;box2d.b2PolygonShape.prototype.SetupDistanceProxy=function(a,b){a.m_vertices=this.m_vertices;a.m_count=this.m_count;a.m_radius=this.m_radius};\nbox2d.b2PolygonShape.prototype.ComputeSubmergedArea=function(a,b,c,e){var d=box2d.b2MulTRV(c.q,a,box2d.b2PolygonShape.prototype.ComputeSubmergedArea.s_normalL),f=b-box2d.b2DotVV(a,c.p),g=box2d.b2PolygonShape.prototype.ComputeSubmergedArea.s_depths,h=0,l=-1;b=-1;var k=!1;a=0;for(var m=this.m_count;a<m;++a){g[a]=box2d.b2DotVV(d,this.m_vertices[a])-f;var n=g[a]<-box2d.b2_epsilon;0<a&&(n?k||(l=a-1,h++):k&&(b=a-1,h++));k=n}switch(h){case 0:return k?(a=box2d.b2PolygonShape.prototype.ComputeSubmergedArea.s_md,\nthis.ComputeMass(a,1),box2d.b2MulXV(c,a.center,e),a.mass):0;case 1:-1===l?l=this.m_count-1:b=this.m_count-1}a=(l+1)%this.m_count;d=(b+1)%this.m_count;f=(0-g[l])/(g[a]-g[l]);g=(0-g[b])/(g[d]-g[b]);l=box2d.b2PolygonShape.prototype.ComputeSubmergedArea.s_intoVec.SetXY(this.m_vertices[l].x*(1-f)+this.m_vertices[a].x*f,this.m_vertices[l].y*(1-f)+this.m_vertices[a].y*f);b=box2d.b2PolygonShape.prototype.ComputeSubmergedArea.s_outoVec.SetXY(this.m_vertices[b].x*(1-g)+this.m_vertices[d].x*g,this.m_vertices[b].y*\n(1-g)+this.m_vertices[d].y*g);g=0;f=box2d.b2PolygonShape.prototype.ComputeSubmergedArea.s_center.SetZero();h=this.m_vertices[a];for(k=null;a!==d;)a=(a+1)%this.m_count,k=a===d?b:this.m_vertices[a],m=0.5*((h.x-l.x)*(k.y-l.y)-(h.y-l.y)*(k.x-l.x)),g+=m,f.x+=m*(l.x+h.x+k.x)/3,f.y+=m*(l.y+h.y+k.y)/3,h=k;f.SelfMul(1/g);box2d.b2MulXV(c,f,e);return g};goog.exportProperty(box2d.b2PolygonShape.prototype,\"ComputeSubmergedArea\",box2d.b2PolygonShape.prototype.ComputeSubmergedArea);\nbox2d.b2PolygonShape.prototype.ComputeSubmergedArea.s_normalL=new box2d.b2Vec2;box2d.b2PolygonShape.prototype.ComputeSubmergedArea.s_depths=box2d.b2MakeNumberArray(box2d.b2_maxPolygonVertices);box2d.b2PolygonShape.prototype.ComputeSubmergedArea.s_md=new box2d.b2MassData;box2d.b2PolygonShape.prototype.ComputeSubmergedArea.s_intoVec=new box2d.b2Vec2;box2d.b2PolygonShape.prototype.ComputeSubmergedArea.s_outoVec=new box2d.b2Vec2;box2d.b2PolygonShape.prototype.ComputeSubmergedArea.s_center=new box2d.b2Vec2;\nbox2d.b2PolygonShape.prototype.Dump=function(){box2d.b2Log(\"    /*box2d.b2PolygonShape*/ var shape = new box2d.b2PolygonShape();\\n\");box2d.b2Log(\"    /*box2d.b2Vec2[]*/ var vs = box2d.b2Vec2.MakeArray(%d);\\n\",box2d.b2_maxPolygonVertices);for(var a=0;a<this.m_count;++a)box2d.b2Log(\"    vs[%d].SetXY(%.15f, %.15f);\\n\",a,this.m_vertices[a].x,this.m_vertices[a].y);box2d.b2Log(\"    shape.Set(vs, %d);\\n\",this.m_count)};goog.exportProperty(box2d.b2PolygonShape.prototype,\"Dump\",box2d.b2PolygonShape.prototype.Dump);\nbox2d.b2PolygonShape.ComputeCentroid=function(a,b,c){box2d.ENABLE_ASSERTS&&box2d.b2Assert(3<=b);c.SetZero();for(var e=0,d=box2d.b2PolygonShape.ComputeCentroid.s_pRef.SetZero(),f=1/3,g=0;g<b;++g){var h=d,l=a[g],k=a[(g+1)%b],m=box2d.b2SubVV(l,h,box2d.b2PolygonShape.ComputeCentroid.s_e1),n=box2d.b2SubVV(k,h,box2d.b2PolygonShape.ComputeCentroid.s_e2),m=0.5*box2d.b2CrossVV(m,n),e=e+m;c.x+=m*f*(h.x+l.x+k.x);c.y+=m*f*(h.y+l.y+k.y)}box2d.ENABLE_ASSERTS&&box2d.b2Assert(e>box2d.b2_epsilon);c.SelfMul(1/e);return c};\ngoog.exportProperty(box2d.b2PolygonShape,\"ComputeCentroid\",box2d.b2PolygonShape.ComputeCentroid);box2d.b2PolygonShape.ComputeCentroid.s_pRef=new box2d.b2Vec2;box2d.b2PolygonShape.ComputeCentroid.s_e1=new box2d.b2Vec2;box2d.b2PolygonShape.ComputeCentroid.s_e2=new box2d.b2Vec2;box2d.b2CollideEdge={};\nbox2d.b2CollideEdgeAndCircle=function(a,b,c,e,d){a.pointCount=0;c=box2d.b2MulTXV(c,box2d.b2MulXV(d,e.m_p,box2d.b2Vec2.s_t0),box2d.b2CollideEdgeAndCircle.s_Q);var f=b.m_vertex1,g=b.m_vertex2,h=box2d.b2SubVV(g,f,box2d.b2CollideEdgeAndCircle.s_e),l=box2d.b2DotVV(h,box2d.b2SubVV(g,c,box2d.b2Vec2.s_t0)),k=box2d.b2DotVV(h,box2d.b2SubVV(c,f,box2d.b2Vec2.s_t0)),m=b.m_radius+e.m_radius;d=box2d.b2CollideEdgeAndCircle.s_id;d.cf.indexB=0;d.cf.typeB=box2d.b2ContactFeatureType.e_vertex;if(0>=k){var n=f,l=box2d.b2SubVV(c,\nn,box2d.b2CollideEdgeAndCircle.s_d),l=box2d.b2DotVV(l,l);if(!(l>m*m)){if(b.m_hasVertex0&&(b=box2d.b2SubVV(f,b.m_vertex0,box2d.b2CollideEdgeAndCircle.s_e1),0<box2d.b2DotVV(b,box2d.b2SubVV(f,c,box2d.b2Vec2.s_t0))))return;d.cf.indexA=0;d.cf.typeA=box2d.b2ContactFeatureType.e_vertex;a.pointCount=1;a.type=box2d.b2ManifoldType.e_circles;a.localNormal.SetZero();a.localPoint.Copy(n);a.points[0].id.Copy(d);a.points[0].localPoint.Copy(e.m_p)}}else if(0>=l){if(n=g,l=box2d.b2SubVV(c,n,box2d.b2CollideEdgeAndCircle.s_d),\nl=box2d.b2DotVV(l,l),!(l>m*m)){if(b.m_hasVertex3&&(f=box2d.b2SubVV(b.m_vertex3,g,box2d.b2CollideEdgeAndCircle.s_e2),0<box2d.b2DotVV(f,box2d.b2SubVV(c,g,box2d.b2Vec2.s_t0))))return;d.cf.indexA=1;d.cf.typeA=box2d.b2ContactFeatureType.e_vertex;a.pointCount=1;a.type=box2d.b2ManifoldType.e_circles;a.localNormal.SetZero();a.localPoint.Copy(n);a.points[0].id.Copy(d);a.points[0].localPoint.Copy(e.m_p)}}else b=box2d.b2DotVV(h,h),box2d.ENABLE_ASSERTS&&box2d.b2Assert(0<b),n=box2d.b2CollideEdgeAndCircle.s_P,\nn.x=1/b*(l*f.x+k*g.x),n.y=1/b*(l*f.y+k*g.y),l=box2d.b2SubVV(c,n,box2d.b2CollideEdgeAndCircle.s_d),l=box2d.b2DotVV(l,l),l>m*m||(n=box2d.b2CollideEdgeAndCircle.s_n.SetXY(-h.y,h.x),0>box2d.b2DotVV(n,box2d.b2SubVV(c,f,box2d.b2Vec2.s_t0))&&n.SetXY(-n.x,-n.y),n.Normalize(),d.cf.indexA=0,d.cf.typeA=box2d.b2ContactFeatureType.e_face,a.pointCount=1,a.type=box2d.b2ManifoldType.e_faceA,a.localNormal.Copy(n),a.localPoint.Copy(f),a.points[0].id.Copy(d),a.points[0].localPoint.Copy(e.m_p))};\ngoog.exportSymbol(\"box2d.b2CollideEdgeAndCircle\",box2d.b2CollideEdgeAndCircle);box2d.b2CollideEdgeAndCircle.s_Q=new box2d.b2Vec2;box2d.b2CollideEdgeAndCircle.s_e=new box2d.b2Vec2;box2d.b2CollideEdgeAndCircle.s_d=new box2d.b2Vec2;box2d.b2CollideEdgeAndCircle.s_e1=new box2d.b2Vec2;box2d.b2CollideEdgeAndCircle.s_e2=new box2d.b2Vec2;box2d.b2CollideEdgeAndCircle.s_P=new box2d.b2Vec2;box2d.b2CollideEdgeAndCircle.s_n=new box2d.b2Vec2;box2d.b2CollideEdgeAndCircle.s_id=new box2d.b2ContactID;\nbox2d.b2EPAxisType={e_unknown:0,e_edgeA:1,e_edgeB:2};goog.exportSymbol(\"box2d.b2EPAxisType\",box2d.b2EPAxisType);goog.exportProperty(box2d.b2EPAxisType,\"e_unknown\",box2d.b2EPAxisType.e_unknown);goog.exportProperty(box2d.b2EPAxisType,\"e_edgeA\",box2d.b2EPAxisType.e_edgeA);goog.exportProperty(box2d.b2EPAxisType,\"e_edgeB\",box2d.b2EPAxisType.e_edgeB);box2d.b2EPAxis=function(){};goog.exportSymbol(\"box2d.b2EPAxis\",box2d.b2EPAxis);box2d.b2EPAxis.prototype.type=box2d.b2EPAxisType.e_unknown;\ngoog.exportProperty(box2d.b2EPAxis.prototype,\"type\",box2d.b2EPAxis.prototype.type);box2d.b2EPAxis.prototype.index=0;goog.exportProperty(box2d.b2EPAxis.prototype,\"index\",box2d.b2EPAxis.prototype.index);box2d.b2EPAxis.prototype.separation=0;goog.exportProperty(box2d.b2EPAxis.prototype,\"separation\",box2d.b2EPAxis.prototype.separation);\nbox2d.b2TempPolygon=function(){this.vertices=box2d.b2Vec2.MakeArray(box2d.b2_maxPolygonVertices);this.normals=box2d.b2Vec2.MakeArray(box2d.b2_maxPolygonVertices);this.count=0};goog.exportSymbol(\"box2d.b2TempPolygon\",box2d.b2TempPolygon);box2d.b2TempPolygon.prototype.vertices=null;goog.exportProperty(box2d.b2TempPolygon.prototype,\"vertices\",box2d.b2TempPolygon.prototype.vertices);box2d.b2TempPolygon.prototype.normals=null;goog.exportProperty(box2d.b2TempPolygon.prototype,\"normals\",box2d.b2TempPolygon.prototype.normals);\nbox2d.b2TempPolygon.prototype.count=0;goog.exportProperty(box2d.b2TempPolygon.prototype,\"count\",box2d.b2TempPolygon.prototype.count);box2d.b2ReferenceFace=function(){this.i2=this.i1=0;this.v1=new box2d.b2Vec2;this.v2=new box2d.b2Vec2;this.normal=new box2d.b2Vec2;this.sideNormal1=new box2d.b2Vec2;this.sideOffset1=0;this.sideNormal2=new box2d.b2Vec2;this.sideOffset2=0};goog.exportSymbol(\"box2d.b2ReferenceFace\",box2d.b2ReferenceFace);box2d.b2ReferenceFace.prototype.i1=0;\ngoog.exportProperty(box2d.b2ReferenceFace.prototype,\"i1\",box2d.b2ReferenceFace.prototype.i1);box2d.b2ReferenceFace.prototype.i2=0;goog.exportProperty(box2d.b2ReferenceFace.prototype,\"i2\",box2d.b2ReferenceFace.prototype.i2);box2d.b2ReferenceFace.prototype.v1=null;goog.exportProperty(box2d.b2ReferenceFace.prototype,\"v1\",box2d.b2ReferenceFace.prototype.v1);box2d.b2ReferenceFace.prototype.v2=null;goog.exportProperty(box2d.b2ReferenceFace.prototype,\"v2\",box2d.b2ReferenceFace.prototype.v2);\nbox2d.b2ReferenceFace.prototype.normal=null;goog.exportProperty(box2d.b2ReferenceFace.prototype,\"normal\",box2d.b2ReferenceFace.prototype.normal);box2d.b2ReferenceFace.prototype.sideNormal1=null;goog.exportProperty(box2d.b2ReferenceFace.prototype,\"sideNormal1\",box2d.b2ReferenceFace.prototype.sideNormal1);box2d.b2ReferenceFace.prototype.sideOffset1=0;goog.exportProperty(box2d.b2ReferenceFace.prototype,\"sideOffset1\",box2d.b2ReferenceFace.prototype.sideOffset1);\nbox2d.b2ReferenceFace.prototype.sideNormal2=null;goog.exportProperty(box2d.b2ReferenceFace.prototype,\"sideNormal2\",box2d.b2ReferenceFace.prototype.sideNormal2);box2d.b2ReferenceFace.prototype.sideOffset2=0;goog.exportProperty(box2d.b2ReferenceFace.prototype,\"sideOffset2\",box2d.b2ReferenceFace.prototype.sideOffset2);box2d.b2EPColliderVertexType={e_isolated:0,e_concave:1,e_convex:2};goog.exportSymbol(\"box2d.b2EPColliderVertexType\",box2d.b2EPColliderVertexType);\ngoog.exportProperty(box2d.b2EPColliderVertexType,\"e_isolated\",box2d.b2EPColliderVertexType.e_isolated);goog.exportProperty(box2d.b2EPColliderVertexType,\"e_concave\",box2d.b2EPColliderVertexType.e_concave);goog.exportProperty(box2d.b2EPColliderVertexType,\"e_convex\",box2d.b2EPColliderVertexType.e_convex);\nbox2d.b2EPCollider=function(){this.m_polygonB=new box2d.b2TempPolygon;this.m_xf=new box2d.b2Transform;this.m_centroidB=new box2d.b2Vec2;this.m_v0=new box2d.b2Vec2;this.m_v1=new box2d.b2Vec2;this.m_v2=new box2d.b2Vec2;this.m_v3=new box2d.b2Vec2;this.m_normal0=new box2d.b2Vec2;this.m_normal1=new box2d.b2Vec2;this.m_normal2=new box2d.b2Vec2;this.m_normal=new box2d.b2Vec2;this.m_type2=this.m_type1=box2d.b2EPColliderVertexType.e_isolated;this.m_lowerLimit=new box2d.b2Vec2;this.m_upperLimit=new box2d.b2Vec2;\nthis.m_radius=0;this.m_front=!1};goog.exportSymbol(\"box2d.b2EPCollider\",box2d.b2EPCollider);box2d.b2EPCollider.prototype.m_polygonB=null;goog.exportProperty(box2d.b2EPCollider.prototype,\"m_polygonB\",box2d.b2EPCollider.prototype.m_polygonB);box2d.b2EPCollider.prototype.m_xf=null;goog.exportProperty(box2d.b2EPCollider.prototype,\"m_xf\",box2d.b2EPCollider.prototype.m_xf);box2d.b2EPCollider.prototype.m_centroidB=null;goog.exportProperty(box2d.b2EPCollider.prototype,\"m_centroidB\",box2d.b2EPCollider.prototype.m_centroidB);\nbox2d.b2EPCollider.prototype.m_v0=null;goog.exportProperty(box2d.b2EPCollider.prototype,\"m_v0\",box2d.b2EPCollider.prototype.m_v0);box2d.b2EPCollider.prototype.m_v1=null;goog.exportProperty(box2d.b2EPCollider.prototype,\"m_v1\",box2d.b2EPCollider.prototype.m_v1);box2d.b2EPCollider.prototype.m_v2=null;goog.exportProperty(box2d.b2EPCollider.prototype,\"m_v2\",box2d.b2EPCollider.prototype.m_v2);box2d.b2EPCollider.prototype.m_v3=null;goog.exportProperty(box2d.b2EPCollider.prototype,\"m_v3\",box2d.b2EPCollider.prototype.m_v3);\nbox2d.b2EPCollider.prototype.m_normal0=null;goog.exportProperty(box2d.b2EPCollider.prototype,\"m_normal0\",box2d.b2EPCollider.prototype.m_normal0);box2d.b2EPCollider.prototype.m_normal1=null;goog.exportProperty(box2d.b2EPCollider.prototype,\"m_normal1\",box2d.b2EPCollider.prototype.m_normal1);box2d.b2EPCollider.prototype.m_normal2=null;goog.exportProperty(box2d.b2EPCollider.prototype,\"m_normal2\",box2d.b2EPCollider.prototype.m_normal2);box2d.b2EPCollider.prototype.m_normal=null;\ngoog.exportProperty(box2d.b2EPCollider.prototype,\"m_normal\",box2d.b2EPCollider.prototype.m_normal);box2d.b2EPCollider.prototype.m_type1=box2d.b2EPColliderVertexType.e_isolated;goog.exportProperty(box2d.b2EPCollider.prototype,\"m_type1\",box2d.b2EPCollider.prototype.m_type1);box2d.b2EPCollider.prototype.m_type2=box2d.b2EPColliderVertexType.e_isolated;goog.exportProperty(box2d.b2EPCollider.prototype,\"m_type2\",box2d.b2EPCollider.prototype.m_type2);box2d.b2EPCollider.prototype.m_lowerLimit=null;\ngoog.exportProperty(box2d.b2EPCollider.prototype,\"m_lowerLimit\",box2d.b2EPCollider.prototype.m_lowerLimit);box2d.b2EPCollider.prototype.m_upperLimit=null;goog.exportProperty(box2d.b2EPCollider.prototype,\"m_upperLimit\",box2d.b2EPCollider.prototype.m_upperLimit);box2d.b2EPCollider.prototype.m_radius=0;goog.exportProperty(box2d.b2EPCollider.prototype,\"m_radius\",box2d.b2EPCollider.prototype.m_radius);box2d.b2EPCollider.prototype.m_front=!1;goog.exportProperty(box2d.b2EPCollider.prototype,\"m_front\",box2d.b2EPCollider.prototype.m_front);\nbox2d.b2EPCollider.prototype.Collide=function(a,b,c,e,d){box2d.b2MulTXX(c,d,this.m_xf);box2d.b2MulXV(this.m_xf,e.m_centroid,this.m_centroidB);this.m_v0.Copy(b.m_vertex0);this.m_v1.Copy(b.m_vertex1);this.m_v2.Copy(b.m_vertex2);this.m_v3.Copy(b.m_vertex3);c=b.m_hasVertex0;b=b.m_hasVertex3;d=box2d.b2SubVV(this.m_v2,this.m_v1,box2d.b2EPCollider.s_edge1);d.Normalize();this.m_normal1.SetXY(d.y,-d.x);var f=box2d.b2DotVV(this.m_normal1,box2d.b2SubVV(this.m_centroidB,this.m_v1,box2d.b2Vec2.s_t0)),g=0,h=0,\nl=!1,k=!1;c&&(g=box2d.b2SubVV(this.m_v1,this.m_v0,box2d.b2EPCollider.s_edge0),g.Normalize(),this.m_normal0.SetXY(g.y,-g.x),l=0<=box2d.b2CrossVV(g,d),g=box2d.b2DotVV(this.m_normal0,box2d.b2SubVV(this.m_centroidB,this.m_v0,box2d.b2Vec2.s_t0)));b&&(h=box2d.b2SubVV(this.m_v3,this.m_v2,box2d.b2EPCollider.s_edge2),h.Normalize(),this.m_normal2.SetXY(h.y,-h.x),k=0<box2d.b2CrossVV(d,h),h=box2d.b2DotVV(this.m_normal2,box2d.b2SubVV(this.m_centroidB,this.m_v2,box2d.b2Vec2.s_t0)));c&&b?l&&k?(this.m_front=0<=g||\n0<=f||0<=h)?(this.m_normal.Copy(this.m_normal1),this.m_lowerLimit.Copy(this.m_normal0),this.m_upperLimit.Copy(this.m_normal2)):(this.m_normal.Copy(this.m_normal1).SelfNeg(),this.m_lowerLimit.Copy(this.m_normal1).SelfNeg(),this.m_upperLimit.Copy(this.m_normal1).SelfNeg()):l?(this.m_front=0<=g||0<=f&&0<=h)?(this.m_normal.Copy(this.m_normal1),this.m_lowerLimit.Copy(this.m_normal0),this.m_upperLimit.Copy(this.m_normal1)):(this.m_normal.Copy(this.m_normal1).SelfNeg(),this.m_lowerLimit.Copy(this.m_normal2).SelfNeg(),\nthis.m_upperLimit.Copy(this.m_normal1).SelfNeg()):k?(this.m_front=0<=h||0<=g&&0<=f)?(this.m_normal.Copy(this.m_normal1),this.m_lowerLimit.Copy(this.m_normal1),this.m_upperLimit.Copy(this.m_normal2)):(this.m_normal.Copy(this.m_normal1).SelfNeg(),this.m_lowerLimit.Copy(this.m_normal1).SelfNeg(),this.m_upperLimit.Copy(this.m_normal0).SelfNeg()):(this.m_front=0<=g&&0<=f&&0<=h)?(this.m_normal.Copy(this.m_normal1),this.m_lowerLimit.Copy(this.m_normal1),this.m_upperLimit.Copy(this.m_normal1)):(this.m_normal.Copy(this.m_normal1).SelfNeg(),\nthis.m_lowerLimit.Copy(this.m_normal2).SelfNeg(),this.m_upperLimit.Copy(this.m_normal0).SelfNeg()):c?l?((this.m_front=0<=g||0<=f)?(this.m_normal.Copy(this.m_normal1),this.m_lowerLimit.Copy(this.m_normal0)):(this.m_normal.Copy(this.m_normal1).SelfNeg(),this.m_lowerLimit.Copy(this.m_normal1)),this.m_upperLimit.Copy(this.m_normal1).SelfNeg()):(this.m_front=0<=g&&0<=f)?(this.m_normal.Copy(this.m_normal1),this.m_lowerLimit.Copy(this.m_normal1),this.m_upperLimit.Copy(this.m_normal1).SelfNeg()):(this.m_normal.Copy(this.m_normal1).SelfNeg(),\nthis.m_lowerLimit.Copy(this.m_normal1),this.m_upperLimit.Copy(this.m_normal0).SelfNeg()):b?k?(this.m_front=0<=f||0<=h)?(this.m_normal.Copy(this.m_normal1),this.m_lowerLimit.Copy(this.m_normal1).SelfNeg(),this.m_upperLimit.Copy(this.m_normal2)):(this.m_normal.Copy(this.m_normal1).SelfNeg(),this.m_lowerLimit.Copy(this.m_normal1).SelfNeg(),this.m_upperLimit.Copy(this.m_normal1)):((this.m_front=0<=f&&0<=h)?(this.m_normal.Copy(this.m_normal1),this.m_lowerLimit.Copy(this.m_normal1).SelfNeg()):(this.m_normal.Copy(this.m_normal1).SelfNeg(),\nthis.m_lowerLimit.Copy(this.m_normal2).SelfNeg()),this.m_upperLimit.Copy(this.m_normal1)):(this.m_front=0<=f)?(this.m_normal.Copy(this.m_normal1),this.m_lowerLimit.Copy(this.m_normal1).SelfNeg(),this.m_upperLimit.Copy(this.m_normal1).SelfNeg()):(this.m_normal.Copy(this.m_normal1).SelfNeg(),this.m_lowerLimit.Copy(this.m_normal1),this.m_upperLimit.Copy(this.m_normal1));this.m_polygonB.count=e.m_count;f=0;for(g=e.m_count;f<g;++f)box2d.b2MulXV(this.m_xf,e.m_vertices[f],this.m_polygonB.vertices[f]),box2d.b2MulRV(this.m_xf.q,\ne.m_normals[f],this.m_polygonB.normals[f]);this.m_radius=2*box2d.b2_polygonRadius;a.pointCount=0;c=this.ComputeEdgeSeparation(box2d.b2EPCollider.s_edgeAxis);if(!(c.type===box2d.b2EPAxisType.e_unknown||c.separation>this.m_radius||(b=this.ComputePolygonSeparation(box2d.b2EPCollider.s_polygonAxis),b.type!==box2d.b2EPAxisType.e_unknown&&b.separation>this.m_radius))){c=b.type===box2d.b2EPAxisType.e_unknown?c:b.separation>0.98*c.separation+0.001?b:c;d=box2d.b2EPCollider.s_ie;b=box2d.b2EPCollider.s_rf;if(c.type===\nbox2d.b2EPAxisType.e_edgeA){a.type=box2d.b2ManifoldType.e_faceA;h=0;l=box2d.b2DotVV(this.m_normal,this.m_polygonB.normals[0]);f=1;for(g=this.m_polygonB.count;f<g;++f)k=box2d.b2DotVV(this.m_normal,this.m_polygonB.normals[f]),k<l&&(l=k,h=f);g=h;f=(g+1)%this.m_polygonB.count;h=d[0];h.v.Copy(this.m_polygonB.vertices[g]);h.id.cf.indexA=0;h.id.cf.indexB=g;h.id.cf.typeA=box2d.b2ContactFeatureType.e_face;h.id.cf.typeB=box2d.b2ContactFeatureType.e_vertex;g=d[1];g.v.Copy(this.m_polygonB.vertices[f]);g.id.cf.indexA=\n0;g.id.cf.indexB=f;g.id.cf.typeA=box2d.b2ContactFeatureType.e_face;g.id.cf.typeB=box2d.b2ContactFeatureType.e_vertex;this.m_front?(b.i1=0,b.i2=1,b.v1.Copy(this.m_v1),b.v2.Copy(this.m_v2),b.normal.Copy(this.m_normal1)):(b.i1=1,b.i2=0,b.v1.Copy(this.m_v2),b.v2.Copy(this.m_v1),b.normal.Copy(this.m_normal1).SelfNeg())}else a.type=box2d.b2ManifoldType.e_faceB,h=d[0],h.v.Copy(this.m_v1),h.id.cf.indexA=0,h.id.cf.indexB=c.index,h.id.cf.typeA=box2d.b2ContactFeatureType.e_vertex,h.id.cf.typeB=box2d.b2ContactFeatureType.e_face,\ng=d[1],g.v.Copy(this.m_v2),g.id.cf.indexA=0,g.id.cf.indexB=c.index,g.id.cf.typeA=box2d.b2ContactFeatureType.e_vertex,g.id.cf.typeB=box2d.b2ContactFeatureType.e_face,b.i1=c.index,b.i2=(b.i1+1)%this.m_polygonB.count,b.v1.Copy(this.m_polygonB.vertices[b.i1]),b.v2.Copy(this.m_polygonB.vertices[b.i2]),b.normal.Copy(this.m_polygonB.normals[b.i1]);b.sideNormal1.SetXY(b.normal.y,-b.normal.x);b.sideNormal2.Copy(b.sideNormal1).SelfNeg();b.sideOffset1=box2d.b2DotVV(b.sideNormal1,b.v1);b.sideOffset2=box2d.b2DotVV(b.sideNormal2,\nb.v2);f=box2d.b2EPCollider.s_clipPoints1;h=box2d.b2EPCollider.s_clipPoints2;g=0;g=box2d.b2ClipSegmentToLine(f,d,b.sideNormal1,b.sideOffset1,b.i1);if(!(g<box2d.b2_maxManifoldPoints||(g=box2d.b2ClipSegmentToLine(h,f,b.sideNormal2,b.sideOffset2,b.i2),g<box2d.b2_maxManifoldPoints))){c.type===box2d.b2EPAxisType.e_edgeA?(a.localNormal.Copy(b.normal),a.localPoint.Copy(b.v1)):(a.localNormal.Copy(e.m_normals[b.i1]),a.localPoint.Copy(e.m_vertices[b.i1]));f=e=0;for(g=box2d.b2_maxManifoldPoints;f<g;++f)box2d.b2DotVV(b.normal,\nbox2d.b2SubVV(h[f].v,b.v1,box2d.b2Vec2.s_t0))<=this.m_radius&&(d=a.points[e],c.type===box2d.b2EPAxisType.e_edgeA?(box2d.b2MulTXV(this.m_xf,h[f].v,d.localPoint),d.id=h[f].id):(d.localPoint.Copy(h[f].v),d.id.cf.typeA=h[f].id.cf.typeB,d.id.cf.typeB=h[f].id.cf.typeA,d.id.cf.indexA=h[f].id.cf.indexB,d.id.cf.indexB=h[f].id.cf.indexA),++e);a.pointCount=e}}};goog.exportProperty(box2d.b2EPCollider.prototype,\"Collide\",box2d.b2EPCollider.prototype.Collide);box2d.b2EPCollider.s_edge1=new box2d.b2Vec2;\nbox2d.b2EPCollider.s_edge0=new box2d.b2Vec2;box2d.b2EPCollider.s_edge2=new box2d.b2Vec2;box2d.b2EPCollider.s_ie=box2d.b2ClipVertex.MakeArray(2);box2d.b2EPCollider.s_rf=new box2d.b2ReferenceFace;box2d.b2EPCollider.s_clipPoints1=box2d.b2ClipVertex.MakeArray(2);box2d.b2EPCollider.s_clipPoints2=box2d.b2ClipVertex.MakeArray(2);box2d.b2EPCollider.s_edgeAxis=new box2d.b2EPAxis;box2d.b2EPCollider.s_polygonAxis=new box2d.b2EPAxis;\nbox2d.b2EPCollider.prototype.ComputeEdgeSeparation=function(a){a.type=box2d.b2EPAxisType.e_edgeA;a.index=this.m_front?0:1;a.separation=box2d.b2_maxFloat;for(var b=0,c=this.m_polygonB.count;b<c;++b){var e=box2d.b2DotVV(this.m_normal,box2d.b2SubVV(this.m_polygonB.vertices[b],this.m_v1,box2d.b2Vec2.s_t0));e<a.separation&&(a.separation=e)}return a};goog.exportProperty(box2d.b2EPCollider.prototype,\"ComputeEdgeSeparation\",box2d.b2EPCollider.prototype.ComputeEdgeSeparation);\nbox2d.b2EPCollider.prototype.ComputePolygonSeparation=function(a){a.type=box2d.b2EPAxisType.e_unknown;a.index=-1;a.separation=-box2d.b2_maxFloat;for(var b=box2d.b2EPCollider.s_perp.SetXY(-this.m_normal.y,this.m_normal.x),c=0,e=this.m_polygonB.count;c<e;++c){var d=box2d.b2NegV(this.m_polygonB.normals[c],box2d.b2EPCollider.s_n),f=box2d.b2DotVV(d,box2d.b2SubVV(this.m_polygonB.vertices[c],this.m_v1,box2d.b2Vec2.s_t0)),g=box2d.b2DotVV(d,box2d.b2SubVV(this.m_polygonB.vertices[c],this.m_v2,box2d.b2Vec2.s_t0)),\nf=box2d.b2Min(f,g);if(f>this.m_radius){a.type=box2d.b2EPAxisType.e_edgeB;a.index=c;a.separation=f;break}if(0<=box2d.b2DotVV(d,b)){if(box2d.b2DotVV(box2d.b2SubVV(d,this.m_upperLimit,box2d.b2Vec2.s_t0),this.m_normal)<-box2d.b2_angularSlop)continue}else if(box2d.b2DotVV(box2d.b2SubVV(d,this.m_lowerLimit,box2d.b2Vec2.s_t0),this.m_normal)<-box2d.b2_angularSlop)continue;f>a.separation&&(a.type=box2d.b2EPAxisType.e_edgeB,a.index=c,a.separation=f)}return a};\ngoog.exportProperty(box2d.b2EPCollider.prototype,\"ComputePolygonSeparation\",box2d.b2EPCollider.prototype.ComputePolygonSeparation);box2d.b2EPCollider.s_n=new box2d.b2Vec2;box2d.b2EPCollider.s_perp=new box2d.b2Vec2;box2d.b2CollideEdgeAndPolygon=function(a,b,c,e,d){box2d.b2CollideEdgeAndPolygon.s_collider.Collide(a,b,c,e,d)};goog.exportSymbol(\"box2d.b2CollideEdgeAndPolygon\",box2d.b2CollideEdgeAndPolygon);box2d.b2CollideEdgeAndPolygon.s_collider=new box2d.b2EPCollider;box2d.b2EdgeShape=function(){box2d.b2Shape.call(this,box2d.b2ShapeType.e_edgeShape,box2d.b2_polygonRadius);this.m_vertex1=new box2d.b2Vec2;this.m_vertex2=new box2d.b2Vec2;this.m_vertex0=new box2d.b2Vec2;this.m_vertex3=new box2d.b2Vec2};goog.inherits(box2d.b2EdgeShape,box2d.b2Shape);goog.exportSymbol(\"box2d.b2EdgeShape\",box2d.b2EdgeShape);box2d.b2EdgeShape.prototype.m_vertex1=null;goog.exportProperty(box2d.b2EdgeShape.prototype,\"m_vertex1\",box2d.b2EdgeShape.prototype.m_vertex1);\nbox2d.b2EdgeShape.prototype.m_vertex2=null;goog.exportProperty(box2d.b2EdgeShape.prototype,\"m_vertex2\",box2d.b2EdgeShape.prototype.m_vertex2);box2d.b2EdgeShape.prototype.m_vertex0=null;goog.exportProperty(box2d.b2EdgeShape.prototype,\"m_vertex0\",box2d.b2EdgeShape.prototype.m_vertex0);box2d.b2EdgeShape.prototype.m_vertex3=null;goog.exportProperty(box2d.b2EdgeShape.prototype,\"m_vertex3\",box2d.b2EdgeShape.prototype.m_vertex3);box2d.b2EdgeShape.prototype.m_hasVertex0=!1;\ngoog.exportProperty(box2d.b2EdgeShape.prototype,\"m_hasVertex0\",box2d.b2EdgeShape.prototype.m_hasVertex0);box2d.b2EdgeShape.prototype.m_hasVertex3=!1;goog.exportProperty(box2d.b2EdgeShape.prototype,\"m_hasVertex3\",box2d.b2EdgeShape.prototype.m_hasVertex3);box2d.b2EdgeShape.prototype.Set=function(a,b){this.m_vertex1.Copy(a);this.m_vertex2.Copy(b);this.m_hasVertex3=this.m_hasVertex0=!1;return this};goog.exportProperty(box2d.b2EdgeShape.prototype,\"Set\",box2d.b2EdgeShape.prototype.Set);\nbox2d.b2EdgeShape.prototype.SetAsEdge=box2d.b2EdgeShape.prototype.Set;box2d.b2EdgeShape.prototype.Clone=function(){return(new box2d.b2EdgeShape).Copy(this)};goog.exportProperty(box2d.b2EdgeShape.prototype,\"Clone\",box2d.b2EdgeShape.prototype.Clone);\nbox2d.b2EdgeShape.prototype.Copy=function(a){box2d.b2EdgeShape.superClass_.Copy.call(this,a);box2d.ENABLE_ASSERTS&&box2d.b2Assert(a instanceof box2d.b2EdgeShape);this.m_vertex1.Copy(a.m_vertex1);this.m_vertex2.Copy(a.m_vertex2);this.m_vertex0.Copy(a.m_vertex0);this.m_vertex3.Copy(a.m_vertex3);this.m_hasVertex0=a.m_hasVertex0;this.m_hasVertex3=a.m_hasVertex3;return this};goog.exportProperty(box2d.b2EdgeShape.prototype,\"Copy\",box2d.b2EdgeShape.prototype.Copy);\nbox2d.b2EdgeShape.prototype.GetChildCount=function(){return 1};goog.exportProperty(box2d.b2EdgeShape.prototype,\"GetChildCount\",box2d.b2EdgeShape.prototype.GetChildCount);box2d.b2EdgeShape.prototype.TestPoint=function(a,b){return!1};goog.exportProperty(box2d.b2EdgeShape.prototype,\"TestPoint\",box2d.b2EdgeShape.prototype.TestPoint);\nbox2d.b2EdgeShape.prototype.RayCast=function(a,b,c,e){var d=box2d.b2MulTXV(c,b.p1,box2d.b2EdgeShape.prototype.RayCast.s_p1);e=box2d.b2MulTXV(c,b.p2,box2d.b2EdgeShape.prototype.RayCast.s_p2);var f=box2d.b2SubVV(e,d,box2d.b2EdgeShape.prototype.RayCast.s_d);e=this.m_vertex1;var g=this.m_vertex2,h=box2d.b2SubVV(g,e,box2d.b2EdgeShape.prototype.RayCast.s_e),l=a.normal.SetXY(h.y,-h.x).SelfNormalize(),h=box2d.b2DotVV(l,box2d.b2SubVV(e,d,box2d.b2Vec2.s_t0)),l=box2d.b2DotVV(l,f);if(0===l)return!1;l=h/l;if(0>\nl||b.maxFraction<l)return!1;b=box2d.b2AddVMulSV(d,l,f,box2d.b2EdgeShape.prototype.RayCast.s_q);d=box2d.b2SubVV(g,e,box2d.b2EdgeShape.prototype.RayCast.s_r);g=box2d.b2DotVV(d,d);if(0===g)return!1;e=box2d.b2DotVV(box2d.b2SubVV(b,e,box2d.b2Vec2.s_t0),d)/g;if(0>e||1<e)return!1;a.fraction=l;box2d.b2MulRV(c.q,a.normal,a.normal);0<h&&a.normal.SelfNeg();return!0};goog.exportProperty(box2d.b2EdgeShape.prototype,\"RayCast\",box2d.b2EdgeShape.prototype.RayCast);box2d.b2EdgeShape.prototype.RayCast.s_p1=new box2d.b2Vec2;\nbox2d.b2EdgeShape.prototype.RayCast.s_p2=new box2d.b2Vec2;box2d.b2EdgeShape.prototype.RayCast.s_d=new box2d.b2Vec2;box2d.b2EdgeShape.prototype.RayCast.s_e=new box2d.b2Vec2;box2d.b2EdgeShape.prototype.RayCast.s_q=new box2d.b2Vec2;box2d.b2EdgeShape.prototype.RayCast.s_r=new box2d.b2Vec2;\nbox2d.b2EdgeShape.prototype.ComputeAABB=function(a,b,c){c=box2d.b2MulXV(b,this.m_vertex1,box2d.b2EdgeShape.prototype.ComputeAABB.s_v1);b=box2d.b2MulXV(b,this.m_vertex2,box2d.b2EdgeShape.prototype.ComputeAABB.s_v2);box2d.b2MinV(c,b,a.lowerBound);box2d.b2MaxV(c,b,a.upperBound);b=this.m_radius;a.lowerBound.SelfSubXY(b,b);a.upperBound.SelfAddXY(b,b)};goog.exportProperty(box2d.b2EdgeShape.prototype,\"ComputeAABB\",box2d.b2EdgeShape.prototype.ComputeAABB);box2d.b2EdgeShape.prototype.ComputeAABB.s_v1=new box2d.b2Vec2;\nbox2d.b2EdgeShape.prototype.ComputeAABB.s_v2=new box2d.b2Vec2;box2d.b2EdgeShape.prototype.ComputeMass=function(a,b){a.mass=0;box2d.b2MidVV(this.m_vertex1,this.m_vertex2,a.center);a.I=0};goog.exportProperty(box2d.b2EdgeShape.prototype,\"ComputeMass\",box2d.b2EdgeShape.prototype.ComputeMass);box2d.b2EdgeShape.prototype.SetupDistanceProxy=function(a,b){a.m_vertices=Array(2);a.m_vertices[0]=this.m_vertex1;a.m_vertices[1]=this.m_vertex2;a.m_count=2;a.m_radius=this.m_radius};\nbox2d.b2EdgeShape.prototype.ComputeSubmergedArea=function(a,b,c,e){e.SetZero();return 0};goog.exportProperty(box2d.b2EdgeShape.prototype,\"ComputeSubmergedArea\",box2d.b2EdgeShape.prototype.ComputeSubmergedArea);\nbox2d.b2EdgeShape.prototype.Dump=function(){box2d.b2Log(\"    /*box2d.b2EdgeShape*/ var shape = new box2d.b2EdgeShape();\\n\");box2d.b2Log(\"    shape.m_radius = %.15f;\\n\",this.m_radius);box2d.b2Log(\"    shape.m_vertex0.SetXY(%.15f, %.15f);\\n\",this.m_vertex0.x,this.m_vertex0.y);box2d.b2Log(\"    shape.m_vertex1.SetXY(%.15f, %.15f);\\n\",this.m_vertex1.x,this.m_vertex1.y);box2d.b2Log(\"    shape.m_vertex2.SetXY(%.15f, %.15f);\\n\",this.m_vertex2.x,this.m_vertex2.y);box2d.b2Log(\"    shape.m_vertex3.SetXY(%.15f, %.15f);\\n\",\nthis.m_vertex3.x,this.m_vertex3.y);box2d.b2Log(\"    shape.m_hasVertex0 = %s;\\n\",this.m_hasVertex0);box2d.b2Log(\"    shape.m_hasVertex3 = %s;\\n\",this.m_hasVertex3)};goog.exportProperty(box2d.b2EdgeShape.prototype,\"Dump\",box2d.b2EdgeShape.prototype.Dump);box2d.b2ChainShape=function(){box2d.b2Shape.call(this,box2d.b2ShapeType.e_chainShape,box2d.b2_polygonRadius);this.m_prevVertex=new box2d.b2Vec2;this.m_nextVertex=new box2d.b2Vec2};goog.inherits(box2d.b2ChainShape,box2d.b2Shape);goog.exportSymbol(\"box2d.b2ChainShape\",box2d.b2ChainShape);box2d.b2ChainShape.prototype.m_vertices=null;goog.exportProperty(box2d.b2ChainShape.prototype,\"m_vertices\",box2d.b2ChainShape.prototype.m_vertices);box2d.b2ChainShape.prototype.m_count=0;\ngoog.exportProperty(box2d.b2ChainShape.prototype,\"m_count\",box2d.b2ChainShape.prototype.m_count);box2d.b2ChainShape.prototype.m_prevVertex=null;goog.exportProperty(box2d.b2ChainShape.prototype,\"m_prevVertex\",box2d.b2ChainShape.prototype.m_prevVertex);box2d.b2ChainShape.prototype.m_nextVertex=null;goog.exportProperty(box2d.b2ChainShape.prototype,\"m_nextVertex\",box2d.b2ChainShape.prototype.m_nextVertex);box2d.b2ChainShape.prototype.m_hasPrevVertex=!1;\ngoog.exportProperty(box2d.b2ChainShape.prototype,\"m_hasPrevVertex\",box2d.b2ChainShape.prototype.m_hasPrevVertex);box2d.b2ChainShape.prototype.m_hasNextVertex=!1;goog.exportProperty(box2d.b2ChainShape.prototype,\"m_hasNextVertex\",box2d.b2ChainShape.prototype.m_hasNextVertex);\nbox2d.b2ChainShape.prototype.CreateLoop=function(a,b){b=b||a.length;box2d.ENABLE_ASSERTS&&box2d.b2Assert(null===this.m_vertices&&0===this.m_count);box2d.ENABLE_ASSERTS&&box2d.b2Assert(3<=b);if(box2d.ENABLE_ASSERTS)for(var c=1;c<b;++c)box2d.b2Assert(box2d.b2DistanceSquaredVV(a[c-1],a[c])>box2d.b2_linearSlop*box2d.b2_linearSlop);this.m_count=b+1;this.m_vertices=box2d.b2Vec2.MakeArray(this.m_count);for(c=0;c<b;++c)this.m_vertices[c].Copy(a[c]);this.m_vertices[b].Copy(this.m_vertices[0]);this.m_prevVertex.Copy(this.m_vertices[this.m_count-\n2]);this.m_nextVertex.Copy(this.m_vertices[1]);this.m_hasNextVertex=this.m_hasPrevVertex=!0;return this};goog.exportProperty(box2d.b2ChainShape.prototype,\"CreateLoop\",box2d.b2ChainShape.prototype.CreateLoop);\nbox2d.b2ChainShape.prototype.CreateChain=function(a,b){b=b||a.length;box2d.ENABLE_ASSERTS&&box2d.b2Assert(null===this.m_vertices&&0===this.m_count);box2d.ENABLE_ASSERTS&&box2d.b2Assert(2<=b);if(box2d.ENABLE_ASSERTS)for(var c=1;c<b;++c)box2d.b2Assert(box2d.b2DistanceSquaredVV(a[c-1],a[c])>box2d.b2_linearSlop*box2d.b2_linearSlop);this.m_count=b;this.m_vertices=box2d.b2Vec2.MakeArray(b);for(c=0;c<b;++c)this.m_vertices[c].Copy(a[c]);this.m_hasNextVertex=this.m_hasPrevVertex=!1;this.m_prevVertex.SetZero();\nthis.m_nextVertex.SetZero();return this};goog.exportProperty(box2d.b2ChainShape.prototype,\"CreateChain\",box2d.b2ChainShape.prototype.CreateChain);box2d.b2ChainShape.prototype.SetPrevVertex=function(a){this.m_prevVertex.Copy(a);this.m_hasPrevVertex=!0;return this};goog.exportProperty(box2d.b2ChainShape.prototype,\"SetPrevVertex\",box2d.b2ChainShape.prototype.SetPrevVertex);box2d.b2ChainShape.prototype.SetNextVertex=function(a){this.m_nextVertex.Copy(a);this.m_hasNextVertex=!0;return this};\ngoog.exportProperty(box2d.b2ChainShape.prototype,\"SetNextVertex\",box2d.b2ChainShape.prototype.SetNextVertex);box2d.b2ChainShape.prototype.Clone=function(){return(new box2d.b2ChainShape).Copy(this)};goog.exportProperty(box2d.b2ChainShape.prototype,\"Clone\",box2d.b2ChainShape.prototype.Clone);\nbox2d.b2ChainShape.prototype.Copy=function(a){box2d.b2ChainShape.superClass_.Copy.call(this,a);box2d.ENABLE_ASSERTS&&box2d.b2Assert(a instanceof box2d.b2ChainShape);this.CreateChain(a.m_vertices,a.m_count);this.m_prevVertex.Copy(a.m_prevVertex);this.m_nextVertex.Copy(a.m_nextVertex);this.m_hasPrevVertex=a.m_hasPrevVertex;this.m_hasNextVertex=a.m_hasNextVertex;return this};goog.exportProperty(box2d.b2ChainShape.prototype,\"Copy\",box2d.b2ChainShape.prototype.Copy);\nbox2d.b2ChainShape.prototype.GetChildCount=function(){return this.m_count-1};goog.exportProperty(box2d.b2ChainShape.prototype,\"GetChildCount\",box2d.b2ChainShape.prototype.GetChildCount);\nbox2d.b2ChainShape.prototype.GetChildEdge=function(a,b){box2d.ENABLE_ASSERTS&&box2d.b2Assert(0<=b&&b<this.m_count-1);a.m_type=box2d.b2ShapeType.e_edgeShape;a.m_radius=this.m_radius;a.m_vertex1.Copy(this.m_vertices[b]);a.m_vertex2.Copy(this.m_vertices[b+1]);0<b?(a.m_vertex0.Copy(this.m_vertices[b-1]),a.m_hasVertex0=!0):(a.m_vertex0.Copy(this.m_prevVertex),a.m_hasVertex0=this.m_hasPrevVertex);b<this.m_count-2?(a.m_vertex3.Copy(this.m_vertices[b+2]),a.m_hasVertex3=!0):(a.m_vertex3.Copy(this.m_nextVertex),\na.m_hasVertex3=this.m_hasNextVertex)};goog.exportProperty(box2d.b2ChainShape.prototype,\"GetChildEdge\",box2d.b2ChainShape.prototype.GetChildEdge);box2d.b2ChainShape.prototype.TestPoint=function(a,b){return!1};goog.exportProperty(box2d.b2ChainShape.prototype,\"TestPoint\",box2d.b2ChainShape.prototype.TestPoint);\nbox2d.b2ChainShape.prototype.RayCast=function(a,b,c,e){box2d.ENABLE_ASSERTS&&box2d.b2Assert(e<this.m_count);var d=box2d.b2ChainShape.s_edgeShape;d.m_vertex1.Copy(this.m_vertices[e]);d.m_vertex2.Copy(this.m_vertices[(e+1)%this.m_count]);return d.RayCast(a,b,c,0)};goog.exportProperty(box2d.b2ChainShape.prototype,\"RayCast\",box2d.b2ChainShape.prototype.RayCast);box2d.b2ChainShape.s_edgeShape=new box2d.b2EdgeShape;goog.exportProperty(box2d.b2ChainShape,\"s_edgeShape\",box2d.b2ChainShape.s_edgeShape);\nbox2d.b2ChainShape.prototype.ComputeAABB=function(a,b,c){box2d.ENABLE_ASSERTS&&box2d.b2Assert(c<this.m_count);var e=this.m_vertices[(c+1)%this.m_count];c=box2d.b2MulXV(b,this.m_vertices[c],box2d.b2ChainShape.prototype.ComputeAABB.s_v1);b=box2d.b2MulXV(b,e,box2d.b2ChainShape.prototype.ComputeAABB.s_v2);box2d.b2MinV(c,b,a.lowerBound);box2d.b2MaxV(c,b,a.upperBound)};goog.exportProperty(box2d.b2ChainShape.prototype,\"ComputeAABB\",box2d.b2ChainShape.prototype.ComputeAABB);\nbox2d.b2ChainShape.prototype.ComputeAABB.s_v1=new box2d.b2Vec2;goog.exportProperty(box2d.b2ChainShape.prototype.ComputeAABB,\"s_v1\",box2d.b2ChainShape.prototype.ComputeAABB.s_v1);box2d.b2ChainShape.prototype.ComputeAABB.s_v2=new box2d.b2Vec2;goog.exportProperty(box2d.b2ChainShape.prototype.ComputeAABB,\"s_v2\",box2d.b2ChainShape.prototype.ComputeAABB.s_v2);box2d.b2ChainShape.prototype.ComputeMass=function(a,b){a.mass=0;a.center.SetZero();a.I=0};\ngoog.exportProperty(box2d.b2ChainShape.prototype,\"ComputeMass\",box2d.b2ChainShape.prototype.ComputeMass);box2d.b2ChainShape.prototype.SetupDistanceProxy=function(a,b){box2d.ENABLE_ASSERTS&&box2d.b2Assert(0<=b&&b<this.m_count);a.m_buffer[0].Copy(this.m_vertices[b]);b+1<this.m_count?a.m_buffer[1].Copy(this.m_vertices[b+1]):a.m_buffer[1].Copy(this.m_vertices[0]);a.m_vertices=a.m_buffer;a.m_count=2;a.m_radius=this.m_radius};\nbox2d.b2ChainShape.prototype.ComputeSubmergedArea=function(a,b,c,e){e.SetZero();return 0};goog.exportProperty(box2d.b2ChainShape.prototype,\"ComputeSubmergedArea\",box2d.b2ChainShape.prototype.ComputeSubmergedArea);\nbox2d.b2ChainShape.prototype.Dump=function(){box2d.b2Log(\"    /*box2d.b2ChainShape*/ var shape = new box2d.b2ChainShape();\\n\");box2d.b2Log(\"    /*box2d.b2Vec2[]*/ var vs = box2d.b2Vec2.MakeArray(%d);\\n\",box2d.b2_maxPolygonVertices);for(var a=0;a<this.m_count;++a)box2d.b2Log(\"    vs[%d].SetXY(%.15f, %.15f);\\n\",a,this.m_vertices[a].x,this.m_vertices[a].y);box2d.b2Log(\"    shape.CreateChain(vs, %d);\\n\",this.m_count);box2d.b2Log(\"    shape.m_prevVertex.SetXY(%.15f, %.15f);\\n\",this.m_prevVertex.x,this.m_prevVertex.y);\nbox2d.b2Log(\"    shape.m_nextVertex.SetXY(%.15f, %.15f);\\n\",this.m_nextVertex.x,this.m_nextVertex.y);box2d.b2Log(\"    shape.m_hasPrevVertex = %s;\\n\",this.m_hasPrevVertex?\"true\":\"false\");box2d.b2Log(\"    shape.m_hasNextVertex = %s;\\n\",this.m_hasNextVertex?\"true\":\"false\")};goog.exportProperty(box2d.b2ChainShape.prototype,\"Dump\",box2d.b2ChainShape.prototype.Dump);box2d.b2ChainAndPolygonContact=function(){box2d.b2Contact.call(this)};goog.inherits(box2d.b2ChainAndPolygonContact,box2d.b2Contact);goog.exportSymbol(\"box2d.b2ChainAndPolygonContact\",box2d.b2ChainAndPolygonContact);box2d.b2ChainAndPolygonContact.Create=function(a){return new box2d.b2ChainAndPolygonContact};goog.exportProperty(box2d.b2ChainAndPolygonContact,\"Create\",box2d.b2ChainAndPolygonContact.Create);box2d.b2ChainAndPolygonContact.Destroy=function(a,b){};\ngoog.exportProperty(box2d.b2ChainAndPolygonContact,\"Destroy\",box2d.b2ChainAndPolygonContact.Destroy);box2d.b2ChainAndPolygonContact.prototype.Reset=function(a,b,c,e){box2d.b2ChainAndPolygonContact.superClass_.Reset.call(this,a,b,c,e);box2d.ENABLE_ASSERTS&&box2d.b2Assert(a.GetType()===box2d.b2ShapeType.e_chainShape);box2d.ENABLE_ASSERTS&&box2d.b2Assert(c.GetType()===box2d.b2ShapeType.e_polygonShape)};goog.exportProperty(box2d.b2ChainAndPolygonContact.prototype,\"Reset\",box2d.b2ChainAndPolygonContact.prototype.Reset);\nbox2d.b2ChainAndPolygonContact.prototype.Evaluate=function(a,b,c){var e=this.m_fixtureA.GetShape(),d=this.m_fixtureB.GetShape();box2d.ENABLE_ASSERTS&&box2d.b2Assert(e instanceof box2d.b2ChainShape);box2d.ENABLE_ASSERTS&&box2d.b2Assert(d instanceof box2d.b2PolygonShape);var f=box2d.b2ChainAndPolygonContact.prototype.Evaluate.s_edge;(e instanceof box2d.b2ChainShape?e:null).GetChildEdge(f,this.m_indexA);box2d.b2CollideEdgeAndPolygon(a,f,b,d instanceof box2d.b2PolygonShape?d:null,c)};\ngoog.exportProperty(box2d.b2ChainAndPolygonContact.prototype,\"Evaluate\",box2d.b2ChainAndPolygonContact.prototype.Evaluate);box2d.b2ChainAndPolygonContact.prototype.Evaluate.s_edge=new box2d.b2EdgeShape;box2d.b2CollidePolygon={};box2d.b2FindMaxSeparation=function(a,b,c,e,d){var f=b.m_count,g=e.m_count,h=b.m_normals;b=b.m_vertices;e=e.m_vertices;c=box2d.b2MulTXX(d,c,box2d.b2FindMaxSeparation.s_xf);d=0;for(var l=-box2d.b2_maxFloat,k=0;k<f;++k){for(var m=box2d.b2MulRV(c.q,h[k],box2d.b2FindMaxSeparation.s_n),n=box2d.b2MulXV(c,b[k],box2d.b2FindMaxSeparation.s_v1),p=box2d.b2_maxFloat,q=0;q<g;++q){var r=box2d.b2DotVV(m,box2d.b2SubVV(e[q],n,box2d.b2Vec2.s_t0));r<p&&(p=r)}p>l&&(l=p,d=k)}a[0]=d;return l};\ngoog.exportSymbol(\"box2d.b2FindMaxSeparation\",box2d.b2FindMaxSeparation);box2d.b2FindMaxSeparation.s_xf=new box2d.b2Transform;box2d.b2FindMaxSeparation.s_n=new box2d.b2Vec2;box2d.b2FindMaxSeparation.s_v1=new box2d.b2Vec2;\nbox2d.b2FindIncidentEdge=function(a,b,c,e,d,f){var g=b.m_count,h=b.m_normals,l=d.m_count;b=d.m_vertices;d=d.m_normals;box2d.ENABLE_ASSERTS&&box2d.b2Assert(0<=e&&e<g);c=box2d.b2MulTRV(f.q,box2d.b2MulRV(c.q,h[e],box2d.b2Vec2.s_t0),box2d.b2FindIncidentEdge.s_normal1);for(var g=0,h=box2d.b2_maxFloat,k=0;k<l;++k){var m=box2d.b2DotVV(c,d[k]);m<h&&(h=m,g=k)}d=g;l=(d+1)%l;c=a[0];box2d.b2MulXV(f,b[d],c.v);c=c.id.cf;c.indexA=e;c.indexB=d;c.typeA=box2d.b2ContactFeatureType.e_face;c.typeB=box2d.b2ContactFeatureType.e_vertex;\na=a[1];box2d.b2MulXV(f,b[l],a.v);f=a.id.cf;f.indexA=e;f.indexB=l;f.typeA=box2d.b2ContactFeatureType.e_face;f.typeB=box2d.b2ContactFeatureType.e_vertex};goog.exportSymbol(\"box2d.b2FindIncidentEdge\",box2d.b2FindIncidentEdge);box2d.b2FindIncidentEdge.s_normal1=new box2d.b2Vec2;\nbox2d.b2CollidePolygons=function(a,b,c,e,d){a.pointCount=0;var f=b.m_radius+e.m_radius,g=box2d.b2CollidePolygons.s_edgeA;g[0]=0;var h=box2d.b2FindMaxSeparation(g,b,c,e,d);if(!(h>f)){var l=box2d.b2CollidePolygons.s_edgeB;l[0]=0;var k=box2d.b2FindMaxSeparation(l,e,d,b,c);if(!(k>f)){var m=0,n=0;k>0.98*h+0.001?(h=e,e=b,b=d,m=l[0],a.type=box2d.b2ManifoldType.e_faceB,n=1):(h=b,b=c,c=d,m=g[0],a.type=box2d.b2ManifoldType.e_faceA,n=0);g=box2d.b2CollidePolygons.s_incidentEdge;box2d.b2FindIncidentEdge(g,h,b,\nm,e,c);d=h.m_vertices;var l=m,h=(m+1)%h.m_count,p=d[l],q=d[h],m=box2d.b2SubVV(q,p,box2d.b2CollidePolygons.s_localTangent);m.Normalize();d=box2d.b2CrossVOne(m,box2d.b2CollidePolygons.s_localNormal);e=box2d.b2MidVV(p,q,box2d.b2CollidePolygons.s_planePoint);var k=box2d.b2MulRV(b.q,m,box2d.b2CollidePolygons.s_tangent),m=box2d.b2CrossVOne(k,box2d.b2CollidePolygons.s_normal),p=box2d.b2MulXV(b,p,box2d.b2CollidePolygons.s_v11),r=box2d.b2MulXV(b,q,box2d.b2CollidePolygons.s_v12);b=box2d.b2DotVV(m,p);var q=\n-box2d.b2DotVV(k,p)+f,r=box2d.b2DotVV(k,r)+f,t=box2d.b2CollidePolygons.s_clipPoints1,p=box2d.b2CollidePolygons.s_clipPoints2,s=box2d.b2NegV(k,box2d.b2CollidePolygons.s_ntangent),g=box2d.b2ClipSegmentToLine(t,g,s,q,l);if(!(2>g||(g=box2d.b2ClipSegmentToLine(p,t,k,r,h),2>g))){a.localNormal.Copy(d);a.localPoint.Copy(e);for(l=g=0;l<box2d.b2_maxManifoldPoints;++l)d=p[l],box2d.b2DotVV(m,d.v)-b<=f&&(h=a.points[g],box2d.b2MulTXV(c,d.v,h.localPoint),h.id.Copy(d.id),n&&(d=h.id.cf,h.id.cf.indexA=d.indexB,h.id.cf.indexB=\nd.indexA,h.id.cf.typeA=d.typeB,h.id.cf.typeB=d.typeA),++g);a.pointCount=g}}}};goog.exportSymbol(\"box2d.b2CollidePolygons\",box2d.b2CollidePolygons);box2d.b2CollidePolygons.s_incidentEdge=box2d.b2ClipVertex.MakeArray(2);box2d.b2CollidePolygons.s_clipPoints1=box2d.b2ClipVertex.MakeArray(2);box2d.b2CollidePolygons.s_clipPoints2=box2d.b2ClipVertex.MakeArray(2);box2d.b2CollidePolygons.s_edgeA=box2d.b2MakeNumberArray(1);box2d.b2CollidePolygons.s_edgeB=box2d.b2MakeNumberArray(1);\nbox2d.b2CollidePolygons.s_localTangent=new box2d.b2Vec2;box2d.b2CollidePolygons.s_localNormal=new box2d.b2Vec2;box2d.b2CollidePolygons.s_planePoint=new box2d.b2Vec2;box2d.b2CollidePolygons.s_normal=new box2d.b2Vec2;box2d.b2CollidePolygons.s_tangent=new box2d.b2Vec2;box2d.b2CollidePolygons.s_ntangent=new box2d.b2Vec2;box2d.b2CollidePolygons.s_v11=new box2d.b2Vec2;box2d.b2CollidePolygons.s_v12=new box2d.b2Vec2;box2d.b2PolygonContact=function(){box2d.b2Contact.call(this)};goog.inherits(box2d.b2PolygonContact,box2d.b2Contact);goog.exportSymbol(\"box2d.b2PolygonContact\",box2d.b2PolygonContact);box2d.b2PolygonContact.Create=function(a){return new box2d.b2PolygonContact};goog.exportProperty(box2d.b2PolygonContact,\"Create\",box2d.b2PolygonContact.Create);box2d.b2PolygonContact.Destroy=function(a,b){};goog.exportProperty(box2d.b2PolygonContact,\"Destroy\",box2d.b2PolygonContact.Destroy);\nbox2d.b2PolygonContact.prototype.Reset=function(a,b,c,e){box2d.b2PolygonContact.superClass_.Reset.call(this,a,b,c,e)};goog.exportProperty(box2d.b2PolygonContact.prototype,\"Reset\",box2d.b2PolygonContact.prototype.Reset);\nbox2d.b2PolygonContact.prototype.Evaluate=function(a,b,c){var e=this.m_fixtureA.GetShape(),d=this.m_fixtureB.GetShape();box2d.ENABLE_ASSERTS&&box2d.b2Assert(e instanceof box2d.b2PolygonShape);box2d.ENABLE_ASSERTS&&box2d.b2Assert(d instanceof box2d.b2PolygonShape);box2d.b2CollidePolygons(a,e instanceof box2d.b2PolygonShape?e:null,b,d instanceof box2d.b2PolygonShape?d:null,c)};goog.exportProperty(box2d.b2PolygonContact.prototype,\"Evaluate\",box2d.b2PolygonContact.prototype.Evaluate);box2d.b2CollideCircle={};box2d.b2CollideCircles=function(a,b,c,e,d){a.pointCount=0;c=box2d.b2MulXV(c,b.m_p,box2d.b2CollideCircles.s_pA);d=box2d.b2MulXV(d,e.m_p,box2d.b2CollideCircles.s_pB);d=box2d.b2DistanceSquaredVV(c,d);c=b.m_radius+e.m_radius;d>c*c||(a.type=box2d.b2ManifoldType.e_circles,a.localPoint.Copy(b.m_p),a.localNormal.SetZero(),a.pointCount=1,a.points[0].localPoint.Copy(e.m_p),a.points[0].id.key=0)};goog.exportSymbol(\"box2d.b2CollideCircles\",box2d.b2CollideCircles);\nbox2d.b2CollideCircles.s_pA=new box2d.b2Vec2;box2d.b2CollideCircles.s_pB=new box2d.b2Vec2;\nbox2d.b2CollidePolygonAndCircle=function(a,b,c,e,d){a.pointCount=0;d=box2d.b2MulXV(d,e.m_p,box2d.b2CollidePolygonAndCircle.s_c);c=box2d.b2MulTXV(c,d,box2d.b2CollidePolygonAndCircle.s_cLocal);var f=0,g=-box2d.b2_maxFloat;d=b.m_radius+e.m_radius;var h=b.m_count,l=b.m_vertices;b=b.m_normals;for(var k=0;k<h;++k){var m=box2d.b2DotVV(b[k],box2d.b2SubVV(c,l[k],box2d.b2Vec2.s_t0));if(m>d)return;m>g&&(g=m,f=k)}k=f;m=l[k];h=l[(k+1)%h];g<box2d.b2_epsilon?(a.pointCount=1,a.type=box2d.b2ManifoldType.e_faceA,a.localNormal.Copy(b[f]),\nbox2d.b2MidVV(m,h,a.localPoint),a.points[0].localPoint.Copy(e.m_p),a.points[0].id.key=0):(g=box2d.b2DotVV(box2d.b2SubVV(c,m,box2d.b2Vec2.s_t0),box2d.b2SubVV(h,m,box2d.b2Vec2.s_t1)),f=box2d.b2DotVV(box2d.b2SubVV(c,h,box2d.b2Vec2.s_t0),box2d.b2SubVV(m,h,box2d.b2Vec2.s_t1)),0>=g?box2d.b2DistanceSquaredVV(c,m)>d*d||(a.pointCount=1,a.type=box2d.b2ManifoldType.e_faceA,box2d.b2SubVV(c,m,a.localNormal).SelfNormalize(),a.localPoint.Copy(m),a.points[0].localPoint.Copy(e.m_p),a.points[0].id.key=0):0>=f?box2d.b2DistanceSquaredVV(c,\nh)>d*d||(a.pointCount=1,a.type=box2d.b2ManifoldType.e_faceA,box2d.b2SubVV(c,h,a.localNormal).SelfNormalize(),a.localPoint.Copy(h),a.points[0].localPoint.Copy(e.m_p),a.points[0].id.key=0):(f=box2d.b2MidVV(m,h,box2d.b2CollidePolygonAndCircle.s_faceCenter),g=box2d.b2DotVV(box2d.b2SubVV(c,f,box2d.b2Vec2.s_t1),b[k]),g>d||(a.pointCount=1,a.type=box2d.b2ManifoldType.e_faceA,a.localNormal.Copy(b[k]).SelfNormalize(),a.localPoint.Copy(f),a.points[0].localPoint.Copy(e.m_p),a.points[0].id.key=0)))};\ngoog.exportSymbol(\"box2d.b2CollidePolygonAndCircle\",box2d.b2CollidePolygonAndCircle);box2d.b2CollidePolygonAndCircle.s_c=new box2d.b2Vec2;box2d.b2CollidePolygonAndCircle.s_cLocal=new box2d.b2Vec2;box2d.b2CollidePolygonAndCircle.s_faceCenter=new box2d.b2Vec2;box2d.b2CircleContact=function(){box2d.b2Contact.call(this)};goog.inherits(box2d.b2CircleContact,box2d.b2Contact);goog.exportSymbol(\"box2d.b2CircleContact\",box2d.b2CircleContact);box2d.b2CircleContact.Create=function(a){return new box2d.b2CircleContact};goog.exportProperty(box2d.b2CircleContact,\"Create\",box2d.b2CircleContact.Create);box2d.b2CircleContact.Destroy=function(a,b){};goog.exportProperty(box2d.b2CircleContact,\"Destroy\",box2d.b2CircleContact.Destroy);\nbox2d.b2CircleContact.prototype.Reset=function(a,b,c,e){box2d.b2CircleContact.superClass_.Reset.call(this,a,b,c,e)};goog.exportProperty(box2d.b2CircleContact.prototype,\"Reset\",box2d.b2CircleContact.prototype.Reset);\nbox2d.b2CircleContact.prototype.Evaluate=function(a,b,c){var e=this.m_fixtureA.GetShape(),d=this.m_fixtureB.GetShape();box2d.ENABLE_ASSERTS&&box2d.b2Assert(e instanceof box2d.b2CircleShape);box2d.ENABLE_ASSERTS&&box2d.b2Assert(d instanceof box2d.b2CircleShape);box2d.b2CollideCircles(a,e instanceof box2d.b2CircleShape?e:null,b,d instanceof box2d.b2CircleShape?d:null,c)};goog.exportProperty(box2d.b2CircleContact.prototype,\"Evaluate\",box2d.b2CircleContact.prototype.Evaluate);box2d.b2ChainAndCircleContact=function(){box2d.b2Contact.call(this)};goog.inherits(box2d.b2ChainAndCircleContact,box2d.b2Contact);goog.exportSymbol(\"box2d.b2ChainAndCircleContact\",box2d.b2ChainAndCircleContact);box2d.b2ChainAndCircleContact.Create=function(a){return new box2d.b2ChainAndCircleContact};goog.exportProperty(box2d.b2ChainAndCircleContact,\"Create\",box2d.b2ChainAndCircleContact.Create);box2d.b2ChainAndCircleContact.Destroy=function(a,b){};\ngoog.exportProperty(box2d.b2ChainAndCircleContact,\"Destroy\",box2d.b2ChainAndCircleContact.Destroy);box2d.b2ChainAndCircleContact.prototype.Reset=function(a,b,c,e){box2d.b2ChainAndCircleContact.superClass_.Reset.call(this,a,b,c,e);box2d.ENABLE_ASSERTS&&box2d.b2Assert(a.GetType()===box2d.b2ShapeType.e_chainShape);box2d.ENABLE_ASSERTS&&box2d.b2Assert(c.GetType()===box2d.b2ShapeType.e_circleShape)};goog.exportProperty(box2d.b2ChainAndCircleContact.prototype,\"Reset\",box2d.b2ChainAndCircleContact.prototype.Reset);\nbox2d.b2ChainAndCircleContact.prototype.Evaluate=function(a,b,c){var e=this.m_fixtureA.GetShape(),d=this.m_fixtureB.GetShape();box2d.ENABLE_ASSERTS&&box2d.b2Assert(e instanceof box2d.b2ChainShape);box2d.ENABLE_ASSERTS&&box2d.b2Assert(d instanceof box2d.b2CircleShape);var f=box2d.b2ChainAndCircleContact.prototype.Evaluate.s_edge;(e instanceof box2d.b2ChainShape?e:null).GetChildEdge(f,this.m_indexA);box2d.b2CollideEdgeAndCircle(a,f,b,d instanceof box2d.b2CircleShape?d:null,c)};\ngoog.exportProperty(box2d.b2ChainAndCircleContact.prototype,\"Evaluate\",box2d.b2ChainAndCircleContact.prototype.Evaluate);box2d.b2ChainAndCircleContact.prototype.Evaluate.s_edge=new box2d.b2EdgeShape;box2d.b2EdgeAndCircleContact=function(){box2d.b2Contact.call(this)};goog.inherits(box2d.b2EdgeAndCircleContact,box2d.b2Contact);goog.exportSymbol(\"box2d.b2EdgeAndCircleContact\",box2d.b2EdgeAndCircleContact);box2d.b2EdgeAndCircleContact.Create=function(a){return new box2d.b2EdgeAndCircleContact};goog.exportProperty(box2d.b2EdgeAndCircleContact,\"Create\",box2d.b2EdgeAndCircleContact.Create);box2d.b2EdgeAndCircleContact.Destroy=function(a,b){};\ngoog.exportProperty(box2d.b2EdgeAndCircleContact,\"Destroy\",box2d.b2EdgeAndCircleContact.Destroy);box2d.b2EdgeAndCircleContact.prototype.Reset=function(a,b,c,e){box2d.b2EdgeAndCircleContact.superClass_.Reset.call(this,a,b,c,e);box2d.ENABLE_ASSERTS&&box2d.b2Assert(a.GetType()===box2d.b2ShapeType.e_edgeShape);box2d.ENABLE_ASSERTS&&box2d.b2Assert(c.GetType()===box2d.b2ShapeType.e_circleShape)};goog.exportProperty(box2d.b2EdgeAndCircleContact.prototype,\"Reset\",box2d.b2EdgeAndCircleContact.prototype.Reset);\nbox2d.b2EdgeAndCircleContact.prototype.Evaluate=function(a,b,c){var e=this.m_fixtureA.GetShape(),d=this.m_fixtureB.GetShape();box2d.ENABLE_ASSERTS&&box2d.b2Assert(e instanceof box2d.b2EdgeShape);box2d.ENABLE_ASSERTS&&box2d.b2Assert(d instanceof box2d.b2CircleShape);box2d.b2CollideEdgeAndCircle(a,e instanceof box2d.b2EdgeShape?e:null,b,d instanceof box2d.b2CircleShape?d:null,c)};goog.exportProperty(box2d.b2EdgeAndCircleContact.prototype,\"Evaluate\",box2d.b2EdgeAndCircleContact.prototype.Evaluate);box2d.b2VelocityConstraintPoint=function(){this.rA=new box2d.b2Vec2;this.rB=new box2d.b2Vec2};goog.exportSymbol(\"box2d.b2VelocityConstraintPoint\",box2d.b2VelocityConstraintPoint);box2d.b2VelocityConstraintPoint.prototype.rA=null;goog.exportProperty(box2d.b2VelocityConstraintPoint.prototype,\"rA\",box2d.b2VelocityConstraintPoint.prototype.rA);box2d.b2VelocityConstraintPoint.prototype.rB=null;goog.exportProperty(box2d.b2VelocityConstraintPoint.prototype,\"rB\",box2d.b2VelocityConstraintPoint.prototype.rB);\nbox2d.b2VelocityConstraintPoint.prototype.normalImpulse=0;goog.exportProperty(box2d.b2VelocityConstraintPoint.prototype,\"normalImpulse\",box2d.b2VelocityConstraintPoint.prototype.normalImpulse);box2d.b2VelocityConstraintPoint.prototype.tangentImpulse=0;goog.exportProperty(box2d.b2VelocityConstraintPoint.prototype,\"tangentImpulse\",box2d.b2VelocityConstraintPoint.prototype.tangentImpulse);box2d.b2VelocityConstraintPoint.prototype.normalMass=0;\ngoog.exportProperty(box2d.b2VelocityConstraintPoint.prototype,\"normalMass\",box2d.b2VelocityConstraintPoint.prototype.normalMass);box2d.b2VelocityConstraintPoint.prototype.tangentMass=0;goog.exportProperty(box2d.b2VelocityConstraintPoint.prototype,\"tangentMass\",box2d.b2VelocityConstraintPoint.prototype.tangentMass);box2d.b2VelocityConstraintPoint.prototype.velocityBias=0;goog.exportProperty(box2d.b2VelocityConstraintPoint.prototype,\"velocityBias\",box2d.b2VelocityConstraintPoint.prototype.velocityBias);\nbox2d.b2VelocityConstraintPoint.MakeArray=function(a){return box2d.b2MakeArray(a,function(a){return new box2d.b2VelocityConstraintPoint})};goog.exportProperty(box2d.b2VelocityConstraintPoint,\"MakeArray\",box2d.b2VelocityConstraintPoint.MakeArray);box2d.b2ContactVelocityConstraint=function(){this.points=box2d.b2VelocityConstraintPoint.MakeArray(box2d.b2_maxManifoldPoints);this.normal=new box2d.b2Vec2;this.tangent=new box2d.b2Vec2;this.normalMass=new box2d.b2Mat22;this.K=new box2d.b2Mat22};\ngoog.exportSymbol(\"box2d.b2ContactVelocityConstraint\",box2d.b2ContactVelocityConstraint);box2d.b2ContactVelocityConstraint.prototype.points=null;goog.exportProperty(box2d.b2ContactVelocityConstraint.prototype,\"points\",box2d.b2ContactVelocityConstraint.prototype.points);box2d.b2ContactVelocityConstraint.prototype.normal=null;goog.exportProperty(box2d.b2ContactVelocityConstraint.prototype,\"normal\",box2d.b2ContactVelocityConstraint.prototype.normal);\nbox2d.b2ContactVelocityConstraint.prototype.tangent=null;goog.exportProperty(box2d.b2ContactVelocityConstraint.prototype,\"tangent\",box2d.b2ContactVelocityConstraint.prototype.tangent);box2d.b2ContactVelocityConstraint.prototype.normalMass=null;goog.exportProperty(box2d.b2ContactVelocityConstraint.prototype,\"normalMass\",box2d.b2ContactVelocityConstraint.prototype.normalMass);box2d.b2ContactVelocityConstraint.prototype.K=null;goog.exportProperty(box2d.b2ContactVelocityConstraint.prototype,\"K\",box2d.b2ContactVelocityConstraint.prototype.K);\nbox2d.b2ContactVelocityConstraint.prototype.indexA=0;goog.exportProperty(box2d.b2ContactVelocityConstraint.prototype,\"indexA\",box2d.b2ContactVelocityConstraint.prototype.indexA);box2d.b2ContactVelocityConstraint.prototype.indexB=0;goog.exportProperty(box2d.b2ContactVelocityConstraint.prototype,\"indexB\",box2d.b2ContactVelocityConstraint.prototype.indexB);box2d.b2ContactVelocityConstraint.prototype.invMassA=0;goog.exportProperty(box2d.b2ContactVelocityConstraint.prototype,\"invMassA\",box2d.b2ContactVelocityConstraint.prototype.invMassA);\nbox2d.b2ContactVelocityConstraint.prototype.invMassB=0;goog.exportProperty(box2d.b2ContactVelocityConstraint.prototype,\"invMassB\",box2d.b2ContactVelocityConstraint.prototype.invMassB);box2d.b2ContactVelocityConstraint.prototype.invIA=0;goog.exportProperty(box2d.b2ContactVelocityConstraint.prototype,\"invIA\",box2d.b2ContactVelocityConstraint.prototype.invIA);box2d.b2ContactVelocityConstraint.prototype.invIB=0;goog.exportProperty(box2d.b2ContactVelocityConstraint.prototype,\"invIB\",box2d.b2ContactVelocityConstraint.prototype.invIB);\nbox2d.b2ContactVelocityConstraint.prototype.friction=0;goog.exportProperty(box2d.b2ContactVelocityConstraint.prototype,\"friction\",box2d.b2ContactVelocityConstraint.prototype.friction);box2d.b2ContactVelocityConstraint.prototype.restitution=0;goog.exportProperty(box2d.b2ContactVelocityConstraint.prototype,\"restitution\",box2d.b2ContactVelocityConstraint.prototype.restitution);box2d.b2ContactVelocityConstraint.prototype.tangentSpeed=0;\ngoog.exportProperty(box2d.b2ContactVelocityConstraint.prototype,\"tangentSpeed\",box2d.b2ContactVelocityConstraint.prototype.tangentSpeed);box2d.b2ContactVelocityConstraint.prototype.pointCount=0;goog.exportProperty(box2d.b2ContactVelocityConstraint.prototype,\"pointCount\",box2d.b2ContactVelocityConstraint.prototype.pointCount);box2d.b2ContactVelocityConstraint.prototype.contactIndex=0;goog.exportProperty(box2d.b2ContactVelocityConstraint.prototype,\"contactIndex\",box2d.b2ContactVelocityConstraint.prototype.contactIndex);\nbox2d.b2ContactVelocityConstraint.MakeArray=function(a){return box2d.b2MakeArray(a,function(a){return new box2d.b2ContactVelocityConstraint})};goog.exportProperty(box2d.b2ContactVelocityConstraint,\"MakeArray\",box2d.b2ContactVelocityConstraint.MakeArray);box2d.b2ContactPositionConstraint=function(){this.localPoints=box2d.b2Vec2.MakeArray(box2d.b2_maxManifoldPoints);this.localNormal=new box2d.b2Vec2;this.localPoint=new box2d.b2Vec2;this.localCenterA=new box2d.b2Vec2;this.localCenterB=new box2d.b2Vec2};\ngoog.exportSymbol(\"box2d.b2ContactPositionConstraint\",box2d.b2ContactPositionConstraint);box2d.b2ContactPositionConstraint.prototype.localPoints=null;goog.exportProperty(box2d.b2ContactPositionConstraint.prototype,\"localPoints\",box2d.b2ContactPositionConstraint.prototype.localPoints);box2d.b2ContactPositionConstraint.prototype.localNormal=null;goog.exportProperty(box2d.b2ContactPositionConstraint.prototype,\"localNormal\",box2d.b2ContactPositionConstraint.prototype.localNormal);\nbox2d.b2ContactPositionConstraint.prototype.localPoint=null;goog.exportProperty(box2d.b2ContactPositionConstraint.prototype,\"localPoint\",box2d.b2ContactPositionConstraint.prototype.localPoint);box2d.b2ContactPositionConstraint.prototype.indexA=0;goog.exportProperty(box2d.b2ContactPositionConstraint.prototype,\"indexA\",box2d.b2ContactPositionConstraint.prototype.indexA);box2d.b2ContactPositionConstraint.prototype.indexB=0;goog.exportProperty(box2d.b2ContactPositionConstraint.prototype,\"indexB\",box2d.b2ContactPositionConstraint.prototype.indexB);\nbox2d.b2ContactPositionConstraint.prototype.invMassA=0;goog.exportProperty(box2d.b2ContactPositionConstraint.prototype,\"invMassA\",box2d.b2ContactPositionConstraint.prototype.invMassA);box2d.b2ContactPositionConstraint.prototype.invMassB=0;goog.exportProperty(box2d.b2ContactPositionConstraint.prototype,\"invMassB\",box2d.b2ContactPositionConstraint.prototype.invMassB);box2d.b2ContactPositionConstraint.prototype.localCenterA=null;\ngoog.exportProperty(box2d.b2ContactPositionConstraint.prototype,\"localCenterA\",box2d.b2ContactPositionConstraint.prototype.localCenterA);box2d.b2ContactPositionConstraint.prototype.localCenterB=null;goog.exportProperty(box2d.b2ContactPositionConstraint.prototype,\"localCenterB\",box2d.b2ContactPositionConstraint.prototype.localCenterB);box2d.b2ContactPositionConstraint.prototype.invIA=0;goog.exportProperty(box2d.b2ContactPositionConstraint.prototype,\"invIA\",box2d.b2ContactPositionConstraint.prototype.invIA);\nbox2d.b2ContactPositionConstraint.prototype.invIB=0;goog.exportProperty(box2d.b2ContactPositionConstraint.prototype,\"invIB\",box2d.b2ContactPositionConstraint.prototype.invIB);box2d.b2ContactPositionConstraint.prototype.type=box2d.b2ManifoldType.e_unknown;goog.exportProperty(box2d.b2ContactPositionConstraint.prototype,\"type\",box2d.b2ContactPositionConstraint.prototype.type);box2d.b2ContactPositionConstraint.prototype.radiusA=0;\ngoog.exportProperty(box2d.b2ContactPositionConstraint.prototype,\"radiusA\",box2d.b2ContactPositionConstraint.prototype.radiusA);box2d.b2ContactPositionConstraint.prototype.radiusB=0;goog.exportProperty(box2d.b2ContactPositionConstraint.prototype,\"radiusB\",box2d.b2ContactPositionConstraint.prototype.radiusB);box2d.b2ContactPositionConstraint.prototype.pointCount=0;goog.exportProperty(box2d.b2ContactPositionConstraint.prototype,\"pointCount\",box2d.b2ContactPositionConstraint.prototype.pointCount);\nbox2d.b2ContactPositionConstraint.MakeArray=function(a){return box2d.b2MakeArray(a,function(a){return new box2d.b2ContactPositionConstraint})};goog.exportProperty(box2d.b2ContactPositionConstraint,\"MakeArray\",box2d.b2ContactPositionConstraint.MakeArray);box2d.b2ContactSolverDef=function(){this.step=new box2d.b2TimeStep};goog.exportSymbol(\"box2d.b2ContactSolverDef\",box2d.b2ContactSolverDef);box2d.b2ContactSolverDef.prototype.step=null;goog.exportProperty(box2d.b2ContactSolverDef.prototype,\"step\",box2d.b2ContactSolverDef.prototype.step);\nbox2d.b2ContactSolverDef.prototype.contacts=null;goog.exportProperty(box2d.b2ContactSolverDef.prototype,\"contacts\",box2d.b2ContactSolverDef.prototype.contacts);box2d.b2ContactSolverDef.prototype.count=0;goog.exportProperty(box2d.b2ContactSolverDef.prototype,\"count\",box2d.b2ContactSolverDef.prototype.count);box2d.b2ContactSolverDef.prototype.positions=null;goog.exportProperty(box2d.b2ContactSolverDef.prototype,\"positions\",box2d.b2ContactSolverDef.prototype.positions);\nbox2d.b2ContactSolverDef.prototype.velocities=null;goog.exportProperty(box2d.b2ContactSolverDef.prototype,\"velocities\",box2d.b2ContactSolverDef.prototype.velocities);box2d.b2ContactSolverDef.prototype.allocator=null;goog.exportProperty(box2d.b2ContactSolverDef.prototype,\"allocator\",box2d.b2ContactSolverDef.prototype.allocator);box2d.b2ContactSolver=function(){this.m_step=new box2d.b2TimeStep;this.m_positionConstraints=box2d.b2ContactPositionConstraint.MakeArray(1024);this.m_velocityConstraints=box2d.b2ContactVelocityConstraint.MakeArray(1024)};\ngoog.exportSymbol(\"box2d.b2ContactSolver\",box2d.b2ContactSolver);box2d.b2ContactSolver.prototype.m_step=null;goog.exportProperty(box2d.b2ContactSolver.prototype,\"m_step\",box2d.b2ContactSolver.prototype.m_step);box2d.b2ContactSolver.prototype.m_positions=null;goog.exportProperty(box2d.b2ContactSolver.prototype,\"m_positions\",box2d.b2ContactSolver.prototype.m_positions);box2d.b2ContactSolver.prototype.m_velocities=null;goog.exportProperty(box2d.b2ContactSolver.prototype,\"m_velocities\",box2d.b2ContactSolver.prototype.m_velocities);\nbox2d.b2ContactSolver.prototype.m_allocator=null;goog.exportProperty(box2d.b2ContactSolver.prototype,\"m_allocator\",box2d.b2ContactSolver.prototype.m_allocator);box2d.b2ContactSolver.prototype.m_positionConstraints=null;goog.exportProperty(box2d.b2ContactSolver.prototype,\"m_positionConstraints\",box2d.b2ContactSolver.prototype.m_positionConstraints);box2d.b2ContactSolver.prototype.m_velocityConstraints=null;goog.exportProperty(box2d.b2ContactSolver.prototype,\"m_velocityConstraints\",box2d.b2ContactSolver.prototype.m_velocityConstraints);\nbox2d.b2ContactSolver.prototype.m_contacts=null;goog.exportProperty(box2d.b2ContactSolver.prototype,\"m_contacts\",box2d.b2ContactSolver.prototype.m_contacts);box2d.b2ContactSolver.prototype.m_count=0;goog.exportProperty(box2d.b2ContactSolver.prototype,\"m_count\",box2d.b2ContactSolver.prototype.m_count);\nbox2d.b2ContactSolver.prototype.Initialize=function(a){this.m_step.Copy(a.step);this.m_allocator=a.allocator;this.m_count=a.count;if(this.m_positionConstraints.length<this.m_count){var b=box2d.b2Max(2*this.m_positionConstraints.length,this.m_count);for(box2d.DEBUG&&window.console.log(\"box2d.b2ContactSolver.m_positionConstraints: \"+b);this.m_positionConstraints.length<b;)this.m_positionConstraints[this.m_positionConstraints.length]=new box2d.b2ContactPositionConstraint}if(this.m_velocityConstraints.length<\nthis.m_count)for(b=box2d.b2Max(2*this.m_velocityConstraints.length,this.m_count),box2d.DEBUG&&window.console.log(\"box2d.b2ContactSolver.m_velocityConstraints: \"+b);this.m_velocityConstraints.length<b;)this.m_velocityConstraints[this.m_velocityConstraints.length]=new box2d.b2ContactVelocityConstraint;this.m_positions=a.positions;this.m_velocities=a.velocities;this.m_contacts=a.contacts;var c,e,d,f,g,h,l,k;a=0;for(b=this.m_count;a<b;++a)for(d=this.m_contacts[a],f=d.m_fixtureA,g=d.m_fixtureB,c=f.GetShape(),\ne=g.GetShape(),c=c.m_radius,e=e.m_radius,h=f.GetBody(),l=g.GetBody(),g=d.GetManifold(),k=g.pointCount,box2d.ENABLE_ASSERTS&&box2d.b2Assert(0<k),f=this.m_velocityConstraints[a],f.friction=d.m_friction,f.restitution=d.m_restitution,f.tangentSpeed=d.m_tangentSpeed,f.indexA=h.m_islandIndex,f.indexB=l.m_islandIndex,f.invMassA=h.m_invMass,f.invMassB=l.m_invMass,f.invIA=h.m_invI,f.invIB=l.m_invI,f.contactIndex=a,f.pointCount=k,f.K.SetZero(),f.normalMass.SetZero(),d=this.m_positionConstraints[a],d.indexA=\nh.m_islandIndex,d.indexB=l.m_islandIndex,d.invMassA=h.m_invMass,d.invMassB=l.m_invMass,d.localCenterA.Copy(h.m_sweep.localCenter),d.localCenterB.Copy(l.m_sweep.localCenter),d.invIA=h.m_invI,d.invIB=l.m_invI,d.localNormal.Copy(g.localNormal),d.localPoint.Copy(g.localPoint),d.pointCount=k,d.radiusA=c,d.radiusB=e,d.type=g.type,c=0,e=k;c<e;++c)h=g.points[c],k=f.points[c],this.m_step.warmStarting?(k.normalImpulse=this.m_step.dtRatio*h.normalImpulse,k.tangentImpulse=this.m_step.dtRatio*h.tangentImpulse):\n(k.normalImpulse=0,k.tangentImpulse=0),k.rA.SetZero(),k.rB.SetZero(),k.normalMass=0,k.tangentMass=0,k.velocityBias=0,d.localPoints[c].Copy(h.localPoint);return this};goog.exportProperty(box2d.b2ContactSolver.prototype,\"Initialize\",box2d.b2ContactSolver.prototype.Initialize);\nbox2d.b2ContactSolver.prototype.InitializeVelocityConstraints=function(){var a,b,c,e,d,f,g,h,l,k,m,n,p,q,r,t,s,u,v,y,D=box2d.b2ContactSolver.prototype.InitializeVelocityConstraints.s_xfA,x=box2d.b2ContactSolver.prototype.InitializeVelocityConstraints.s_xfB,w=box2d.b2ContactSolver.prototype.InitializeVelocityConstraints.s_worldManifold;a=0;for(b=this.m_count;a<b;++a){d=this.m_velocityConstraints[a];f=this.m_positionConstraints[a];c=f.radiusA;e=f.radiusB;g=this.m_contacts[d.contactIndex].GetManifold();\nh=d.indexA;l=d.indexB;k=d.invMassA;m=d.invMassB;n=d.invIA;p=d.invIB;q=f.localCenterA;r=f.localCenterB;f=this.m_positions[h].c;t=this.m_positions[h].a;s=this.m_velocities[h].v;h=this.m_velocities[h].w;u=this.m_positions[l].c;v=this.m_positions[l].a;y=this.m_velocities[l].v;l=this.m_velocities[l].w;box2d.ENABLE_ASSERTS&&box2d.b2Assert(0<g.pointCount);D.q.SetAngleRadians(t);x.q.SetAngleRadians(v);box2d.b2SubVV(f,box2d.b2MulRV(D.q,q,box2d.b2Vec2.s_t0),D.p);box2d.b2SubVV(u,box2d.b2MulRV(x.q,r,box2d.b2Vec2.s_t0),\nx.p);w.Initialize(g,D,c,x,e);d.normal.Copy(w.normal);box2d.b2CrossVOne(d.normal,d.tangent);e=d.pointCount;for(c=0;c<e;++c)g=d.points[c],box2d.b2SubVV(w.points[c],f,g.rA),box2d.b2SubVV(w.points[c],u,g.rB),q=box2d.b2CrossVV(g.rA,d.normal),r=box2d.b2CrossVV(g.rB,d.normal),q=k+m+n*q*q+p*r*r,g.normalMass=0<q?1/q:0,r=d.tangent,q=box2d.b2CrossVV(g.rA,r),r=box2d.b2CrossVV(g.rB,r),q=k+m+n*q*q+p*r*r,g.tangentMass=0<q?1/q:0,g.velocityBias=0,q=box2d.b2DotVV(d.normal,box2d.b2SubVV(box2d.b2AddVCrossSV(y,l,g.rB,\nbox2d.b2Vec2.s_t0),box2d.b2AddVCrossSV(s,h,g.rA,box2d.b2Vec2.s_t1),box2d.b2Vec2.s_t0)),q<-box2d.b2_velocityThreshold&&(g.velocityBias+=-d.restitution*q);2===d.pointCount&&(s=d.points[0],u=d.points[1],f=box2d.b2CrossVV(s.rA,d.normal),s=box2d.b2CrossVV(s.rB,d.normal),h=box2d.b2CrossVV(u.rA,d.normal),l=box2d.b2CrossVV(u.rB,d.normal),u=k+m+n*f*f+p*s*s,y=k+m+n*h*h+p*l*l,k=k+m+n*f*h+p*s*l,u*u<1E3*(u*y-k*k)?(d.K.ex.SetXY(u,k),d.K.ey.SetXY(k,y),d.K.GetInverse(d.normalMass)):d.pointCount=1)}};\ngoog.exportProperty(box2d.b2ContactSolver.prototype,\"InitializeVelocityConstraints\",box2d.b2ContactSolver.prototype.InitializeVelocityConstraints);box2d.b2ContactSolver.prototype.InitializeVelocityConstraints.s_xfA=new box2d.b2Transform;box2d.b2ContactSolver.prototype.InitializeVelocityConstraints.s_xfB=new box2d.b2Transform;box2d.b2ContactSolver.prototype.InitializeVelocityConstraints.s_worldManifold=new box2d.b2WorldManifold;\nbox2d.b2ContactSolver.prototype.WarmStart=function(){var a,b,c,e,d,f,g,h,l,k,m,n,p,q,r,t,s,u,v=box2d.b2ContactSolver.prototype.WarmStart.s_P;a=0;for(b=this.m_count;a<b;++a){d=this.m_velocityConstraints[a];f=d.indexA;g=d.indexB;h=d.invMassA;l=d.invIA;k=d.invMassB;m=d.invIB;e=d.pointCount;n=this.m_velocities[f].v;p=this.m_velocities[f].w;q=this.m_velocities[g].v;r=this.m_velocities[g].w;t=d.normal;s=d.tangent;for(c=0;c<e;++c)u=d.points[c],box2d.b2AddVV(box2d.b2MulSV(u.normalImpulse,t,box2d.b2Vec2.s_t0),\nbox2d.b2MulSV(u.tangentImpulse,s,box2d.b2Vec2.s_t1),v),p-=l*box2d.b2CrossVV(u.rA,v),n.SelfMulSub(h,v),r+=m*box2d.b2CrossVV(u.rB,v),q.SelfMulAdd(k,v);this.m_velocities[f].w=p;this.m_velocities[g].w=r}};goog.exportProperty(box2d.b2ContactSolver.prototype,\"WarmStart\",box2d.b2ContactSolver.prototype.WarmStart);box2d.b2ContactSolver.prototype.WarmStart.s_P=new box2d.b2Vec2;\nbox2d.b2ContactSolver.prototype.SolveVelocityConstraints=function(){var a,b,c,e,d,f,g,h,l,k,m,n,p,q,r,t,s,u,v,y=box2d.b2ContactSolver.prototype.SolveVelocityConstraints.s_dv,D=box2d.b2ContactSolver.prototype.SolveVelocityConstraints.s_dv1,x=box2d.b2ContactSolver.prototype.SolveVelocityConstraints.s_dv2,w,C,A=box2d.b2ContactSolver.prototype.SolveVelocityConstraints.s_P,E=box2d.b2ContactSolver.prototype.SolveVelocityConstraints.s_a,B=box2d.b2ContactSolver.prototype.SolveVelocityConstraints.s_b,z=box2d.b2ContactSolver.prototype.SolveVelocityConstraints.s_x,\nG=box2d.b2ContactSolver.prototype.SolveVelocityConstraints.s_d,F=box2d.b2ContactSolver.prototype.SolveVelocityConstraints.s_P1,H=box2d.b2ContactSolver.prototype.SolveVelocityConstraints.s_P2,I=box2d.b2ContactSolver.prototype.SolveVelocityConstraints.s_P1P2;a=0;for(b=this.m_count;a<b;++a){d=this.m_velocityConstraints[a];f=d.indexA;g=d.indexB;h=d.invMassA;l=d.invIA;k=d.invMassB;m=d.invIB;n=d.pointCount;p=this.m_velocities[f].v;q=this.m_velocities[f].w;r=this.m_velocities[g].v;t=this.m_velocities[g].w;\ns=d.normal;u=d.tangent;v=d.friction;box2d.ENABLE_ASSERTS&&box2d.b2Assert(1===n||2===n);c=0;for(e=n;c<e;++c)n=d.points[c],box2d.b2SubVV(box2d.b2AddVCrossSV(r,t,n.rB,box2d.b2Vec2.s_t0),box2d.b2AddVCrossSV(p,q,n.rA,box2d.b2Vec2.s_t1),y),w=box2d.b2DotVV(y,u)-d.tangentSpeed,w=n.tangentMass*-w,C=v*n.normalImpulse,C=box2d.b2Clamp(n.tangentImpulse+w,-C,C),w=C-n.tangentImpulse,n.tangentImpulse=C,box2d.b2MulSV(w,u,A),p.SelfMulSub(h,A),q-=l*box2d.b2CrossVV(n.rA,A),r.SelfMulAdd(k,A),t+=m*box2d.b2CrossVV(n.rB,\nA);if(1===d.pointCount)n=d.points[0],box2d.b2SubVV(box2d.b2AddVCrossSV(r,t,n.rB,box2d.b2Vec2.s_t0),box2d.b2AddVCrossSV(p,q,n.rA,box2d.b2Vec2.s_t1),y),d=box2d.b2DotVV(y,s),w=-n.normalMass*(d-n.velocityBias),C=box2d.b2Max(n.normalImpulse+w,0),w=C-n.normalImpulse,n.normalImpulse=C,box2d.b2MulSV(w,s,A),p.SelfMulSub(h,A),q-=l*box2d.b2CrossVV(n.rA,A),r.SelfMulAdd(k,A),t+=m*box2d.b2CrossVV(n.rB,A);else for(c=d.points[0],u=d.points[1],E.SetXY(c.normalImpulse,u.normalImpulse),box2d.ENABLE_ASSERTS&&box2d.b2Assert(0<=\nE.x&&0<=E.y),box2d.b2SubVV(box2d.b2AddVCrossSV(r,t,c.rB,box2d.b2Vec2.s_t0),box2d.b2AddVCrossSV(p,q,c.rA,box2d.b2Vec2.s_t1),D),box2d.b2SubVV(box2d.b2AddVCrossSV(r,t,u.rB,box2d.b2Vec2.s_t0),box2d.b2AddVCrossSV(p,q,u.rA,box2d.b2Vec2.s_t1),x),v=box2d.b2DotVV(D,s),n=box2d.b2DotVV(x,s),B.x=v-c.velocityBias,B.y=n-u.velocityBias,B.SelfSub(box2d.b2MulMV(d.K,E,box2d.b2Vec2.s_t0));;){box2d.b2MulMV(d.normalMass,B,z).SelfNeg();if(0<=z.x&&0<=z.y){box2d.b2SubVV(z,E,G);box2d.b2MulSV(G.x,s,F);box2d.b2MulSV(G.y,s,\nH);box2d.b2AddVV(F,H,I);p.SelfMulSub(h,I);q-=l*(box2d.b2CrossVV(c.rA,F)+box2d.b2CrossVV(u.rA,H));r.SelfMulAdd(k,I);t+=m*(box2d.b2CrossVV(c.rB,F)+box2d.b2CrossVV(u.rB,H));c.normalImpulse=z.x;u.normalImpulse=z.y;break}z.x=-c.normalMass*B.x;z.y=0;n=d.K.ex.y*z.x+B.y;if(0<=z.x&&0<=n){box2d.b2SubVV(z,E,G);box2d.b2MulSV(G.x,s,F);box2d.b2MulSV(G.y,s,H);box2d.b2AddVV(F,H,I);p.SelfMulSub(h,I);q-=l*(box2d.b2CrossVV(c.rA,F)+box2d.b2CrossVV(u.rA,H));r.SelfMulAdd(k,I);t+=m*(box2d.b2CrossVV(c.rB,F)+box2d.b2CrossVV(u.rB,\nH));c.normalImpulse=z.x;u.normalImpulse=z.y;break}z.x=0;z.y=-u.normalMass*B.y;v=d.K.ey.x*z.y+B.x;if(0<=z.y&&0<=v){box2d.b2SubVV(z,E,G);box2d.b2MulSV(G.x,s,F);box2d.b2MulSV(G.y,s,H);box2d.b2AddVV(F,H,I);p.SelfMulSub(h,I);q-=l*(box2d.b2CrossVV(c.rA,F)+box2d.b2CrossVV(u.rA,H));r.SelfMulAdd(k,I);t+=m*(box2d.b2CrossVV(c.rB,F)+box2d.b2CrossVV(u.rB,H));c.normalImpulse=z.x;u.normalImpulse=z.y;break}z.x=0;z.y=0;v=B.x;n=B.y;if(0<=v&&0<=n){box2d.b2SubVV(z,E,G);box2d.b2MulSV(G.x,s,F);box2d.b2MulSV(G.y,s,H);box2d.b2AddVV(F,\nH,I);p.SelfMulSub(h,I);q-=l*(box2d.b2CrossVV(c.rA,F)+box2d.b2CrossVV(u.rA,H));r.SelfMulAdd(k,I);t+=m*(box2d.b2CrossVV(c.rB,F)+box2d.b2CrossVV(u.rB,H));c.normalImpulse=z.x;u.normalImpulse=z.y;break}break}this.m_velocities[f].w=q;this.m_velocities[g].w=t}};goog.exportProperty(box2d.b2ContactSolver.prototype,\"SolveVelocityConstraints\",box2d.b2ContactSolver.prototype.SolveVelocityConstraints);box2d.b2ContactSolver.prototype.SolveVelocityConstraints.s_dv=new box2d.b2Vec2;\nbox2d.b2ContactSolver.prototype.SolveVelocityConstraints.s_dv1=new box2d.b2Vec2;box2d.b2ContactSolver.prototype.SolveVelocityConstraints.s_dv2=new box2d.b2Vec2;box2d.b2ContactSolver.prototype.SolveVelocityConstraints.s_P=new box2d.b2Vec2;box2d.b2ContactSolver.prototype.SolveVelocityConstraints.s_a=new box2d.b2Vec2;box2d.b2ContactSolver.prototype.SolveVelocityConstraints.s_b=new box2d.b2Vec2;box2d.b2ContactSolver.prototype.SolveVelocityConstraints.s_x=new box2d.b2Vec2;\nbox2d.b2ContactSolver.prototype.SolveVelocityConstraints.s_d=new box2d.b2Vec2;box2d.b2ContactSolver.prototype.SolveVelocityConstraints.s_P1=new box2d.b2Vec2;box2d.b2ContactSolver.prototype.SolveVelocityConstraints.s_P2=new box2d.b2Vec2;box2d.b2ContactSolver.prototype.SolveVelocityConstraints.s_P1P2=new box2d.b2Vec2;\nbox2d.b2ContactSolver.prototype.StoreImpulses=function(){var a,b,c,e,d,f;a=0;for(b=this.m_count;a<b;++a)for(d=this.m_velocityConstraints[a],f=this.m_contacts[d.contactIndex].GetManifold(),c=0,e=d.pointCount;c<e;++c)f.points[c].normalImpulse=d.points[c].normalImpulse,f.points[c].tangentImpulse=d.points[c].tangentImpulse};goog.exportProperty(box2d.b2ContactSolver.prototype,\"StoreImpulses\",box2d.b2ContactSolver.prototype.StoreImpulses);\nbox2d.b2PositionSolverManifold=function(){this.normal=new box2d.b2Vec2;this.point=new box2d.b2Vec2};goog.exportSymbol(\"box2d.b2PositionSolverManifold\",box2d.b2PositionSolverManifold);box2d.b2PositionSolverManifold.prototype.normal=null;goog.exportProperty(box2d.b2PositionSolverManifold.prototype,\"normal\",box2d.b2PositionSolverManifold.prototype.normal);box2d.b2PositionSolverManifold.prototype.point=null;goog.exportProperty(box2d.b2PositionSolverManifold.prototype,\"point\",box2d.b2PositionSolverManifold.prototype.point);\nbox2d.b2PositionSolverManifold.prototype.separation=0;goog.exportProperty(box2d.b2PositionSolverManifold.prototype,\"separation\",box2d.b2PositionSolverManifold.prototype.separation);\nbox2d.b2PositionSolverManifold.prototype.Initialize=function(a,b,c,e){var d=box2d.b2PositionSolverManifold.prototype.Initialize.s_pointA,f=box2d.b2PositionSolverManifold.prototype.Initialize.s_pointB,g=box2d.b2PositionSolverManifold.prototype.Initialize.s_planePoint,h=box2d.b2PositionSolverManifold.prototype.Initialize.s_clipPoint;box2d.ENABLE_ASSERTS&&box2d.b2Assert(0<a.pointCount);switch(a.type){case box2d.b2ManifoldType.e_circles:box2d.b2MulXV(b,a.localPoint,d);box2d.b2MulXV(c,a.localPoints[0],\nf);box2d.b2SubVV(f,d,this.normal).SelfNormalize();box2d.b2MidVV(d,f,this.point);this.separation=box2d.b2DotVV(box2d.b2SubVV(f,d,box2d.b2Vec2.s_t0),this.normal)-a.radiusA-a.radiusB;break;case box2d.b2ManifoldType.e_faceA:box2d.b2MulRV(b.q,a.localNormal,this.normal);box2d.b2MulXV(b,a.localPoint,g);box2d.b2MulXV(c,a.localPoints[e],h);this.separation=box2d.b2DotVV(box2d.b2SubVV(h,g,box2d.b2Vec2.s_t0),this.normal)-a.radiusA-a.radiusB;this.point.Copy(h);break;case box2d.b2ManifoldType.e_faceB:box2d.b2MulRV(c.q,\na.localNormal,this.normal),box2d.b2MulXV(c,a.localPoint,g),box2d.b2MulXV(b,a.localPoints[e],h),this.separation=box2d.b2DotVV(box2d.b2SubVV(h,g,box2d.b2Vec2.s_t0),this.normal)-a.radiusA-a.radiusB,this.point.Copy(h),this.normal.SelfNeg()}};goog.exportProperty(box2d.b2PositionSolverManifold.prototype,\"Initialize\",box2d.b2PositionSolverManifold.prototype.Initialize);box2d.b2PositionSolverManifold.prototype.Initialize.s_pointA=new box2d.b2Vec2;\nbox2d.b2PositionSolverManifold.prototype.Initialize.s_pointB=new box2d.b2Vec2;box2d.b2PositionSolverManifold.prototype.Initialize.s_planePoint=new box2d.b2Vec2;box2d.b2PositionSolverManifold.prototype.Initialize.s_clipPoint=new box2d.b2Vec2;\nbox2d.b2ContactSolver.prototype.SolvePositionConstraints=function(){var a,b,c,e,d,f,g,h,l,k,m,n,p,q,r,t,s,u=box2d.b2ContactSolver.prototype.SolvePositionConstraints.s_xfA,v=box2d.b2ContactSolver.prototype.SolvePositionConstraints.s_xfB,y=box2d.b2ContactSolver.prototype.SolvePositionConstraints.s_psm,D,x,w,C=box2d.b2ContactSolver.prototype.SolvePositionConstraints.s_rA,A=box2d.b2ContactSolver.prototype.SolvePositionConstraints.s_rB,E,B=box2d.b2ContactSolver.prototype.SolvePositionConstraints.s_P,z=\n0;a=0;for(b=this.m_count;a<b;++a){d=this.m_positionConstraints[a];f=d.indexA;g=d.indexB;h=d.localCenterA;l=d.invMassA;k=d.invIA;m=d.localCenterB;n=d.invMassB;p=d.invIB;e=d.pointCount;q=this.m_positions[f].c;r=this.m_positions[f].a;t=this.m_positions[g].c;s=this.m_positions[g].a;for(c=0;c<e;++c)u.q.SetAngleRadians(r),v.q.SetAngleRadians(s),box2d.b2SubVV(q,box2d.b2MulRV(u.q,h,box2d.b2Vec2.s_t0),u.p),box2d.b2SubVV(t,box2d.b2MulRV(v.q,m,box2d.b2Vec2.s_t0),v.p),y.Initialize(d,u,v,c),D=y.normal,x=y.point,\nw=y.separation,box2d.b2SubVV(x,q,C),box2d.b2SubVV(x,t,A),z=box2d.b2Min(z,w),x=box2d.b2Clamp(box2d.b2_baumgarte*(w+box2d.b2_linearSlop),-box2d.b2_maxLinearCorrection,0),w=box2d.b2CrossVV(C,D),E=box2d.b2CrossVV(A,D),w=l+n+k*w*w+p*E*E,x=0<w?-x/w:0,box2d.b2MulSV(x,D,B),q.SelfMulSub(l,B),r-=k*box2d.b2CrossVV(C,B),t.SelfMulAdd(n,B),s+=p*box2d.b2CrossVV(A,B);this.m_positions[f].a=r;this.m_positions[g].a=s}return z>-3*box2d.b2_linearSlop};\ngoog.exportProperty(box2d.b2ContactSolver.prototype,\"SolvePositionConstraints\",box2d.b2ContactSolver.prototype.SolvePositionConstraints);box2d.b2ContactSolver.prototype.SolvePositionConstraints.s_xfA=new box2d.b2Transform;box2d.b2ContactSolver.prototype.SolvePositionConstraints.s_xfB=new box2d.b2Transform;box2d.b2ContactSolver.prototype.SolvePositionConstraints.s_psm=new box2d.b2PositionSolverManifold;box2d.b2ContactSolver.prototype.SolvePositionConstraints.s_rA=new box2d.b2Vec2;\nbox2d.b2ContactSolver.prototype.SolvePositionConstraints.s_rB=new box2d.b2Vec2;box2d.b2ContactSolver.prototype.SolvePositionConstraints.s_P=new box2d.b2Vec2;\nbox2d.b2ContactSolver.prototype.SolveTOIPositionConstraints=function(a,b){var c,e,d,f,g,h,l,k,m,n,p,q,r,t,s,u,v,y=box2d.b2ContactSolver.prototype.SolveTOIPositionConstraints.s_xfA,D=box2d.b2ContactSolver.prototype.SolveTOIPositionConstraints.s_xfB,x=box2d.b2ContactSolver.prototype.SolveTOIPositionConstraints.s_psm,w,C,A,E=box2d.b2ContactSolver.prototype.SolveTOIPositionConstraints.s_rA,B=box2d.b2ContactSolver.prototype.SolveTOIPositionConstraints.s_rB,z,G=box2d.b2ContactSolver.prototype.SolveTOIPositionConstraints.s_P,\nF=0;c=0;for(e=this.m_count;c<e;++c){g=this.m_positionConstraints[c];h=g.indexA;l=g.indexB;k=g.localCenterA;m=g.localCenterB;f=g.pointCount;p=n=0;if(h===a||h===b)n=g.invMassA,p=g.invIA;r=q=0;if(l===a||l===b)q=g.invMassB,r=g.invIB;t=this.m_positions[h].c;s=this.m_positions[h].a;u=this.m_positions[l].c;v=this.m_positions[l].a;for(d=0;d<f;++d)y.q.SetAngleRadians(s),D.q.SetAngleRadians(v),box2d.b2SubVV(t,box2d.b2MulRV(y.q,k,box2d.b2Vec2.s_t0),y.p),box2d.b2SubVV(u,box2d.b2MulRV(D.q,m,box2d.b2Vec2.s_t0),\nD.p),x.Initialize(g,y,D,d),w=x.normal,C=x.point,A=x.separation,box2d.b2SubVV(C,t,E),box2d.b2SubVV(C,u,B),F=box2d.b2Min(F,A),C=box2d.b2Clamp(box2d.b2_toiBaumgarte*(A+box2d.b2_linearSlop),-box2d.b2_maxLinearCorrection,0),A=box2d.b2CrossVV(E,w),z=box2d.b2CrossVV(B,w),A=n+q+p*A*A+r*z*z,C=0<A?-C/A:0,box2d.b2MulSV(C,w,G),t.SelfMulSub(n,G),s-=p*box2d.b2CrossVV(E,G),u.SelfMulAdd(q,G),v+=r*box2d.b2CrossVV(B,G);this.m_positions[h].a=s;this.m_positions[l].a=v}return F>=-1.5*box2d.b2_linearSlop};\ngoog.exportProperty(box2d.b2ContactSolver.prototype,\"SolveTOIPositionConstraints\",box2d.b2ContactSolver.prototype.SolveTOIPositionConstraints);box2d.b2ContactSolver.prototype.SolveTOIPositionConstraints.s_xfA=new box2d.b2Transform;box2d.b2ContactSolver.prototype.SolveTOIPositionConstraints.s_xfB=new box2d.b2Transform;box2d.b2ContactSolver.prototype.SolveTOIPositionConstraints.s_psm=new box2d.b2PositionSolverManifold;box2d.b2ContactSolver.prototype.SolveTOIPositionConstraints.s_rA=new box2d.b2Vec2;\nbox2d.b2ContactSolver.prototype.SolveTOIPositionConstraints.s_rB=new box2d.b2Vec2;box2d.b2ContactSolver.prototype.SolveTOIPositionConstraints.s_P=new box2d.b2Vec2;box2d.b2WorldCallbacks={};box2d.b2DestructionListener=function(){};goog.exportSymbol(\"box2d.b2DestructionListener\",box2d.b2DestructionListener);box2d.b2DestructionListener.prototype.SayGoodbyeJoint=function(a){};goog.exportProperty(box2d.b2DestructionListener.prototype,\"SayGoodbyeJoint\",box2d.b2DestructionListener.prototype.SayGoodbyeJoint);box2d.b2DestructionListener.prototype.SayGoodbyeFixture=function(a){};goog.exportProperty(box2d.b2DestructionListener.prototype,\"SayGoodbyeFixture\",box2d.b2DestructionListener.prototype.SayGoodbyeFixture);\nbox2d.b2ContactFilter=function(){};goog.exportSymbol(\"box2d.b2ContactFilter\",box2d.b2ContactFilter);box2d.b2ContactFilter.prototype.ShouldCollide=function(a,b){var c=a.GetFilterData(),e=b.GetFilterData();return c.groupIndex===e.groupIndex&&0!==c.groupIndex?0<c.groupIndex:0!==(c.maskBits&e.categoryBits)&&0!==(c.categoryBits&e.maskBits)};goog.exportProperty(box2d.b2ContactFilter.prototype,\"ShouldCollide\",box2d.b2ContactFilter.prototype.ShouldCollide);box2d.b2ContactFilter.b2_defaultFilter=new box2d.b2ContactFilter;\nbox2d.b2ContactImpulse=function(){this.normalImpulses=box2d.b2MakeNumberArray(box2d.b2_maxManifoldPoints);this.tangentImpulses=box2d.b2MakeNumberArray(box2d.b2_maxManifoldPoints)};goog.exportSymbol(\"box2d.b2ContactImpulse\",box2d.b2ContactImpulse);box2d.b2ContactImpulse.prototype.normalImpulses=null;box2d.b2ContactImpulse.prototype.tangentImpulses=null;box2d.b2ContactImpulse.prototype.count=0;box2d.b2ContactListener=function(){};goog.exportSymbol(\"box2d.b2ContactListener\",box2d.b2ContactListener);\nbox2d.b2ContactListener.prototype.BeginContact=function(a){};goog.exportProperty(box2d.b2ContactListener.prototype,\"BeginContact\",box2d.b2ContactListener.prototype.BeginContact);box2d.b2ContactListener.prototype.EndContact=function(a){};goog.exportProperty(box2d.b2ContactListener.prototype,\"EndContact\",box2d.b2ContactListener.prototype.EndContact);box2d.b2ContactListener.prototype.PreSolve=function(a,b){};goog.exportProperty(box2d.b2ContactListener.prototype,\"PreSolve\",box2d.b2ContactListener.prototype.PreSolve);\nbox2d.b2ContactListener.prototype.PostSolve=function(a,b){};goog.exportProperty(box2d.b2ContactListener.prototype,\"PostSolve\",box2d.b2ContactListener.prototype.PostSolve);box2d.b2ContactListener.b2_defaultListener=new box2d.b2ContactListener;goog.exportProperty(box2d.b2ContactListener,\"b2_defaultListener\",box2d.b2ContactListener.b2_defaultListener);box2d.b2QueryCallback=function(){};goog.exportSymbol(\"box2d.b2QueryCallback\",box2d.b2QueryCallback);box2d.b2QueryCallback.prototype.ReportFixture=function(a){return!0};\ngoog.exportProperty(box2d.b2QueryCallback.prototype,\"ReportFixture\",box2d.b2QueryCallback.prototype.ReportFixture);box2d.b2RayCastCallback=function(){};goog.exportSymbol(\"box2d.b2RayCastCallback\",box2d.b2RayCastCallback);box2d.b2RayCastCallback.prototype.ReportFixture=function(a,b,c,e){return e};goog.exportProperty(box2d.b2RayCastCallback.prototype,\"ReportFixture\",box2d.b2RayCastCallback.prototype.ReportFixture);box2d.b2Island=function(){this.m_bodies=Array(1024);this.m_contacts=Array(1024);this.m_joints=Array(1024);this.m_positions=box2d.b2Position.MakeArray(1024);this.m_velocities=box2d.b2Velocity.MakeArray(1024)};goog.exportSymbol(\"box2d.b2Island\",box2d.b2Island);box2d.b2Island.prototype.m_allocator=null;goog.exportProperty(box2d.b2Island.prototype,\"m_allocator\",box2d.b2Island.prototype.m_allocator);box2d.b2Island.prototype.m_listener=null;goog.exportProperty(box2d.b2Island.prototype,\"m_listener\",box2d.b2Island.prototype.m_listener);\nbox2d.b2Island.prototype.m_bodies=null;goog.exportProperty(box2d.b2Island.prototype,\"m_bodies\",box2d.b2Island.prototype.m_bodies);box2d.b2Island.prototype.m_contacts=null;goog.exportProperty(box2d.b2Island.prototype,\"m_contacts\",box2d.b2Island.prototype.m_contacts);box2d.b2Island.prototype.m_joints=null;goog.exportProperty(box2d.b2Island.prototype,\"m_joints\",box2d.b2Island.prototype.m_joints);box2d.b2Island.prototype.m_positions=null;goog.exportProperty(box2d.b2Island.prototype,\"m_positions\",box2d.b2Island.prototype.m_positions);\nbox2d.b2Island.prototype.m_velocities=null;goog.exportProperty(box2d.b2Island.prototype,\"m_velocities\",box2d.b2Island.prototype.m_velocities);box2d.b2Island.prototype.m_bodyCount=0;goog.exportProperty(box2d.b2Island.prototype,\"m_bodyCount\",box2d.b2Island.prototype.m_bodyCount);box2d.b2Island.prototype.m_jointCount=0;goog.exportProperty(box2d.b2Island.prototype,\"m_jointCount\",box2d.b2Island.prototype.m_jointCount);box2d.b2Island.prototype.m_contactCount=0;\ngoog.exportProperty(box2d.b2Island.prototype,\"m_contactCount\",box2d.b2Island.prototype.m_contactCount);box2d.b2Island.prototype.m_bodyCapacity=0;goog.exportProperty(box2d.b2Island.prototype,\"m_bodyCapacity\",box2d.b2Island.prototype.m_bodyCapacity);box2d.b2Island.prototype.m_contactCapacity=0;goog.exportProperty(box2d.b2Island.prototype,\"m_contactCapacity\",box2d.b2Island.prototype.m_contactCapacity);box2d.b2Island.prototype.m_jointCapacity=0;\ngoog.exportProperty(box2d.b2Island.prototype,\"m_jointCapacity\",box2d.b2Island.prototype.m_jointCapacity);\nbox2d.b2Island.prototype.Initialize=function(a,b,c,e,d){this.m_bodyCapacity=a;this.m_contactCapacity=b;this.m_jointCapacity=c;this.m_jointCount=this.m_contactCount=this.m_bodyCount=0;this.m_allocator=e;for(this.m_listener=d;this.m_bodies.length<a;)this.m_bodies[this.m_bodies.length]=null;for(;this.m_contacts.length<b;)this.m_contacts[this.m_contacts.length]=null;for(;this.m_joints.length<c;)this.m_joints[this.m_joints.length]=null;if(this.m_positions.length<a)for(b=box2d.b2Max(2*this.m_positions.length,\na),box2d.DEBUG&&window.console.log(\"box2d.b2Island.m_positions: \"+b);this.m_positions.length<b;)this.m_positions[this.m_positions.length]=new box2d.b2Position;if(this.m_velocities.length<a)for(b=box2d.b2Max(2*this.m_velocities.length,a),box2d.DEBUG&&window.console.log(\"box2d.b2Island.m_velocities: \"+b);this.m_velocities.length<b;)this.m_velocities[this.m_velocities.length]=new box2d.b2Velocity};goog.exportProperty(box2d.b2Island.prototype,\"Initialize\",box2d.b2Island.prototype.Initialize);\nbox2d.b2Island.prototype.Clear=function(){this.m_jointCount=this.m_contactCount=this.m_bodyCount=0};goog.exportProperty(box2d.b2Island.prototype,\"Clear\",box2d.b2Island.prototype.Clear);box2d.b2Island.prototype.AddBody=function(a){box2d.ENABLE_ASSERTS&&box2d.b2Assert(this.m_bodyCount<this.m_bodyCapacity);a.m_islandIndex=this.m_bodyCount;this.m_bodies[this.m_bodyCount++]=a};goog.exportProperty(box2d.b2Island.prototype,\"AddBody\",box2d.b2Island.prototype.AddBody);\nbox2d.b2Island.prototype.AddContact=function(a){box2d.ENABLE_ASSERTS&&box2d.b2Assert(this.m_contactCount<this.m_contactCapacity);this.m_contacts[this.m_contactCount++]=a};goog.exportProperty(box2d.b2Island.prototype,\"AddContact\",box2d.b2Island.prototype.AddContact);box2d.b2Island.prototype.AddJoint=function(a){box2d.ENABLE_ASSERTS&&box2d.b2Assert(this.m_jointCount<this.m_jointCapacity);this.m_joints[this.m_jointCount++]=a};goog.exportProperty(box2d.b2Island.prototype,\"AddJoint\",box2d.b2Island.prototype.AddJoint);\nbox2d.b2Island.prototype.Solve=function(a,b,c,e){for(var d=box2d.b2Island.s_timer.Reset(),f=b.dt,g=0;g<this.m_bodyCount;++g){var h=this.m_bodies[g],l=this.m_positions[g].c.Copy(h.m_sweep.c),k=h.m_sweep.a,m=this.m_velocities[g].v.Copy(h.m_linearVelocity),n=h.m_angularVelocity;h.m_sweep.c0.Copy(h.m_sweep.c);h.m_sweep.a0=h.m_sweep.a;h.m_type===box2d.b2BodyType.b2_dynamicBody&&(m.x+=f*(h.m_gravityScale*c.x+h.m_invMass*h.m_force.x),m.y+=f*(h.m_gravityScale*c.y+h.m_invMass*h.m_force.y),n+=f*h.m_invI*h.m_torque,\nm.SelfMul(1/(1+f*h.m_linearDamping)),n*=1/(1+f*h.m_angularDamping));this.m_positions[g].a=k;this.m_velocities[g].w=n}d.Reset();h=box2d.b2Island.s_solverData;h.step.Copy(b);h.positions=this.m_positions;h.velocities=this.m_velocities;g=box2d.b2Island.s_contactSolverDef;g.step.Copy(b);g.contacts=this.m_contacts;g.count=this.m_contactCount;g.positions=this.m_positions;g.velocities=this.m_velocities;g.allocator=this.m_allocator;c=box2d.b2Island.s_contactSolver.Initialize(g);c.InitializeVelocityConstraints();\nb.warmStarting&&c.WarmStart();for(g=0;g<this.m_jointCount;++g)this.m_joints[g].InitVelocityConstraints(h);a.solveInit=d.GetMilliseconds();d.Reset();for(g=0;g<b.velocityIterations;++g){for(k=0;k<this.m_jointCount;++k)this.m_joints[k].SolveVelocityConstraints(h);c.SolveVelocityConstraints()}c.StoreImpulses();a.solveVelocity=d.GetMilliseconds();for(g=0;g<this.m_bodyCount;++g){var l=this.m_positions[g].c,k=this.m_positions[g].a,m=this.m_velocities[g].v,n=this.m_velocities[g].w,p=box2d.b2MulSV(f,m,box2d.b2Island.s_translation);\nbox2d.b2DotVV(p,p)>box2d.b2_maxTranslationSquared&&(p=box2d.b2_maxTranslation/p.GetLength(),m.SelfMul(p));p=f*n;p*p>box2d.b2_maxRotationSquared&&(p=box2d.b2_maxRotation/box2d.b2Abs(p),n*=p);l.x+=f*m.x;l.y+=f*m.y;k+=f*n;this.m_positions[g].a=k;this.m_velocities[g].w=n}d.Reset();l=!1;for(g=0;g<b.positionIterations;++g){m=c.SolvePositionConstraints();n=!0;for(k=0;k<this.m_jointCount;++k)p=this.m_joints[k].SolvePositionConstraints(h),n=n&&p;if(m&&n){l=!0;break}}for(g=0;g<this.m_bodyCount;++g)b=this.m_bodies[g],\nb.m_sweep.c.Copy(this.m_positions[g].c),b.m_sweep.a=this.m_positions[g].a,b.m_linearVelocity.Copy(this.m_velocities[g].v),b.m_angularVelocity=this.m_velocities[g].w,b.SynchronizeTransform();a.solvePosition=d.GetMilliseconds();this.Report(c.m_velocityConstraints);if(e){a=box2d.b2_maxFloat;e=box2d.b2_linearSleepTolerance*box2d.b2_linearSleepTolerance;d=box2d.b2_angularSleepTolerance*box2d.b2_angularSleepTolerance;for(g=0;g<this.m_bodyCount;++g)h=this.m_bodies[g],h.GetType()!==box2d.b2BodyType.b2_staticBody&&\n(0===(h.m_flags&box2d.b2BodyFlag.e_autoSleepFlag)||h.m_angularVelocity*h.m_angularVelocity>d||box2d.b2DotVV(h.m_linearVelocity,h.m_linearVelocity)>e?a=h.m_sleepTime=0:(h.m_sleepTime+=f,a=box2d.b2Min(a,h.m_sleepTime)));if(a>=box2d.b2_timeToSleep&&l)for(g=0;g<this.m_bodyCount;++g)h=this.m_bodies[g],h.SetAwake(!1)}};goog.exportProperty(box2d.b2Island.prototype,\"Solve\",box2d.b2Island.prototype.Solve);\nbox2d.b2Island.prototype.SolveTOI=function(a,b,c){box2d.ENABLE_ASSERTS&&box2d.b2Assert(b<this.m_bodyCount);box2d.ENABLE_ASSERTS&&box2d.b2Assert(c<this.m_bodyCount);for(var e=0;e<this.m_bodyCount;++e){var d=this.m_bodies[e];this.m_positions[e].c.Copy(d.m_sweep.c);this.m_positions[e].a=d.m_sweep.a;this.m_velocities[e].v.Copy(d.m_linearVelocity);this.m_velocities[e].w=d.m_angularVelocity}e=box2d.b2Island.s_contactSolverDef;e.contacts=this.m_contacts;e.count=this.m_contactCount;e.allocator=this.m_allocator;\ne.step.Copy(a);e.positions=this.m_positions;e.velocities=this.m_velocities;d=box2d.b2Island.s_contactSolver.Initialize(e);for(e=0;e<a.positionIterations&&!d.SolveTOIPositionConstraints(b,c);++e);this.m_bodies[b].m_sweep.c0.Copy(this.m_positions[b].c);this.m_bodies[b].m_sweep.a0=this.m_positions[b].a;this.m_bodies[c].m_sweep.c0.Copy(this.m_positions[c].c);this.m_bodies[c].m_sweep.a0=this.m_positions[c].a;d.InitializeVelocityConstraints();for(e=0;e<a.velocityIterations;++e)d.SolveVelocityConstraints();\na=a.dt;for(e=0;e<this.m_bodyCount;++e){b=this.m_positions[e].c;c=this.m_positions[e].a;var f=this.m_velocities[e].v,g=this.m_velocities[e].w,h=box2d.b2MulSV(a,f,box2d.b2Island.s_translation);box2d.b2DotVV(h,h)>box2d.b2_maxTranslationSquared&&(h=box2d.b2_maxTranslation/h.GetLength(),f.SelfMul(h));h=a*g;h*h>box2d.b2_maxRotationSquared&&(h=box2d.b2_maxRotation/box2d.b2Abs(h),g*=h);b.SelfMulAdd(a,f);c+=a*g;this.m_positions[e].a=c;this.m_velocities[e].w=g;h=this.m_bodies[e];h.m_sweep.c.Copy(b);h.m_sweep.a=\nc;h.m_linearVelocity.Copy(f);h.m_angularVelocity=g;h.SynchronizeTransform()}this.Report(d.m_velocityConstraints)};goog.exportProperty(box2d.b2Island.prototype,\"SolveTOI\",box2d.b2Island.prototype.SolveTOI);\nbox2d.b2Island.prototype.Report=function(a){if(null!==this.m_listener)for(var b=0;b<this.m_contactCount;++b){var c=this.m_contacts[b];if(c){var e=a[b],d=box2d.b2Island.s_impulse;d.count=e.pointCount;for(var f=0;f<e.pointCount;++f)d.normalImpulses[f]=e.points[f].normalImpulse,d.tangentImpulses[f]=e.points[f].tangentImpulse;this.m_listener.PostSolve(c,d)}}};goog.exportProperty(box2d.b2Island.prototype,\"Report\",box2d.b2Island.prototype.Report);box2d.b2Island.s_timer=new box2d.b2Timer;\nbox2d.b2Island.s_solverData=new box2d.b2SolverData;box2d.b2Island.s_contactSolverDef=new box2d.b2ContactSolverDef;box2d.b2Island.s_contactSolver=new box2d.b2ContactSolver;box2d.b2Island.s_translation=new box2d.b2Vec2;box2d.b2Island.s_impulse=new box2d.b2ContactImpulse;box2d.b2ContactRegister=function(){};goog.exportSymbol(\"box2d.b2ContactRegister\",box2d.b2ContactRegister);box2d.b2ContactRegister.prototype.createFcn=null;box2d.b2ContactRegister.prototype.destroyFcn=null;box2d.b2ContactRegister.prototype.primary=!1;box2d.b2ContactFactory=function(a){this.m_allocator=a;this.InitializeRegisters()};goog.exportSymbol(\"box2d.b2ContactFactory\",box2d.b2ContactFactory);box2d.b2ContactFactory.prototype.m_allocator=null;\nbox2d.b2ContactFactory.prototype.AddType=function(a,b,c,e){var d=box2d.b2MakeArray(256,function(b){return a()});b=function(b){return 0<d.length?d.pop():a(b)};var f=function(a,b){d.push(a)};this.m_registers[c][e].pool=d;this.m_registers[c][e].createFcn=b;this.m_registers[c][e].destroyFcn=f;this.m_registers[c][e].primary=!0;c!==e&&(this.m_registers[e][c].pool=d,this.m_registers[e][c].createFcn=b,this.m_registers[e][c].destroyFcn=f,this.m_registers[e][c].primary=!1)};\ngoog.exportProperty(box2d.b2ContactFactory.prototype,\"AddType\",box2d.b2ContactFactory.prototype.AddType);\nbox2d.b2ContactFactory.prototype.InitializeRegisters=function(){this.m_registers=Array(box2d.b2ShapeType.e_shapeTypeCount);for(var a=0;a<box2d.b2ShapeType.e_shapeTypeCount;a++){this.m_registers[a]=Array(box2d.b2ShapeType.e_shapeTypeCount);for(var b=0;b<box2d.b2ShapeType.e_shapeTypeCount;b++)this.m_registers[a][b]=new box2d.b2ContactRegister}this.AddType(box2d.b2CircleContact.Create,box2d.b2CircleContact.Destroy,box2d.b2ShapeType.e_circleShape,box2d.b2ShapeType.e_circleShape);this.AddType(box2d.b2PolygonAndCircleContact.Create,\nbox2d.b2PolygonAndCircleContact.Destroy,box2d.b2ShapeType.e_polygonShape,box2d.b2ShapeType.e_circleShape);this.AddType(box2d.b2PolygonContact.Create,box2d.b2PolygonContact.Destroy,box2d.b2ShapeType.e_polygonShape,box2d.b2ShapeType.e_polygonShape);this.AddType(box2d.b2EdgeAndCircleContact.Create,box2d.b2EdgeAndCircleContact.Destroy,box2d.b2ShapeType.e_edgeShape,box2d.b2ShapeType.e_circleShape);this.AddType(box2d.b2EdgeAndPolygonContact.Create,box2d.b2EdgeAndPolygonContact.Destroy,box2d.b2ShapeType.e_edgeShape,\nbox2d.b2ShapeType.e_polygonShape);this.AddType(box2d.b2ChainAndCircleContact.Create,box2d.b2ChainAndCircleContact.Destroy,box2d.b2ShapeType.e_chainShape,box2d.b2ShapeType.e_circleShape);this.AddType(box2d.b2ChainAndPolygonContact.Create,box2d.b2ChainAndPolygonContact.Destroy,box2d.b2ShapeType.e_chainShape,box2d.b2ShapeType.e_polygonShape)};goog.exportProperty(box2d.b2ContactFactory.prototype,\"InitializeRegisters\",box2d.b2ContactFactory.prototype.InitializeRegisters);\nbox2d.b2ContactFactory.prototype.Create=function(a,b,c,e){var d=a.GetType(),f=c.GetType();box2d.ENABLE_ASSERTS&&box2d.b2Assert(0<=d&&d<box2d.b2ShapeType.e_shapeTypeCount);box2d.ENABLE_ASSERTS&&box2d.b2Assert(0<=f&&f<box2d.b2ShapeType.e_shapeTypeCount);d=this.m_registers[d][f];f=d.createFcn;return null!==f?(d.primary?(d=f(this.m_allocator),d.Reset(a,b,c,e)):(d=f(this.m_allocator),d.Reset(c,e,a,b)),d):null};goog.exportProperty(box2d.b2ContactFactory.prototype,\"Create\",box2d.b2ContactFactory.prototype.Create);\nbox2d.b2ContactFactory.prototype.Destroy=function(a){var b=a.m_fixtureA,c=a.m_fixtureB;0<a.m_manifold.pointCount&&!1===b.IsSensor()&&!1===c.IsSensor()&&(b.GetBody().SetAwake(!0),c.GetBody().SetAwake(!0));b=b.GetType();c=c.GetType();box2d.ENABLE_ASSERTS&&box2d.b2Assert(0<=b&&c<box2d.b2ShapeType.e_shapeTypeCount);box2d.ENABLE_ASSERTS&&box2d.b2Assert(0<=b&&c<box2d.b2ShapeType.e_shapeTypeCount);c=this.m_registers[b][c].destroyFcn;c(a,this.m_allocator)};\ngoog.exportProperty(box2d.b2ContactFactory.prototype,\"Destroy\",box2d.b2ContactFactory.prototype.Destroy);box2d.b2GrowableStack=function(a){this.m_stack=Array(a)};goog.exportSymbol(\"box2d.b2GrowableStack\",box2d.b2GrowableStack);box2d.b2GrowableStack.prototype.m_stack=null;goog.exportProperty(box2d.b2GrowableStack.prototype,\"m_stack\",box2d.b2GrowableStack.prototype.m_stack);box2d.b2GrowableStack.prototype.m_count=0;goog.exportProperty(box2d.b2GrowableStack.prototype,\"m_count\",box2d.b2GrowableStack.prototype.m_count);box2d.b2GrowableStack.prototype.Reset=function(){this.m_count=0;return this};\ngoog.exportProperty(box2d.b2GrowableStack.prototype,\"Reset\",box2d.b2GrowableStack.prototype.Reset);box2d.b2GrowableStack.prototype.Push=function(a){this.m_stack[this.m_count]=a;++this.m_count};goog.exportProperty(box2d.b2GrowableStack.prototype,\"Push\",box2d.b2GrowableStack.prototype.Push);box2d.b2GrowableStack.prototype.Pop=function(){box2d.ENABLE_ASSERTS&&box2d.b2Assert(0<this.m_count);--this.m_count;var a=this.m_stack[this.m_count];this.m_stack[this.m_count]=null;return a};\ngoog.exportProperty(box2d.b2GrowableStack.prototype,\"Pop\",box2d.b2GrowableStack.prototype.Pop);box2d.b2GrowableStack.prototype.GetCount=function(){return this.m_count};goog.exportProperty(box2d.b2GrowableStack.prototype,\"GetCount\",box2d.b2GrowableStack.prototype.GetCount);box2d.b2TreeNode=function(a){this.m_id=a||0;this.aabb=new box2d.b2AABB};goog.exportSymbol(\"box2d.b2TreeNode\",box2d.b2TreeNode);box2d.b2TreeNode.prototype.m_id=0;goog.exportProperty(box2d.b2TreeNode.prototype,\"m_id\",box2d.b2TreeNode.prototype.m_id);box2d.b2TreeNode.prototype.aabb=null;goog.exportProperty(box2d.b2TreeNode.prototype,\"aabb\",box2d.b2TreeNode.prototype.aabb);box2d.b2TreeNode.prototype.userData=null;goog.exportProperty(box2d.b2TreeNode.prototype,\"userData\",box2d.b2TreeNode.prototype.userData);\nbox2d.b2TreeNode.prototype.parent=null;goog.exportProperty(box2d.b2TreeNode.prototype,\"parent\",box2d.b2TreeNode.prototype.parent);box2d.b2TreeNode.prototype.child1=null;goog.exportProperty(box2d.b2TreeNode.prototype,\"child1\",box2d.b2TreeNode.prototype.child1);box2d.b2TreeNode.prototype.child2=null;goog.exportProperty(box2d.b2TreeNode.prototype,\"child2\",box2d.b2TreeNode.prototype.child2);box2d.b2TreeNode.prototype.height=0;goog.exportProperty(box2d.b2TreeNode.prototype,\"height\",box2d.b2TreeNode.prototype.height);\nbox2d.b2TreeNode.prototype.IsLeaf=function(){return null===this.child1};goog.exportProperty(box2d.b2TreeNode.prototype,\"IsLeaf\",box2d.b2TreeNode.prototype.IsLeaf);box2d.b2DynamicTree=function(){};goog.exportSymbol(\"box2d.b2DynamicTree\",box2d.b2DynamicTree);box2d.b2DynamicTree.prototype.m_root=null;goog.exportProperty(box2d.b2DynamicTree.prototype,\"m_root\",box2d.b2DynamicTree.prototype.m_root);box2d.b2DynamicTree.prototype.m_freeList=null;\ngoog.exportProperty(box2d.b2DynamicTree.prototype,\"m_freeList\",box2d.b2DynamicTree.prototype.m_freeList);box2d.b2DynamicTree.prototype.m_path=0;goog.exportProperty(box2d.b2DynamicTree.prototype,\"m_path\",box2d.b2DynamicTree.prototype.m_path);box2d.b2DynamicTree.prototype.m_insertionCount=0;goog.exportProperty(box2d.b2DynamicTree.prototype,\"m_insertionCount\",box2d.b2DynamicTree.prototype.m_insertionCount);box2d.b2DynamicTree.s_stack=new box2d.b2GrowableStack(256);box2d.b2DynamicTree.s_r=new box2d.b2Vec2;\nbox2d.b2DynamicTree.s_v=new box2d.b2Vec2;box2d.b2DynamicTree.s_abs_v=new box2d.b2Vec2;box2d.b2DynamicTree.s_segmentAABB=new box2d.b2AABB;box2d.b2DynamicTree.s_subInput=new box2d.b2RayCastInput;box2d.b2DynamicTree.s_combinedAABB=new box2d.b2AABB;box2d.b2DynamicTree.s_aabb=new box2d.b2AABB;box2d.b2DynamicTree.prototype.GetUserData=function(a){box2d.ENABLE_ASSERTS&&box2d.b2Assert(null!==a);return a.userData};goog.exportProperty(box2d.b2DynamicTree.prototype,\"GetUserData\",box2d.b2DynamicTree.prototype.GetUserData);\nbox2d.b2DynamicTree.prototype.GetFatAABB=function(a){box2d.ENABLE_ASSERTS&&box2d.b2Assert(null!==a);return a.aabb};goog.exportProperty(box2d.b2DynamicTree.prototype,\"GetFatAABB\",box2d.b2DynamicTree.prototype.GetFatAABB);box2d.b2DynamicTree.prototype.Query=function(a,b){if(null!==this.m_root){var c=box2d.b2DynamicTree.s_stack.Reset();for(c.Push(this.m_root);0<c.GetCount();){var e=c.Pop();if(null!==e&&e.aabb.TestOverlap(b))if(e.IsLeaf()){if(!1===a(e))break}else c.Push(e.child1),c.Push(e.child2)}}};\ngoog.exportProperty(box2d.b2DynamicTree.prototype,\"Query\",box2d.b2DynamicTree.prototype.Query);\nbox2d.b2DynamicTree.prototype.RayCast=function(a,b){if(null!==this.m_root){var c=b.p1,e=b.p2,d=box2d.b2SubVV(e,c,box2d.b2DynamicTree.s_r);box2d.ENABLE_ASSERTS&&box2d.b2Assert(0<d.GetLengthSquared());d.Normalize();var d=box2d.b2CrossOneV(d,box2d.b2DynamicTree.s_v),f=box2d.b2AbsV(d,box2d.b2DynamicTree.s_abs_v),g=b.maxFraction,h=box2d.b2DynamicTree.s_segmentAABB,l=c.x+g*(e.x-c.x),k=c.y+g*(e.y-c.y);h.lowerBound.x=box2d.b2Min(c.x,l);h.lowerBound.y=box2d.b2Min(c.y,k);h.upperBound.x=box2d.b2Max(c.x,l);h.upperBound.y=\nbox2d.b2Max(c.y,k);var m=box2d.b2DynamicTree.s_stack.Reset();for(m.Push(this.m_root);0<m.GetCount();)if(l=m.Pop(),null!==l&&!1!==box2d.b2TestOverlapAABB(l.aabb,h)){var k=l.aabb.GetCenter(),n=l.aabb.GetExtents();if(!(0<box2d.b2Abs(box2d.b2DotVV(d,box2d.b2SubVV(c,k,box2d.b2Vec2.s_t0)))-box2d.b2DotVV(f,n)))if(l.IsLeaf()){k=box2d.b2DynamicTree.s_subInput;k.p1.Copy(b.p1);k.p2.Copy(b.p2);k.maxFraction=g;l=a(k,l);if(0===l)break;0<l&&(g=l,l=c.x+g*(e.x-c.x),k=c.y+g*(e.y-c.y),h.lowerBound.x=box2d.b2Min(c.x,\nl),h.lowerBound.y=box2d.b2Min(c.y,k),h.upperBound.x=box2d.b2Max(c.x,l),h.upperBound.y=box2d.b2Max(c.y,k))}else m.Push(l.child1),m.Push(l.child2)}}};goog.exportProperty(box2d.b2DynamicTree.prototype,\"RayCast\",box2d.b2DynamicTree.prototype.RayCast);box2d.b2DynamicTree.prototype.AllocateNode=function(){if(this.m_freeList){var a=this.m_freeList;this.m_freeList=a.parent;a.parent=null;a.child1=null;a.child2=null;a.height=0;a.userData=null;return a}return new box2d.b2TreeNode(box2d.b2DynamicTree.prototype.s_node_id++)};\ngoog.exportProperty(box2d.b2DynamicTree.prototype,\"AllocateNode\",box2d.b2DynamicTree.prototype.AllocateNode);box2d.b2DynamicTree.prototype.s_node_id=0;box2d.b2DynamicTree.prototype.FreeNode=function(a){a.parent=this.m_freeList;a.height=-1;this.m_freeList=a};goog.exportProperty(box2d.b2DynamicTree.prototype,\"FreeNode\",box2d.b2DynamicTree.prototype.FreeNode);\nbox2d.b2DynamicTree.prototype.CreateProxy=function(a,b){var c=this.AllocateNode(),e=box2d.b2_aabbExtension,d=box2d.b2_aabbExtension;c.aabb.lowerBound.x=a.lowerBound.x-e;c.aabb.lowerBound.y=a.lowerBound.y-d;c.aabb.upperBound.x=a.upperBound.x+e;c.aabb.upperBound.y=a.upperBound.y+d;c.userData=b;c.height=0;this.InsertLeaf(c);return c};goog.exportProperty(box2d.b2DynamicTree.prototype,\"CreateProxy\",box2d.b2DynamicTree.prototype.CreateProxy);\nbox2d.b2DynamicTree.prototype.DestroyProxy=function(a){box2d.ENABLE_ASSERTS&&box2d.b2Assert(a.IsLeaf());this.RemoveLeaf(a);this.FreeNode(a)};goog.exportProperty(box2d.b2DynamicTree.prototype,\"DestroyProxy\",box2d.b2DynamicTree.prototype.DestroyProxy);\nbox2d.b2DynamicTree.prototype.MoveProxy=function(a,b,c){box2d.ENABLE_ASSERTS&&box2d.b2Assert(a.IsLeaf());if(a.aabb.Contains(b))return!1;this.RemoveLeaf(a);var e=box2d.b2_aabbExtension+box2d.b2_aabbMultiplier*(0<c.x?c.x:-c.x);c=box2d.b2_aabbExtension+box2d.b2_aabbMultiplier*(0<c.y?c.y:-c.y);a.aabb.lowerBound.x=b.lowerBound.x-e;a.aabb.lowerBound.y=b.lowerBound.y-c;a.aabb.upperBound.x=b.upperBound.x+e;a.aabb.upperBound.y=b.upperBound.y+c;this.InsertLeaf(a);return!0};\ngoog.exportProperty(box2d.b2DynamicTree.prototype,\"MoveProxy\",box2d.b2DynamicTree.prototype.MoveProxy);\nbox2d.b2DynamicTree.prototype.InsertLeaf=function(a){++this.m_insertionCount;if(null===this.m_root)this.m_root=a,this.m_root.parent=null;else{var b=a.aabb;b.GetCenter();for(var c=this.m_root,e,d;!1===c.IsLeaf();){e=c.child1;d=c.child2;var f=c.aabb.GetPerimeter(),g=box2d.b2DynamicTree.s_combinedAABB;g.Combine2(c.aabb,b);var h=g.GetPerimeter(),g=2*h,h=2*(h-f),l=box2d.b2DynamicTree.s_aabb,k,m;e.IsLeaf()?(l.Combine2(b,e.aabb),f=l.GetPerimeter()+h):(l.Combine2(b,e.aabb),k=e.aabb.GetPerimeter(),m=l.GetPerimeter(),\nf=m-k+h);d.IsLeaf()?(l.Combine2(b,d.aabb),h=l.GetPerimeter()+h):(l.Combine2(b,d.aabb),k=d.aabb.GetPerimeter(),m=l.GetPerimeter(),h=m-k+h);if(g<f&&g<h)break;c=f<h?e:d}e=c.parent;d=this.AllocateNode();d.parent=e;d.userData=null;d.aabb.Combine2(b,c.aabb);d.height=c.height+1;e?(e.child1===c?e.child1=d:e.child2=d,d.child1=c,d.child2=a,c.parent=d,a.parent=d):(d.child1=c,d.child2=a,c.parent=d,this.m_root=a.parent=d);for(c=a.parent;null!==c;)c=this.Balance(c),e=c.child1,d=c.child2,box2d.ENABLE_ASSERTS&&box2d.b2Assert(null!==\ne),box2d.ENABLE_ASSERTS&&box2d.b2Assert(null!==d),c.height=1+box2d.b2Max(e.height,d.height),c.aabb.Combine2(e.aabb,d.aabb),c=c.parent}};goog.exportProperty(box2d.b2DynamicTree.prototype,\"InsertLeaf\",box2d.b2DynamicTree.prototype.InsertLeaf);\nbox2d.b2DynamicTree.prototype.RemoveLeaf=function(a){if(a===this.m_root)this.m_root=null;else{var b=a.parent,c=b.parent;a=b.child1===a?b.child2:b.child1;if(c)for(c.child1===b?c.child1=a:c.child2=a,a.parent=c,this.FreeNode(b),b=c;b;)b=this.Balance(b),c=b.child1,a=b.child2,b.aabb.Combine2(c.aabb,a.aabb),b.height=1+box2d.b2Max(c.height,a.height),b=b.parent;else this.m_root=a,a.parent=null,this.FreeNode(b)}};goog.exportProperty(box2d.b2DynamicTree.prototype,\"RemoveLeaf\",box2d.b2DynamicTree.prototype.RemoveLeaf);\nbox2d.b2DynamicTree.prototype.Balance=function(a){box2d.ENABLE_ASSERTS&&box2d.b2Assert(null!==a);if(a.IsLeaf()||2>a.height)return a;var b=a.child1,c=a.child2,e=c.height-b.height;if(1<e){var e=c.child1,d=c.child2;c.child1=a;c.parent=a.parent;a.parent=c;null!==c.parent?c.parent.child1===a?c.parent.child1=c:(box2d.ENABLE_ASSERTS&&box2d.b2Assert(c.parent.child2===a),c.parent.child2=c):this.m_root=c;e.height>d.height?(c.child2=e,a.child2=d,d.parent=a,a.aabb.Combine2(b.aabb,d.aabb),c.aabb.Combine2(a.aabb,\ne.aabb),a.height=1+box2d.b2Max(b.height,d.height),c.height=1+box2d.b2Max(a.height,e.height)):(c.child2=d,a.child2=e,e.parent=a,a.aabb.Combine2(b.aabb,e.aabb),c.aabb.Combine2(a.aabb,d.aabb),a.height=1+box2d.b2Max(b.height,e.height),c.height=1+box2d.b2Max(a.height,d.height));return c}return-1>e?(e=b.child1,d=b.child2,b.child1=a,b.parent=a.parent,a.parent=b,null!==b.parent?b.parent.child1===a?b.parent.child1=b:(box2d.ENABLE_ASSERTS&&box2d.b2Assert(b.parent.child2===a),b.parent.child2=b):this.m_root=\nb,e.height>d.height?(b.child2=e,a.child1=d,d.parent=a,a.aabb.Combine2(c.aabb,d.aabb),b.aabb.Combine2(a.aabb,e.aabb),a.height=1+box2d.b2Max(c.height,d.height),b.height=1+box2d.b2Max(a.height,e.height)):(b.child2=d,a.child1=e,e.parent=a,a.aabb.Combine2(c.aabb,e.aabb),b.aabb.Combine2(a.aabb,d.aabb),a.height=1+box2d.b2Max(c.height,e.height),b.height=1+box2d.b2Max(a.height,d.height)),b):a};goog.exportProperty(box2d.b2DynamicTree.prototype,\"Balance\",box2d.b2DynamicTree.prototype.Balance);\nbox2d.b2DynamicTree.prototype.GetHeight=function(){return null===this.m_root?0:this.m_root.height};goog.exportProperty(box2d.b2DynamicTree.prototype,\"GetHeight\",box2d.b2DynamicTree.prototype.GetHeight);box2d.b2DynamicTree.prototype.GetAreaRatio=function(){if(null===this.m_root)return 0;var a=this.m_root.aabb.GetPerimeter(),b=function(a){if(null===a||a.IsLeaf())return 0;var e=a.aabb.GetPerimeter(),e=e+b(a.child1);return e+=b(a.child2)};return b(this.m_root)/a};\ngoog.exportProperty(box2d.b2DynamicTree.prototype,\"GetAreaRatio\",box2d.b2DynamicTree.prototype.GetAreaRatio);box2d.b2DynamicTree.prototype.ComputeHeightNode=function(a){if(a.IsLeaf())return 0;var b=this.ComputeHeightNode(a.child1);a=this.ComputeHeightNode(a.child2);return 1+box2d.b2Max(b,a)};goog.exportProperty(box2d.b2DynamicTree.prototype,\"ComputeHeightNode\",box2d.b2DynamicTree.prototype.ComputeHeightNode);box2d.b2DynamicTree.prototype.ComputeHeight=function(){return this.ComputeHeightNode(this.m_root)};\ngoog.exportProperty(box2d.b2DynamicTree.prototype,\"ComputeHeight\",box2d.b2DynamicTree.prototype.ComputeHeight);\nbox2d.b2DynamicTree.prototype.ValidateStructure=function(a){if(null!==a){a===this.m_root&&box2d.ENABLE_ASSERTS&&box2d.b2Assert(null===a.parent);var b=a.child1,c=a.child2;a.IsLeaf()?(box2d.ENABLE_ASSERTS&&box2d.b2Assert(null===b),box2d.ENABLE_ASSERTS&&box2d.b2Assert(null===c),box2d.ENABLE_ASSERTS&&box2d.b2Assert(0===a.height)):(box2d.ENABLE_ASSERTS&&box2d.b2Assert(b.parent===a),box2d.ENABLE_ASSERTS&&box2d.b2Assert(c.parent===a),this.ValidateStructure(b),this.ValidateStructure(c))}};\ngoog.exportProperty(box2d.b2DynamicTree.prototype,\"ValidateStructure\",box2d.b2DynamicTree.prototype.ValidateStructure);\nbox2d.b2DynamicTree.prototype.ValidateMetrics=function(a){if(null!==a){var b=a.child1,c=a.child2;if(a.IsLeaf())box2d.ENABLE_ASSERTS&&box2d.b2Assert(null===b),box2d.ENABLE_ASSERTS&&box2d.b2Assert(null===c),box2d.ENABLE_ASSERTS&&box2d.b2Assert(0===a.height);else{var e;e=1+box2d.b2Max(b.height,c.height);box2d.ENABLE_ASSERTS&&box2d.b2Assert(a.height===e);e=box2d.b2DynamicTree.s_aabb;e.Combine2(b.aabb,c.aabb);box2d.ENABLE_ASSERTS&&box2d.b2Assert(e.lowerBound===a.aabb.lowerBound);box2d.ENABLE_ASSERTS&&\nbox2d.b2Assert(e.upperBound===a.aabb.upperBound);this.ValidateMetrics(b);this.ValidateMetrics(c)}}};goog.exportProperty(box2d.b2DynamicTree.prototype,\"ValidateMetrics\",box2d.b2DynamicTree.prototype.ValidateMetrics);box2d.b2DynamicTree.prototype.Validate=function(){this.ValidateStructure(this.m_root);this.ValidateMetrics(this.m_root);for(var a=0,b=this.m_freeList;null!==b;)b=b.parent,++a;box2d.ENABLE_ASSERTS&&box2d.b2Assert(this.GetHeight()===this.ComputeHeight())};\ngoog.exportProperty(box2d.b2DynamicTree.prototype,\"Validate\",box2d.b2DynamicTree.prototype.Validate);box2d.b2DynamicTree.prototype.GetMaxBalance=function(){var a;a=this.m_root;null===a?a=0:1>=a.height?a=0:(box2d.ENABLE_ASSERTS&&box2d.b2Assert(!1===a.IsLeaf()),a=box2d.b2Abs(a.child2.height-a.child1.height),a=box2d.b2Max(0,a));return a};goog.exportProperty(box2d.b2DynamicTree.prototype,\"GetMaxBalance\",box2d.b2DynamicTree.prototype.GetMaxBalance);box2d.b2DynamicTree.prototype.RebuildBottomUp=function(){this.Validate()};\ngoog.exportProperty(box2d.b2DynamicTree.prototype,\"RebuildBottomUp\",box2d.b2DynamicTree.prototype.RebuildBottomUp);box2d.b2DynamicTree.prototype.ShiftOrigin=function(a){var b=function(a,e){if(null!==a&&!(1>=a.height)){box2d.ENABLE_ASSERTS&&box2d.b2Assert(!1===a.IsLeaf());var d=a.child2;b(a.child1,e);b(d,e);a.aabb.lowerBound.SelfSub(e);a.aabb.upperBound.SelfSub(e)}};b(this.m_root,a)};goog.exportProperty(box2d.b2DynamicTree.prototype,\"ShiftOrigin\",box2d.b2DynamicTree.prototype.ShiftOrigin);box2d.b2Pair=function(){};goog.exportSymbol(\"box2d.b2Pair\",box2d.b2Pair);box2d.b2Pair.prototype.proxyA=null;goog.exportProperty(box2d.b2Pair.prototype,\"proxyA\",box2d.b2Pair.prototype.proxyA);box2d.b2Pair.prototype.proxyB=null;goog.exportProperty(box2d.b2Pair.prototype,\"proxyB\",box2d.b2Pair.prototype.proxyB);box2d.b2BroadPhase=function(){this.m_tree=new box2d.b2DynamicTree;this.m_moveBuffer=[];this.m_pairBuffer=[]};goog.exportSymbol(\"box2d.b2BroadPhase\",box2d.b2BroadPhase);\nbox2d.b2BroadPhase.prototype.m_tree=null;goog.exportProperty(box2d.b2BroadPhase.prototype,\"m_tree\",box2d.b2BroadPhase.prototype.m_tree);box2d.b2BroadPhase.prototype.m_proxyCount=0;goog.exportProperty(box2d.b2BroadPhase.prototype,\"m_proxyCount\",box2d.b2BroadPhase.prototype.m_proxyCount);box2d.b2BroadPhase.prototype.m_moveCount=0;goog.exportProperty(box2d.b2BroadPhase.prototype,\"m_moveCount\",box2d.b2BroadPhase.prototype.m_moveCount);box2d.b2BroadPhase.prototype.m_moveBuffer=null;\ngoog.exportProperty(box2d.b2BroadPhase.prototype,\"m_moveBuffer\",box2d.b2BroadPhase.prototype.m_moveBuffer);box2d.b2BroadPhase.prototype.m_pairCount=0;goog.exportProperty(box2d.b2BroadPhase.prototype,\"m_pairCount\",box2d.b2BroadPhase.prototype.m_pairCount);box2d.b2BroadPhase.prototype.m_pairBuffer=null;goog.exportProperty(box2d.b2BroadPhase.prototype,\"m_pairBuffer\",box2d.b2BroadPhase.prototype.m_pairBuffer);\nbox2d.b2BroadPhase.prototype.CreateProxy=function(a,b){var c=this.m_tree.CreateProxy(a,b);++this.m_proxyCount;this.BufferMove(c);return c};goog.exportProperty(box2d.b2BroadPhase.prototype,\"CreateProxy\",box2d.b2BroadPhase.prototype.CreateProxy);box2d.b2BroadPhase.prototype.DestroyProxy=function(a){this.UnBufferMove(a);--this.m_proxyCount;this.m_tree.DestroyProxy(a)};goog.exportProperty(box2d.b2BroadPhase.prototype,\"DestroyProxy\",box2d.b2BroadPhase.prototype.DestroyProxy);\nbox2d.b2BroadPhase.prototype.MoveProxy=function(a,b,c){this.m_tree.MoveProxy(a,b,c)&&this.BufferMove(a)};goog.exportProperty(box2d.b2BroadPhase.prototype,\"MoveProxy\",box2d.b2BroadPhase.prototype.MoveProxy);box2d.b2BroadPhase.prototype.TouchProxy=function(a){this.BufferMove(a)};goog.exportProperty(box2d.b2BroadPhase.prototype,\"TouchProxy\",box2d.b2BroadPhase.prototype.TouchProxy);box2d.b2BroadPhase.prototype.GetFatAABB=function(a){return this.m_tree.GetFatAABB(a)};\ngoog.exportProperty(box2d.b2BroadPhase.prototype,\"GetFatAABB\",box2d.b2BroadPhase.prototype.GetFatAABB);box2d.b2BroadPhase.prototype.GetUserData=function(a){return this.m_tree.GetUserData(a)};goog.exportProperty(box2d.b2BroadPhase.prototype,\"GetUserData\",box2d.b2BroadPhase.prototype.GetUserData);box2d.b2BroadPhase.prototype.TestOverlap=function(a,b){var c=this.m_tree.GetFatAABB(a),e=this.m_tree.GetFatAABB(b);return box2d.b2TestOverlapAABB(c,e)};\ngoog.exportProperty(box2d.b2BroadPhase.prototype,\"TestOverlap\",box2d.b2BroadPhase.prototype.TestOverlap);box2d.b2BroadPhase.prototype.GetProxyCount=function(){return this.m_proxyCount};goog.exportProperty(box2d.b2BroadPhase.prototype,\"GetProxyCount\",box2d.b2BroadPhase.prototype.GetProxyCount);box2d.b2BroadPhase.prototype.GetTreeHeight=function(){return this.m_tree.GetHeight()};goog.exportProperty(box2d.b2BroadPhase.prototype,\"GetTreeHeight\",box2d.b2BroadPhase.prototype.GetTreeHeight);\nbox2d.b2BroadPhase.prototype.GetTreeBalance=function(){return this.m_tree.GetMaxBalance()};goog.exportProperty(box2d.b2BroadPhase.prototype,\"GetTreeBalance\",box2d.b2BroadPhase.prototype.GetTreeBalance);box2d.b2BroadPhase.prototype.GetTreeQuality=function(){return this.m_tree.GetAreaRatio()};goog.exportProperty(box2d.b2BroadPhase.prototype,\"GetTreeQuality\",box2d.b2BroadPhase.prototype.GetTreeQuality);box2d.b2BroadPhase.prototype.ShiftOrigin=function(a){this.m_tree.ShiftOrigin(a)};\ngoog.exportProperty(box2d.b2BroadPhase.prototype,\"ShiftOrigin\",box2d.b2BroadPhase.prototype.ShiftOrigin);\nbox2d.b2BroadPhase.prototype.UpdatePairs=function(a){for(var b=this.m_pairCount=0;b<this.m_moveCount;++b){var c=this.m_moveBuffer[b];if(null!==c){var e=this,d=this.m_tree.GetFatAABB(c);this.m_tree.Query(function(a){if(a.m_id===c.m_id)return!0;e.m_pairCount===e.m_pairBuffer.length&&(e.m_pairBuffer[e.m_pairCount]=new box2d.b2Pair);var b=e.m_pairBuffer[e.m_pairCount];a.m_id<c.m_id?(b.proxyA=a,b.proxyB=c):(b.proxyA=c,b.proxyB=a);++e.m_pairCount;return!0},d)}}this.m_moveCount=0;this.m_pairBuffer.length=\nthis.m_pairCount;this.m_pairBuffer.sort(box2d.b2PairLessThan);for(b=0;b<this.m_pairCount;){var d=this.m_pairBuffer[b],f=this.m_tree.GetUserData(d.proxyA),g=this.m_tree.GetUserData(d.proxyB);a.AddPair(f,g);for(++b;b<this.m_pairCount;){f=this.m_pairBuffer[b];if(f.proxyA.m_id!==d.proxyA.m_id||f.proxyB.m_id!==d.proxyB.m_id)break;++b}}};goog.exportProperty(box2d.b2BroadPhase.prototype,\"UpdatePairs\",box2d.b2BroadPhase.prototype.UpdatePairs);\nbox2d.b2BroadPhase.prototype.Query=function(a,b){this.m_tree.Query(a,b)};goog.exportProperty(box2d.b2BroadPhase.prototype,\"Query\",box2d.b2BroadPhase.prototype.Query);box2d.b2BroadPhase.prototype.RayCast=function(a,b){this.m_tree.RayCast(a,b)};goog.exportProperty(box2d.b2BroadPhase.prototype,\"RayCast\",box2d.b2BroadPhase.prototype.RayCast);box2d.b2BroadPhase.prototype.BufferMove=function(a){this.m_moveBuffer[this.m_moveCount]=a;++this.m_moveCount};\ngoog.exportProperty(box2d.b2BroadPhase.prototype,\"BufferMove\",box2d.b2BroadPhase.prototype.BufferMove);box2d.b2BroadPhase.prototype.UnBufferMove=function(a){a=this.m_moveBuffer.indexOf(a);this.m_moveBuffer[a]=null};goog.exportProperty(box2d.b2BroadPhase.prototype,\"UnBufferMove\",box2d.b2BroadPhase.prototype.UnBufferMove);box2d.b2PairLessThan=function(a,b){return a.proxyA.m_id===b.proxyA.m_id?a.proxyB.m_id-b.proxyB.m_id:a.proxyA.m_id-b.proxyA.m_id};box2d.b2ContactManager=function(){this.m_broadPhase=new box2d.b2BroadPhase;this.m_contactFactory=new box2d.b2ContactFactory(this.m_allocator)};box2d.b2ContactManager.prototype.m_broadPhase=null;goog.exportSymbol(\"box2d.b2ContactManager.prototype.m_broadPhase\",box2d.b2ContactManager.prototype.m_broadPhase);box2d.b2ContactManager.prototype.m_contactList=null;goog.exportSymbol(\"box2d.b2ContactManager.prototype.m_contactList\",box2d.b2ContactManager.prototype.m_contactList);\nbox2d.b2ContactManager.prototype.m_contactCount=0;goog.exportSymbol(\"box2d.b2ContactManager.prototype.m_contactCount\",box2d.b2ContactManager.prototype.m_contactCount);box2d.b2ContactManager.prototype.m_contactFilter=box2d.b2ContactFilter.b2_defaultFilter;goog.exportSymbol(\"box2d.b2ContactManager.prototype.m_contactFilter\",box2d.b2ContactManager.prototype.m_contactFilter);box2d.b2ContactManager.prototype.m_contactListener=box2d.b2ContactListener.b2_defaultListener;\ngoog.exportSymbol(\"box2d.b2ContactManager.prototype.m_contactListener\",box2d.b2ContactManager.prototype.m_contactListener);box2d.b2ContactManager.prototype.m_allocator=null;goog.exportSymbol(\"box2d.b2ContactManager.prototype.m_allocator\",box2d.b2ContactManager.prototype.m_allocator);box2d.b2ContactManager.prototype.m_contactFactory=null;goog.exportSymbol(\"box2d.b2ContactManager.prototype.m_contactFactory\",box2d.b2ContactManager.prototype.m_contactFactory);\nbox2d.b2ContactManager.prototype.Destroy=function(a){var b=a.GetFixtureA(),c=a.GetFixtureB(),b=b.GetBody(),c=c.GetBody();this.m_contactListener&&a.IsTouching()&&this.m_contactListener.EndContact(a);a.m_prev&&(a.m_prev.m_next=a.m_next);a.m_next&&(a.m_next.m_prev=a.m_prev);a===this.m_contactList&&(this.m_contactList=a.m_next);a.m_nodeA.prev&&(a.m_nodeA.prev.next=a.m_nodeA.next);a.m_nodeA.next&&(a.m_nodeA.next.prev=a.m_nodeA.prev);a.m_nodeA===b.m_contactList&&(b.m_contactList=a.m_nodeA.next);a.m_nodeB.prev&&\n(a.m_nodeB.prev.next=a.m_nodeB.next);a.m_nodeB.next&&(a.m_nodeB.next.prev=a.m_nodeB.prev);a.m_nodeB===c.m_contactList&&(c.m_contactList=a.m_nodeB.next);this.m_contactFactory.Destroy(a);--this.m_contactCount};goog.exportSymbol(\"box2d.b2ContactManager.prototype.Destroy\",box2d.b2ContactManager.prototype.Destroy);\nbox2d.b2ContactManager.prototype.Collide=function(){for(var a=this.m_contactList;a;){var b=a.GetFixtureA(),c=a.GetFixtureB(),e=a.GetChildIndexA(),d=a.GetChildIndexB(),f=b.GetBody(),g=c.GetBody();if(a.m_flags&box2d.b2ContactFlag.e_filterFlag){if(!1===g.ShouldCollide(f)){b=a;a=b.m_next;this.Destroy(b);continue}if(this.m_contactFilter&&!1===this.m_contactFilter.ShouldCollide(b,c)){b=a;a=b.m_next;this.Destroy(b);continue}a.m_flags&=~box2d.b2ContactFlag.e_filterFlag}f=f.IsAwake()&&f.m_type!==box2d.b2BodyType.b2_staticBody;\ng=g.IsAwake()&&g.m_type!==box2d.b2BodyType.b2_staticBody;!1===f&&!1===g?a=a.m_next:!1===this.m_broadPhase.TestOverlap(b.m_proxies[e].proxy,c.m_proxies[d].proxy)?(b=a,a=b.m_next,this.Destroy(b)):(a.Update(this.m_contactListener),a=a.m_next)}};goog.exportSymbol(\"box2d.b2ContactManager.prototype.Collide\",box2d.b2ContactManager.prototype.Collide);box2d.b2ContactManager.prototype.FindNewContacts=function(){this.m_broadPhase.UpdatePairs(this)};\ngoog.exportSymbol(\"box2d.b2ContactManager.prototype.FindNewContacts\",box2d.b2ContactManager.prototype.FindNewContacts);\nbox2d.b2ContactManager.prototype.AddPair=function(a,b){box2d.ENABLE_ASSERTS&&box2d.b2Assert(a instanceof box2d.b2FixtureProxy);box2d.ENABLE_ASSERTS&&box2d.b2Assert(b instanceof box2d.b2FixtureProxy);var c=a.fixture,e=b.fixture,d=a.childIndex,f=b.childIndex,g=c.GetBody(),h=e.GetBody();if(g!==h){for(var l=h.GetContactList();l;){if(l.other===g){var k=l.contact.GetFixtureA(),m=l.contact.GetFixtureB(),n=l.contact.GetChildIndexA(),p=l.contact.GetChildIndexB();if(k===c&&m===e&&n===d&&p===f||k===e&&m===c&&\nn===f&&p===d)return}l=l.next}!1===h.ShouldCollide(g)||this.m_contactFilter&&!1===this.m_contactFilter.ShouldCollide(c,e)||(d=this.m_contactFactory.Create(c,d,e,f),null!==d&&(c=d.GetFixtureA(),e=d.GetFixtureB(),d.GetChildIndexA(),d.GetChildIndexB(),g=c.m_body,h=e.m_body,d.m_prev=null,d.m_next=this.m_contactList,null!==this.m_contactList&&(this.m_contactList.m_prev=d),this.m_contactList=d,d.m_nodeA.contact=d,d.m_nodeA.other=h,d.m_nodeA.prev=null,d.m_nodeA.next=g.m_contactList,null!==g.m_contactList&&\n(g.m_contactList.prev=d.m_nodeA),g.m_contactList=d.m_nodeA,d.m_nodeB.contact=d,d.m_nodeB.other=g,d.m_nodeB.prev=null,d.m_nodeB.next=h.m_contactList,null!==h.m_contactList&&(h.m_contactList.prev=d.m_nodeB),h.m_contactList=d.m_nodeB,!1===c.IsSensor()&&!1===e.IsSensor()&&(g.SetAwake(!0),h.SetAwake(!0)),++this.m_contactCount))}};goog.exportSymbol(\"box2d.b2ContactManager.prototype.AddPair\",box2d.b2ContactManager.prototype.AddPair);box2d.b2JointFactory={};\nbox2d.b2JointFactory.Create=function(a,b){var c=null;switch(a.type){case box2d.b2JointType.e_distanceJoint:c=new box2d.b2DistanceJoint(a instanceof box2d.b2DistanceJointDef?a:null);break;case box2d.b2JointType.e_mouseJoint:c=new box2d.b2MouseJoint(a instanceof box2d.b2MouseJointDef?a:null);break;case box2d.b2JointType.e_prismaticJoint:c=new box2d.b2PrismaticJoint(a instanceof box2d.b2PrismaticJointDef?a:null);break;case box2d.b2JointType.e_revoluteJoint:c=new box2d.b2RevoluteJoint(a instanceof box2d.b2RevoluteJointDef?\na:null);break;case box2d.b2JointType.e_pulleyJoint:c=new box2d.b2PulleyJoint(a instanceof box2d.b2PulleyJointDef?a:null);break;case box2d.b2JointType.e_gearJoint:c=new box2d.b2GearJoint(a instanceof box2d.b2GearJointDef?a:null);break;case box2d.b2JointType.e_wheelJoint:c=new box2d.b2WheelJoint(a instanceof box2d.b2WheelJointDef?a:null);break;case box2d.b2JointType.e_weldJoint:c=new box2d.b2WeldJoint(a instanceof box2d.b2WeldJointDef?a:null);break;case box2d.b2JointType.e_frictionJoint:c=new box2d.b2FrictionJoint(a instanceof\nbox2d.b2FrictionJointDef?a:null);break;case box2d.b2JointType.e_ropeJoint:c=new box2d.b2RopeJoint(a instanceof box2d.b2RopeJointDef?a:null);break;case box2d.b2JointType.e_motorJoint:c=new box2d.b2MotorJoint(a instanceof box2d.b2MotorJointDef?a:null);break;case box2d.b2JointType.e_areaJoint:c=new box2d.b2AreaJoint(a instanceof box2d.b2AreaJointDef?a:null);break;default:box2d.ENABLE_ASSERTS&&box2d.b2Assert(!1)}return c};goog.exportSymbol(\"box2d.b2JointFactory.Create\",box2d.b2JointFactory.Create);\nbox2d.b2JointFactory.Destroy=function(a,b){};goog.exportSymbol(\"box2d.b2JointFactory.Destroy\",box2d.b2JointFactory.Destroy);box2d.b2Color=function(a,b,c){this.r=a;this.g=b;this.b=c};goog.exportSymbol(\"box2d.b2Color\",box2d.b2Color);box2d.b2Color.prototype.r=0.5;goog.exportProperty(box2d.b2Color.prototype,\"r\",box2d.b2Color.prototype.r);box2d.b2Color.prototype.g=0.5;goog.exportProperty(box2d.b2Color.prototype,\"g\",box2d.b2Color.prototype.g);box2d.b2Color.prototype.b=0.5;goog.exportProperty(box2d.b2Color.prototype,\"b\",box2d.b2Color.prototype.b);box2d.b2Color.prototype.SetRGB=function(a,b,c){this.r=a;this.g=b;this.b=c;return this};\ngoog.exportProperty(box2d.b2Color.prototype,\"SetRGB\",box2d.b2Color.prototype.SetRGB);box2d.b2Color.prototype.MakeStyleString=function(a){var b=Math.round(Math.max(0,Math.min(255,255*this.r))),c=Math.round(Math.max(0,Math.min(255,255*this.g))),e=Math.round(Math.max(0,Math.min(255,255*this.b)));a=\"undefined\"===typeof a?1:Math.max(0,Math.min(1,a));return box2d.b2Color.MakeStyleString(b,c,e,a)};goog.exportProperty(box2d.b2Color.prototype,\"MakeStyleString\",box2d.b2Color.prototype.MakeStyleString);\nbox2d.b2Color.MakeStyleString=function(a,b,c,e){return 1>e?\"rgba(\"+a+\",\"+b+\",\"+c+\",\"+e+\")\":\"rgb(\"+a+\",\"+b+\",\"+c+\")\"};goog.exportProperty(box2d.b2Color,\"MakeStyleString\",box2d.b2Color.MakeStyleString);box2d.b2Color.RED=new box2d.b2Color(1,0,0);goog.exportProperty(box2d.b2Color,\"RED\",box2d.b2Color.RED);box2d.b2Color.GREEN=new box2d.b2Color(0,1,0);goog.exportProperty(box2d.b2Color,\"GREEN\",box2d.b2Color.GREEN);box2d.b2Color.BLUE=new box2d.b2Color(0,0,1);goog.exportProperty(box2d.b2Color,\"BLUE\",box2d.b2Color.BLUE);\nbox2d.b2DrawFlags={e_none:0,e_shapeBit:1,e_jointBit:2,e_aabbBit:4,e_pairBit:8,e_centerOfMassBit:16,e_controllerBit:32,e_all:63};goog.exportSymbol(\"box2d.b2DrawFlags\",box2d.b2DrawFlags);goog.exportProperty(box2d.b2DrawFlags,\"e_none\",box2d.b2DrawFlags.e_none);goog.exportProperty(box2d.b2DrawFlags,\"e_shapeBit\",box2d.b2DrawFlags.e_shapeBit);goog.exportProperty(box2d.b2DrawFlags,\"e_jointBit\",box2d.b2DrawFlags.e_jointBit);goog.exportProperty(box2d.b2DrawFlags,\"e_aabbBit\",box2d.b2DrawFlags.e_aabbBit);\ngoog.exportProperty(box2d.b2DrawFlags,\"e_pairBit\",box2d.b2DrawFlags.e_pairBit);goog.exportProperty(box2d.b2DrawFlags,\"e_centerOfMassBit\",box2d.b2DrawFlags.e_centerOfMassBit);goog.exportProperty(box2d.b2DrawFlags,\"e_controllerBit\",box2d.b2DrawFlags.e_controllerBit);goog.exportProperty(box2d.b2DrawFlags,\"e_all\",box2d.b2DrawFlags.e_all);box2d.b2Draw=function(){};goog.exportSymbol(\"box2d.b2Draw\",box2d.b2Draw);box2d.b2Draw.prototype.m_drawFlags=box2d.b2DrawFlags.e_none;\ngoog.exportProperty(box2d.b2Draw.prototype,\"m_drawFlags\",box2d.b2Draw.prototype.m_drawFlags);box2d.b2Draw.prototype.SetFlags=function(a){this.m_drawFlags=a};goog.exportProperty(box2d.b2Draw.prototype,\"SetFlags\",box2d.b2Draw.prototype.SetFlags);box2d.b2Draw.prototype.GetFlags=function(){return this.m_drawFlags};goog.exportProperty(box2d.b2Draw.prototype,\"GetFlags\",box2d.b2Draw.prototype.GetFlags);box2d.b2Draw.prototype.AppendFlags=function(a){this.m_drawFlags|=a};\ngoog.exportProperty(box2d.b2Draw.prototype,\"AppendFlags\",box2d.b2Draw.prototype.AppendFlags);box2d.b2Draw.prototype.ClearFlags=function(a){this.m_drawFlags&=~a};goog.exportProperty(box2d.b2Draw.prototype,\"ClearFlags\",box2d.b2Draw.prototype.ClearFlags);box2d.b2Draw.prototype.PushTransform=function(a){};goog.exportProperty(box2d.b2Draw.prototype,\"PushTransform\",box2d.b2Draw.prototype.PushTransform);box2d.b2Draw.prototype.PopTransform=function(a){};\ngoog.exportProperty(box2d.b2Draw.prototype,\"PopTransform\",box2d.b2Draw.prototype.PopTransform);box2d.b2Draw.prototype.DrawPolygon=function(a,b,c){};goog.exportProperty(box2d.b2Draw.prototype,\"DrawPolygon\",box2d.b2Draw.prototype.DrawPolygon);box2d.b2Draw.prototype.DrawSolidPolygon=function(a,b,c){};goog.exportProperty(box2d.b2Draw.prototype,\"DrawSolidPolygon\",box2d.b2Draw.prototype.DrawSolidPolygon);box2d.b2Draw.prototype.DrawCircle=function(a,b,c){};\ngoog.exportProperty(box2d.b2Draw.prototype,\"DrawCircle\",box2d.b2Draw.prototype.DrawCircle);box2d.b2Draw.prototype.DrawSolidCircle=function(a,b,c,e){};goog.exportProperty(box2d.b2Draw.prototype,\"DrawSolidCircle\",box2d.b2Draw.prototype.DrawSolidCircle);box2d.b2Draw.prototype.DrawSegment=function(a,b,c){};goog.exportProperty(box2d.b2Draw.prototype,\"DrawSegment\",box2d.b2Draw.prototype.DrawSegment);box2d.b2Draw.prototype.DrawTransform=function(a){};\ngoog.exportProperty(box2d.b2Draw.prototype,\"DrawTransform\",box2d.b2Draw.prototype.DrawTransform);box2d.b2Filter=function(){};goog.exportSymbol(\"box2d.b2Filter\",box2d.b2Filter);box2d.b2Filter.prototype.categoryBits=1;goog.exportProperty(box2d.b2Filter.prototype,\"categoryBits\",box2d.b2Filter.prototype.categoryBits);box2d.b2Filter.prototype.maskBits=65535;goog.exportProperty(box2d.b2Filter.prototype,\"maskBits\",box2d.b2Filter.prototype.maskBits);box2d.b2Filter.prototype.groupIndex=0;goog.exportProperty(box2d.b2Filter.prototype,\"groupIndex\",box2d.b2Filter.prototype.groupIndex);\nbox2d.b2Filter.prototype.Clone=function(){return(new box2d.b2Filter).Copy(this)};goog.exportProperty(box2d.b2Filter.prototype,\"Clone\",box2d.b2Filter.prototype.Clone);box2d.b2Filter.prototype.Copy=function(a){box2d.ENABLE_ASSERTS&&box2d.b2Assert(this!==a);this.categoryBits=a.categoryBits;this.maskBits=a.maskBits;this.groupIndex=a.groupIndex;return this};goog.exportProperty(box2d.b2Filter.prototype,\"Copy\",box2d.b2Filter.prototype.Copy);box2d.b2FixtureDef=function(){this.filter=new box2d.b2Filter};\ngoog.exportSymbol(\"box2d.b2FixtureDef\",box2d.b2FixtureDef);box2d.b2FixtureDef.prototype.shape=null;goog.exportProperty(box2d.b2FixtureDef.prototype,\"shape\",box2d.b2FixtureDef.prototype.shape);box2d.b2FixtureDef.prototype.userData=null;goog.exportProperty(box2d.b2FixtureDef.prototype,\"userData\",box2d.b2FixtureDef.prototype.userData);box2d.b2FixtureDef.prototype.friction=0.2;goog.exportProperty(box2d.b2FixtureDef.prototype,\"friction\",box2d.b2FixtureDef.prototype.friction);\nbox2d.b2FixtureDef.prototype.restitution=0;goog.exportProperty(box2d.b2FixtureDef.prototype,\"restitution\",box2d.b2FixtureDef.prototype.restitution);box2d.b2FixtureDef.prototype.density=0;goog.exportProperty(box2d.b2FixtureDef.prototype,\"density\",box2d.b2FixtureDef.prototype.density);box2d.b2FixtureDef.prototype.isSensor=!1;goog.exportProperty(box2d.b2FixtureDef.prototype,\"isSensor\",box2d.b2FixtureDef.prototype.isSensor);box2d.b2FixtureDef.prototype.filter=null;\ngoog.exportProperty(box2d.b2FixtureDef.prototype,\"filter\",box2d.b2FixtureDef.prototype.filter);box2d.b2FixtureProxy=function(){this.aabb=new box2d.b2AABB};goog.exportSymbol(\"box2d.b2FixtureProxy\",box2d.b2FixtureProxy);box2d.b2FixtureProxy.prototype.aabb=null;goog.exportProperty(box2d.b2FixtureProxy.prototype,\"aabb\",box2d.b2FixtureProxy.prototype.aabb);box2d.b2FixtureProxy.prototype.fixture=null;goog.exportProperty(box2d.b2FixtureProxy.prototype,\"fixture\",box2d.b2FixtureProxy.prototype.fixture);\nbox2d.b2FixtureProxy.prototype.childIndex=0;goog.exportProperty(box2d.b2FixtureProxy.prototype,\"childIndex\",box2d.b2FixtureProxy.prototype.childIndex);box2d.b2FixtureProxy.prototype.proxy=null;goog.exportProperty(box2d.b2FixtureProxy.prototype,\"proxy\",box2d.b2FixtureProxy.prototype.proxy);box2d.b2FixtureProxy.MakeArray=function(a){return box2d.b2MakeArray(a,function(a){return new box2d.b2FixtureProxy})};goog.exportProperty(box2d.b2FixtureProxy,\"MakeArray\",box2d.b2FixtureProxy.MakeArray);\nbox2d.b2Fixture=function(){this.m_proxyCount=0;this.m_filter=new box2d.b2Filter};goog.exportSymbol(\"box2d.b2Fixture\",box2d.b2Fixture);box2d.b2Fixture.prototype.m_density=0;goog.exportProperty(box2d.b2Fixture.prototype,\"m_density\",box2d.b2Fixture.prototype.m_density);box2d.b2Fixture.prototype.m_next=null;goog.exportProperty(box2d.b2Fixture.prototype,\"m_next\",box2d.b2Fixture.prototype.m_next);box2d.b2Fixture.prototype.m_body=null;goog.exportProperty(box2d.b2Fixture.prototype,\"m_body\",box2d.b2Fixture.prototype.m_body);\nbox2d.b2Fixture.prototype.m_shape=null;goog.exportProperty(box2d.b2Fixture.prototype,\"m_shape\",box2d.b2Fixture.prototype.m_shape);box2d.b2Fixture.prototype.m_friction=0;goog.exportProperty(box2d.b2Fixture.prototype,\"m_friction\",box2d.b2Fixture.prototype.m_friction);box2d.b2Fixture.prototype.m_restitution=0;goog.exportProperty(box2d.b2Fixture.prototype,\"m_restitution\",box2d.b2Fixture.prototype.m_restitution);box2d.b2Fixture.prototype.m_proxies=null;\ngoog.exportProperty(box2d.b2Fixture.prototype,\"m_proxies\",box2d.b2Fixture.prototype.m_proxies);box2d.b2Fixture.prototype.m_proxyCount=0;goog.exportProperty(box2d.b2Fixture.prototype,\"m_proxyCount\",box2d.b2Fixture.prototype.m_proxyCount);box2d.b2Fixture.prototype.m_filter=null;goog.exportProperty(box2d.b2Fixture.prototype,\"m_filter\",box2d.b2Fixture.prototype.m_filter);box2d.b2Fixture.prototype.m_isSensor=!1;goog.exportProperty(box2d.b2Fixture.prototype,\"m_isSensor\",box2d.b2Fixture.prototype.m_isSensor);\nbox2d.b2Fixture.prototype.m_userData=null;goog.exportProperty(box2d.b2Fixture.prototype,\"m_userData\",box2d.b2Fixture.prototype.m_userData);box2d.b2Fixture.prototype.GetType=function(){return this.m_shape.GetType()};goog.exportProperty(box2d.b2Fixture.prototype,\"GetType\",box2d.b2Fixture.prototype.GetType);box2d.b2Fixture.prototype.GetShape=function(){return this.m_shape};goog.exportProperty(box2d.b2Fixture.prototype,\"GetShape\",box2d.b2Fixture.prototype.GetShape);\nbox2d.b2Fixture.prototype.IsSensor=function(){return this.m_isSensor};goog.exportProperty(box2d.b2Fixture.prototype,\"IsSensor\",box2d.b2Fixture.prototype.IsSensor);box2d.b2Fixture.prototype.GetFilterData=function(){return this.m_filter};goog.exportProperty(box2d.b2Fixture.prototype,\"GetFilterData\",box2d.b2Fixture.prototype.GetFilterData);box2d.b2Fixture.prototype.GetUserData=function(){return this.m_userData};goog.exportProperty(box2d.b2Fixture.prototype,\"GetUserData\",box2d.b2Fixture.prototype.GetUserData);\nbox2d.b2Fixture.prototype.SetUserData=function(a){this.m_userData=a};goog.exportProperty(box2d.b2Fixture.prototype,\"SetUserData\",box2d.b2Fixture.prototype.SetUserData);box2d.b2Fixture.prototype.GetBody=function(){return this.m_body};goog.exportProperty(box2d.b2Fixture.prototype,\"GetBody\",box2d.b2Fixture.prototype.GetBody);box2d.b2Fixture.prototype.GetNext=function(){return this.m_next};goog.exportProperty(box2d.b2Fixture.prototype,\"GetNext\",box2d.b2Fixture.prototype.GetNext);\nbox2d.b2Fixture.prototype.SetDensity=function(a){this.m_density=a};goog.exportProperty(box2d.b2Fixture.prototype,\"SetDensity\",box2d.b2Fixture.prototype.SetDensity);box2d.b2Fixture.prototype.GetDensity=function(){return this.m_density};goog.exportProperty(box2d.b2Fixture.prototype,\"GetDensity\",box2d.b2Fixture.prototype.GetDensity);box2d.b2Fixture.prototype.GetFriction=function(){return this.m_friction};goog.exportProperty(box2d.b2Fixture.prototype,\"GetFriction\",box2d.b2Fixture.prototype.GetFriction);\nbox2d.b2Fixture.prototype.SetFriction=function(a){this.m_friction=a};goog.exportProperty(box2d.b2Fixture.prototype,\"SetFriction\",box2d.b2Fixture.prototype.SetFriction);box2d.b2Fixture.prototype.GetRestitution=function(){return this.m_restitution};goog.exportProperty(box2d.b2Fixture.prototype,\"GetRestitution\",box2d.b2Fixture.prototype.GetRestitution);box2d.b2Fixture.prototype.SetRestitution=function(a){this.m_restitution=a};goog.exportProperty(box2d.b2Fixture.prototype,\"SetRestitution\",box2d.b2Fixture.prototype.SetRestitution);\nbox2d.b2Fixture.prototype.TestPoint=function(a){return this.m_shape.TestPoint(this.m_body.GetTransform(),a)};goog.exportProperty(box2d.b2Fixture.prototype,\"TestPoint\",box2d.b2Fixture.prototype.TestPoint);box2d.b2Fixture.prototype.RayCast=function(a,b,c){return this.m_shape.RayCast(a,b,this.m_body.GetTransform(),c)};goog.exportProperty(box2d.b2Fixture.prototype,\"RayCast\",box2d.b2Fixture.prototype.RayCast);\nbox2d.b2Fixture.prototype.GetMassData=function(a){a=a||new box2d.b2MassData;this.m_shape.ComputeMass(a,this.m_density);return a};goog.exportProperty(box2d.b2Fixture.prototype,\"GetMassData\",box2d.b2Fixture.prototype.GetMassData);box2d.b2Fixture.prototype.GetAABB=function(a){box2d.ENABLE_ASSERTS&&box2d.b2Assert(0<=a&&a<this.m_proxyCount);return this.m_proxies[a].aabb};goog.exportProperty(box2d.b2Fixture.prototype,\"GetAABB\",box2d.b2Fixture.prototype.GetAABB);\nbox2d.b2Fixture.prototype.Create=function(a,b){this.m_userData=b.userData;this.m_friction=b.friction;this.m_restitution=b.restitution;this.m_body=a;this.m_next=null;this.m_filter.Copy(b.filter);this.m_isSensor=b.isSensor;this.m_shape=b.shape.Clone();this.m_proxies=box2d.b2FixtureProxy.MakeArray(this.m_shape.GetChildCount());this.m_proxyCount=0;this.m_density=b.density};goog.exportProperty(box2d.b2Fixture.prototype,\"Create\",box2d.b2Fixture.prototype.Create);\nbox2d.b2Fixture.prototype.Destroy=function(){box2d.ENABLE_ASSERTS&&box2d.b2Assert(0===this.m_proxyCount);this.m_shape=null};goog.exportProperty(box2d.b2Fixture.prototype,\"Destroy\",box2d.b2Fixture.prototype.Destroy);\nbox2d.b2Fixture.prototype.CreateProxies=function(a,b){box2d.ENABLE_ASSERTS&&box2d.b2Assert(0===this.m_proxyCount);this.m_proxyCount=this.m_shape.GetChildCount();for(var c=0;c<this.m_proxyCount;++c){var e=this.m_proxies[c];this.m_shape.ComputeAABB(e.aabb,b,c);e.proxy=a.CreateProxy(e.aabb,e);e.fixture=this;e.childIndex=c}};goog.exportProperty(box2d.b2Fixture.prototype,\"CreateProxies\",box2d.b2Fixture.prototype.CreateProxies);\nbox2d.b2Fixture.prototype.DestroyProxies=function(a){for(var b=0;b<this.m_proxyCount;++b){var c=this.m_proxies[b];a.DestroyProxy(c.proxy);c.proxy=null}this.m_proxyCount=0};goog.exportProperty(box2d.b2Fixture.prototype,\"DestroyProxies\",box2d.b2Fixture.prototype.DestroyProxies);\nbox2d.b2Fixture.prototype.Synchronize=function(a,b,c){if(0!==this.m_proxyCount)for(var e=0;e<this.m_proxyCount;++e){var d=this.m_proxies[e],f=box2d.b2Fixture.prototype.Synchronize.s_aabb1,g=box2d.b2Fixture.prototype.Synchronize.s_aabb2;this.m_shape.ComputeAABB(f,b,e);this.m_shape.ComputeAABB(g,c,e);d.aabb.Combine2(f,g);f=box2d.b2SubVV(c.p,b.p,box2d.b2Fixture.prototype.Synchronize.s_displacement);a.MoveProxy(d.proxy,d.aabb,f)}};goog.exportProperty(box2d.b2Fixture.prototype,\"Synchronize\",box2d.b2Fixture.prototype.Synchronize);\nbox2d.b2Fixture.prototype.Synchronize.s_aabb1=new box2d.b2AABB;box2d.b2Fixture.prototype.Synchronize.s_aabb2=new box2d.b2AABB;box2d.b2Fixture.prototype.Synchronize.s_displacement=new box2d.b2Vec2;box2d.b2Fixture.prototype.SetFilterData=function(a){this.m_filter.Copy(a);this.Refilter()};goog.exportProperty(box2d.b2Fixture.prototype,\"SetFilterData\",box2d.b2Fixture.prototype.SetFilterData);\nbox2d.b2Fixture.prototype.Refilter=function(){if(!this.m_body){for(var a=this.m_body.GetContactList();a;){var b=a.contact,c=b.GetFixtureA(),e=b.GetFixtureB();c!==this&&e!==this||b.FlagForFiltering();a=a.next}a=this.m_body.GetWorld();if(null!==a)for(a=a.m_contactManager.m_broadPhase,b=0;b<this.m_proxyCount;++b)a.TouchProxy(this.m_proxies[b].proxy)}};goog.exportProperty(box2d.b2Fixture.prototype,\"Refilter\",box2d.b2Fixture.prototype.Refilter);\nbox2d.b2Fixture.prototype.SetSensor=function(a){a!==this.m_isSensor&&(this.m_body.SetAwake(!0),this.m_isSensor=a)};goog.exportProperty(box2d.b2Fixture.prototype,\"SetSensor\",box2d.b2Fixture.prototype.SetSensor);\nbox2d.b2Fixture.prototype.Dump=function(a){box2d.DEBUG&&(box2d.b2Log(\"    /*box2d.b2FixtureDef*/ var fd = new box2d.b2FixtureDef();\\n\"),box2d.b2Log(\"    fd.friction = %.15f;\\n\",this.m_friction),box2d.b2Log(\"    fd.restitution = %.15f;\\n\",this.m_restitution),box2d.b2Log(\"    fd.density = %.15f;\\n\",this.m_density),box2d.b2Log(\"    fd.isSensor = %s;\\n\",this.m_isSensor?\"true\":\"false\"),box2d.b2Log(\"    fd.filter.categoryBits = %d;\\n\",this.m_filter.categoryBits),box2d.b2Log(\"    fd.filter.maskBits = %d;\\n\",\nthis.m_filter.maskBits),box2d.b2Log(\"    fd.filter.groupIndex = %d;\\n\",this.m_filter.groupIndex),this.m_shape.Dump(),box2d.b2Log(\"\\n\"),box2d.b2Log(\"    fd.shape = shape;\\n\"),box2d.b2Log(\"\\n\"),box2d.b2Log(\"    bodies[%d].CreateFixture(fd);\\n\",a))};goog.exportProperty(box2d.b2Fixture.prototype,\"Dump\",box2d.b2Fixture.prototype.Dump);box2d.b2BodyType={b2_unknown:-1,b2_staticBody:0,b2_kinematicBody:1,b2_dynamicBody:2,b2_bulletBody:3};goog.exportSymbol(\"box2d.b2BodyType\",box2d.b2BodyType);goog.exportProperty(box2d.b2BodyType,\"b2_unknown\",box2d.b2BodyType.b2_unknown);goog.exportProperty(box2d.b2BodyType,\"b2_staticBody\",box2d.b2BodyType.b2_staticBody);goog.exportProperty(box2d.b2BodyType,\"b2_kinematicBody\",box2d.b2BodyType.b2_kinematicBody);goog.exportProperty(box2d.b2BodyType,\"b2_dynamicBody\",box2d.b2BodyType.b2_dynamicBody);\ngoog.exportProperty(box2d.b2BodyType,\"b2_bulletBody\",box2d.b2BodyType.b2_bulletBody);box2d.b2BodyDef=function(){this.position=new box2d.b2Vec2(0,0);this.linearVelocity=new box2d.b2Vec2(0,0)};goog.exportSymbol(\"box2d.b2BodyDef\",box2d.b2BodyDef);box2d.b2BodyDef.prototype.type=box2d.b2BodyType.b2_staticBody;goog.exportProperty(box2d.b2BodyDef.prototype,\"type\",box2d.b2BodyDef.prototype.type);box2d.b2BodyDef.prototype.position=null;goog.exportProperty(box2d.b2BodyDef.prototype,\"position\",box2d.b2BodyDef.prototype.position);\nbox2d.b2BodyDef.prototype.angle=0;goog.exportProperty(box2d.b2BodyDef.prototype,\"angle\",box2d.b2BodyDef.prototype.angle);box2d.b2BodyDef.prototype.linearVelocity=null;goog.exportProperty(box2d.b2BodyDef.prototype,\"linearVelocity\",box2d.b2BodyDef.prototype.linearVelocity);box2d.b2BodyDef.prototype.angularVelocity=0;goog.exportProperty(box2d.b2BodyDef.prototype,\"angularVelocity\",box2d.b2BodyDef.prototype.angularVelocity);box2d.b2BodyDef.prototype.linearDamping=0;\ngoog.exportProperty(box2d.b2BodyDef.prototype,\"linearDamping\",box2d.b2BodyDef.prototype.linearDamping);box2d.b2BodyDef.prototype.angularDamping=0;goog.exportProperty(box2d.b2BodyDef.prototype,\"angularDamping\",box2d.b2BodyDef.prototype.angularDamping);box2d.b2BodyDef.prototype.allowSleep=!0;goog.exportProperty(box2d.b2BodyDef.prototype,\"allowSleep\",box2d.b2BodyDef.prototype.allowSleep);box2d.b2BodyDef.prototype.awake=!0;goog.exportProperty(box2d.b2BodyDef.prototype,\"awake\",box2d.b2BodyDef.prototype.awake);\nbox2d.b2BodyDef.prototype.fixedRotation=!1;goog.exportProperty(box2d.b2BodyDef.prototype,\"fixedRotation\",box2d.b2BodyDef.prototype.fixedRotation);box2d.b2BodyDef.prototype.bullet=!1;goog.exportProperty(box2d.b2BodyDef.prototype,\"bullet\",box2d.b2BodyDef.prototype.bullet);box2d.b2BodyDef.prototype.active=!0;goog.exportProperty(box2d.b2BodyDef.prototype,\"active\",box2d.b2BodyDef.prototype.active);box2d.b2BodyDef.prototype.userData=null;goog.exportProperty(box2d.b2BodyDef.prototype,\"userData\",box2d.b2BodyDef.prototype.userData);\nbox2d.b2BodyDef.prototype.gravityScale=1;goog.exportProperty(box2d.b2BodyDef.prototype,\"gravityScale\",box2d.b2BodyDef.prototype.gravityScale);box2d.b2BodyFlag={e_none:0,e_islandFlag:1,e_awakeFlag:2,e_autoSleepFlag:4,e_bulletFlag:8,e_fixedRotationFlag:16,e_activeFlag:32,e_toiFlag:64};goog.exportProperty(box2d.b2BodyFlag,\"e_none\",box2d.b2BodyFlag.e_none);goog.exportProperty(box2d.b2BodyFlag,\"e_islandFlag\",box2d.b2BodyFlag.e_islandFlag);goog.exportProperty(box2d.b2BodyFlag,\"e_awakeFlag\",box2d.b2BodyFlag.e_awakeFlag);\ngoog.exportProperty(box2d.b2BodyFlag,\"e_autoSleepFlag\",box2d.b2BodyFlag.e_autoSleepFlag);goog.exportProperty(box2d.b2BodyFlag,\"e_bulletFlag\",box2d.b2BodyFlag.e_bulletFlag);goog.exportProperty(box2d.b2BodyFlag,\"e_fixedRotationFlag\",box2d.b2BodyFlag.e_fixedRotationFlag);goog.exportProperty(box2d.b2BodyFlag,\"e_activeFlag\",box2d.b2BodyFlag.e_activeFlag);goog.exportProperty(box2d.b2BodyFlag,\"e_toiFlag\",box2d.b2BodyFlag.e_toiFlag);\nbox2d.b2Body=function(a,b){this.m_xf=new box2d.b2Transform;this.m_out_xf=new box2d.b2Transform;this.m_sweep=new box2d.b2Sweep;this.m_out_sweep=new box2d.b2Sweep;this.m_linearVelocity=new box2d.b2Vec2;this.m_out_linearVelocity=new box2d.b2Vec2;this.m_force=new box2d.b2Vec2;box2d.ENABLE_ASSERTS&&box2d.b2Assert(a.position.IsValid());box2d.ENABLE_ASSERTS&&box2d.b2Assert(a.linearVelocity.IsValid());box2d.ENABLE_ASSERTS&&box2d.b2Assert(box2d.b2IsValid(a.angle));box2d.ENABLE_ASSERTS&&box2d.b2Assert(box2d.b2IsValid(a.angularVelocity));\nbox2d.ENABLE_ASSERTS&&box2d.b2Assert(box2d.b2IsValid(a.gravityScale)&&0<=a.gravityScale);box2d.ENABLE_ASSERTS&&box2d.b2Assert(box2d.b2IsValid(a.angularDamping)&&0<=a.angularDamping);box2d.ENABLE_ASSERTS&&box2d.b2Assert(box2d.b2IsValid(a.linearDamping)&&0<=a.linearDamping);this.m_flags=box2d.b2BodyFlag.e_none;a.bullet&&(this.m_flags|=box2d.b2BodyFlag.e_bulletFlag);a.fixedRotation&&(this.m_flags|=box2d.b2BodyFlag.e_fixedRotationFlag);a.allowSleep&&(this.m_flags|=box2d.b2BodyFlag.e_autoSleepFlag);a.awake&&\n(this.m_flags|=box2d.b2BodyFlag.e_awakeFlag);a.active&&(this.m_flags|=box2d.b2BodyFlag.e_activeFlag);this.m_world=b;this.m_xf.p.Copy(a.position);this.m_xf.q.SetAngleRadians(a.angle);this.m_sweep.localCenter.SetZero();this.m_sweep.c0.Copy(this.m_xf.p);this.m_sweep.c.Copy(this.m_xf.p);this.m_sweep.a0=a.angle;this.m_sweep.a=a.angle;this.m_sweep.alpha0=0;this.m_linearVelocity.Copy(a.linearVelocity);this.m_angularVelocity=a.angularVelocity;this.m_linearDamping=a.linearDamping;this.m_angularDamping=a.angularDamping;\nthis.m_gravityScale=a.gravityScale;this.m_force.SetZero();this.m_sleepTime=this.m_torque=0;this.m_type=a.type;this.m_invMass=a.type===box2d.b2BodyType.b2_dynamicBody?this.m_mass=1:this.m_mass=0;this.m_invI=this.m_I=0;this.m_userData=a.userData;this.m_fixtureList=null;this.m_fixtureCount=0;this.m_controllerList=null;this.m_controllerCount=0};goog.exportSymbol(\"box2d.b2Body\",box2d.b2Body);box2d.b2Body.prototype.m_flags=box2d.b2BodyFlag.e_none;goog.exportProperty(box2d.b2Body.prototype,\"m_flags\",box2d.b2Body.prototype.m_flags);\nbox2d.b2Body.prototype.m_islandIndex=0;goog.exportProperty(box2d.b2Body.prototype,\"m_islandIndex\",box2d.b2Body.prototype.m_islandIndex);box2d.b2Body.prototype.m_world=null;goog.exportProperty(box2d.b2Body.prototype,\"m_world\",box2d.b2Body.prototype.m_world);box2d.b2Body.prototype.m_xf=null;goog.exportProperty(box2d.b2Body.prototype,\"m_xf\",box2d.b2Body.prototype.m_xf);box2d.b2Body.prototype.m_out_xf=null;goog.exportProperty(box2d.b2Body.prototype,\"m_out_xf\",box2d.b2Body.prototype.m_out_xf);\nbox2d.b2Body.prototype.m_sweep=null;goog.exportProperty(box2d.b2Body.prototype,\"m_sweep\",box2d.b2Body.prototype.m_sweep);box2d.b2Body.prototype.m_out_sweep=null;goog.exportProperty(box2d.b2Body.prototype,\"m_out_sweep\",box2d.b2Body.prototype.m_out_sweep);box2d.b2Body.prototype.m_jointList=null;goog.exportProperty(box2d.b2Body.prototype,\"m_jointList\",box2d.b2Body.prototype.m_jointList);box2d.b2Body.prototype.m_contactList=null;goog.exportProperty(box2d.b2Body.prototype,\"m_contactList\",box2d.b2Body.prototype.m_contactList);\nbox2d.b2Body.prototype.m_prev=null;goog.exportProperty(box2d.b2Body.prototype,\"m_prev\",box2d.b2Body.prototype.m_prev);box2d.b2Body.prototype.m_next=null;goog.exportProperty(box2d.b2Body.prototype,\"m_next\",box2d.b2Body.prototype.m_next);box2d.b2Body.prototype.m_linearVelocity=null;goog.exportProperty(box2d.b2Body.prototype,\"m_linearVelocity\",box2d.b2Body.prototype.m_linearVelocity);box2d.b2Body.prototype.m_out_linearVelocity=null;goog.exportProperty(box2d.b2Body.prototype,\"m_out_linearVelocity\",box2d.b2Body.prototype.m_out_linearVelocity);\nbox2d.b2Body.prototype.m_angularVelocity=0;goog.exportProperty(box2d.b2Body.prototype,\"m_angularVelocity\",box2d.b2Body.prototype.m_angularVelocity);box2d.b2Body.prototype.m_linearDamping=0;goog.exportProperty(box2d.b2Body.prototype,\"m_linearDamping\",box2d.b2Body.prototype.m_linearDamping);box2d.b2Body.prototype.m_angularDamping=0;goog.exportProperty(box2d.b2Body.prototype,\"m_angularDamping\",box2d.b2Body.prototype.m_angularDamping);box2d.b2Body.prototype.m_gravityScale=1;\ngoog.exportProperty(box2d.b2Body.prototype,\"m_gravityScale\",box2d.b2Body.prototype.m_gravityScale);box2d.b2Body.prototype.m_force=null;goog.exportProperty(box2d.b2Body.prototype,\"m_force\",box2d.b2Body.prototype.m_force);box2d.b2Body.prototype.m_torque=0;goog.exportProperty(box2d.b2Body.prototype,\"m_torque\",box2d.b2Body.prototype.m_torque);box2d.b2Body.prototype.m_sleepTime=0;goog.exportProperty(box2d.b2Body.prototype,\"m_sleepTime\",box2d.b2Body.prototype.m_sleepTime);\nbox2d.b2Body.prototype.m_type=box2d.b2BodyType.b2_staticBody;goog.exportProperty(box2d.b2Body.prototype,\"m_type\",box2d.b2Body.prototype.m_type);box2d.b2Body.prototype.m_mass=1;goog.exportProperty(box2d.b2Body.prototype,\"m_mass\",box2d.b2Body.prototype.m_mass);box2d.b2Body.prototype.m_invMass=1;goog.exportProperty(box2d.b2Body.prototype,\"m_invMass\",box2d.b2Body.prototype.m_invMass);box2d.b2Body.prototype.m_I=0;goog.exportProperty(box2d.b2Body.prototype,\"m_I\",box2d.b2Body.prototype.m_I);\nbox2d.b2Body.prototype.m_invI=0;goog.exportProperty(box2d.b2Body.prototype,\"m_invI\",box2d.b2Body.prototype.m_invI);box2d.b2Body.prototype.m_userData=null;goog.exportProperty(box2d.b2Body.prototype,\"m_userData\",box2d.b2Body.prototype.m_userData);box2d.b2Body.prototype.m_fixtureList=null;goog.exportProperty(box2d.b2Body.prototype,\"m_fixtureList\",box2d.b2Body.prototype.m_fixtureList);box2d.b2Body.prototype.m_fixtureCount=0;goog.exportProperty(box2d.b2Body.prototype,\"m_fixtureCount\",box2d.b2Body.prototype.m_fixtureCount);\nbox2d.b2Body.prototype.m_controllerList=null;goog.exportProperty(box2d.b2Body.prototype,\"m_controllerList\",box2d.b2Body.prototype.m_controllerList);box2d.b2Body.prototype.m_controllerCount=0;goog.exportProperty(box2d.b2Body.prototype,\"m_controllerCount\",box2d.b2Body.prototype.m_controllerCount);\nbox2d.b2Body.prototype.CreateFixture=function(a){box2d.ENABLE_ASSERTS&&box2d.b2Assert(!1===this.m_world.IsLocked());if(!0===this.m_world.IsLocked())return null;var b=new box2d.b2Fixture;b.Create(this,a);this.m_flags&box2d.b2BodyFlag.e_activeFlag&&b.CreateProxies(this.m_world.m_contactManager.m_broadPhase,this.m_xf);b.m_next=this.m_fixtureList;this.m_fixtureList=b;++this.m_fixtureCount;b.m_body=this;0<b.m_density&&this.ResetMassData();this.m_world.m_flags|=box2d.b2WorldFlag.e_newFixture;return b};\ngoog.exportProperty(box2d.b2Body.prototype,\"CreateFixture\",box2d.b2Body.prototype.CreateFixture);box2d.b2Body.prototype.CreateFixture2=function(a,b){void 0===b&&(b=0);var c=box2d.b2Body.prototype.CreateFixture2.s_def;c.shape=a;c.density=b;return this.CreateFixture(c)};goog.exportProperty(box2d.b2Body.prototype,\"CreateFixture2\",box2d.b2Body.prototype.CreateFixture2);box2d.b2Body.prototype.CreateFixture2.s_def=new box2d.b2FixtureDef;\nbox2d.b2Body.prototype.DestroyFixture=function(a){box2d.ENABLE_ASSERTS&&box2d.b2Assert(!1===this.m_world.IsLocked());if(!0!==this.m_world.IsLocked()){box2d.ENABLE_ASSERTS&&box2d.b2Assert(a.m_body===this);box2d.ENABLE_ASSERTS&&box2d.b2Assert(0<this.m_fixtureCount);for(var b=this.m_fixtureList,c=null,e=!1;null!==b;){if(b===a){c?c.m_next=a.m_next:this.m_fixtureList=a.m_next;e=!0;break}c=b;b=b.m_next}box2d.ENABLE_ASSERTS&&box2d.b2Assert(e);for(b=this.m_contactList;b;){var c=b.contact,b=b.next,e=c.GetFixtureA(),\nd=c.GetFixtureB();a!==e&&a!==d||this.m_world.m_contactManager.Destroy(c)}this.m_flags&box2d.b2BodyFlag.e_activeFlag&&a.DestroyProxies(this.m_world.m_contactManager.m_broadPhase);a.Destroy();a.m_body=null;a.m_next=null;--this.m_fixtureCount;this.ResetMassData()}};goog.exportProperty(box2d.b2Body.prototype,\"DestroyFixture\",box2d.b2Body.prototype.DestroyFixture);box2d.b2Body.prototype.SetTransformVecRadians=function(a,b){this.SetTransformXYRadians(a.x,a.y,b)};\ngoog.exportProperty(box2d.b2Body.prototype,\"SetTransformVecRadians\",box2d.b2Body.prototype.SetTransformVecRadians);\nbox2d.b2Body.prototype.SetTransformXYRadians=function(a,b,c){box2d.ENABLE_ASSERTS&&box2d.b2Assert(!1===this.m_world.IsLocked());if(!0!==this.m_world.IsLocked()&&(this.m_xf.p.x!==a||this.m_xf.p.y!==b||this.m_xf.q.GetAngleRadians()!==c))for(this.m_xf.q.SetAngleRadians(c),this.m_xf.p.SetXY(a,b),box2d.b2MulXV(this.m_xf,this.m_sweep.localCenter,this.m_sweep.c),this.m_sweep.a=c,this.m_sweep.c0.Copy(this.m_sweep.c),this.m_sweep.a0=c,a=this.m_world.m_contactManager.m_broadPhase,b=this.m_fixtureList;b;b=b.m_next)b.Synchronize(a,\nthis.m_xf,this.m_xf)};goog.exportProperty(box2d.b2Body.prototype,\"SetTransformXYRadians\",box2d.b2Body.prototype.SetTransformXYRadians);box2d.b2Body.prototype.SetTransform=function(a){this.SetTransformVecRadians(a.p,a.GetAngleRadians())};goog.exportProperty(box2d.b2Body.prototype,\"SetTransform\",box2d.b2Body.prototype.SetTransform);box2d.b2Body.prototype.GetTransform=function(a){a=a||this.m_out_xf;return a.Copy(this.m_xf)};goog.exportProperty(box2d.b2Body.prototype,\"GetTransform\",box2d.b2Body.prototype.GetTransform);\nbox2d.b2Body.prototype.GetPosition=function(a){a=a||this.m_out_xf.p;return a.Copy(this.m_xf.p)};goog.exportProperty(box2d.b2Body.prototype,\"GetPosition\",box2d.b2Body.prototype.GetPosition);box2d.b2Body.prototype.SetPosition=function(a){this.SetTransformVecRadians(a,this.GetAngleRadians())};goog.exportProperty(box2d.b2Body.prototype,\"SetPosition\",box2d.b2Body.prototype.SetPosition);box2d.b2Body.prototype.SetPositionXY=function(a,b){this.SetTransformXYRadians(a,b,this.GetAngleRadians())};\ngoog.exportProperty(box2d.b2Body.prototype,\"SetPositionXY\",box2d.b2Body.prototype.SetPositionXY);box2d.b2Body.prototype.GetAngle=function(){return this.m_sweep.a};goog.exportProperty(box2d.b2Body.prototype,\"GetAngle\",box2d.b2Body.prototype.GetAngle);box2d.b2Body.prototype.GetAngleRadians=box2d.b2Body.prototype.GetAngle;box2d.b2Body.prototype.GetAngleDegrees=function(){return box2d.b2RadToDeg(this.GetAngle())};\nbox2d.b2Body.prototype.SetAngle=function(a){this.SetTransformVecRadians(this.GetPosition(),a)};goog.exportProperty(box2d.b2Body.prototype,\"SetAngle\",box2d.b2Body.prototype.SetAngle);box2d.b2Body.prototype.SetAngleRadians=box2d.b2Body.prototype.SetAngle;box2d.b2Body.prototype.SetAngleDegrees=function(a){this.SetAngle(box2d.b2DegToRad(a))};box2d.b2Body.prototype.GetWorldCenter=function(a){a=a||this.m_out_sweep.c;return a.Copy(this.m_sweep.c)};\ngoog.exportProperty(box2d.b2Body.prototype,\"GetWorldCenter\",box2d.b2Body.prototype.GetWorldCenter);box2d.b2Body.prototype.GetLocalCenter=function(a){a=a||this.m_out_sweep.localCenter;return a.Copy(this.m_sweep.localCenter)};goog.exportProperty(box2d.b2Body.prototype,\"GetLocalCenter\",box2d.b2Body.prototype.GetLocalCenter);box2d.b2Body.prototype.SetLinearVelocity=function(a){this.m_type!==box2d.b2BodyType.b2_staticBody&&(0<box2d.b2DotVV(a,a)&&this.SetAwake(!0),this.m_linearVelocity.Copy(a))};\ngoog.exportProperty(box2d.b2Body.prototype,\"SetLinearVelocity\",box2d.b2Body.prototype.SetLinearVelocity);box2d.b2Body.prototype.GetLinearVelocity=function(a){a=a||this.m_out_linearVelocity;return a.Copy(this.m_linearVelocity)};goog.exportProperty(box2d.b2Body.prototype,\"GetLinearVelocity\",box2d.b2Body.prototype.GetLinearVelocity);box2d.b2Body.prototype.SetAngularVelocity=function(a){this.m_type!==box2d.b2BodyType.b2_staticBody&&(0<a*a&&this.SetAwake(!0),this.m_angularVelocity=a)};\ngoog.exportProperty(box2d.b2Body.prototype,\"SetAngularVelocity\",box2d.b2Body.prototype.SetAngularVelocity);box2d.b2Body.prototype.GetAngularVelocity=function(){return this.m_angularVelocity};goog.exportProperty(box2d.b2Body.prototype,\"GetAngularVelocity\",box2d.b2Body.prototype.GetAngularVelocity);\nbox2d.b2Body.prototype.GetDefinition=function(a){a.type=this.GetType();a.allowSleep=(this.m_flags&box2d.b2BodyFlag.e_autoSleepFlag)===box2d.b2BodyFlag.e_autoSleepFlag;a.angle=this.GetAngleRadians();a.angularDamping=this.m_angularDamping;a.gravityScale=this.m_gravityScale;a.angularVelocity=this.m_angularVelocity;a.fixedRotation=(this.m_flags&box2d.b2BodyFlag.e_fixedRotationFlag)===box2d.b2BodyFlag.e_fixedRotationFlag;a.bullet=(this.m_flags&box2d.b2BodyFlag.e_bulletFlag)===box2d.b2BodyFlag.e_bulletFlag;\na.awake=(this.m_flags&box2d.b2BodyFlag.e_awakeFlag)===box2d.b2BodyFlag.e_awakeFlag;a.linearDamping=this.m_linearDamping;a.linearVelocity.Copy(this.GetLinearVelocity());a.position.Copy(this.GetPosition());a.userData=this.GetUserData();return a};goog.exportProperty(box2d.b2Body.prototype,\"GetDefinition\",box2d.b2Body.prototype.GetDefinition);\nbox2d.b2Body.prototype.ApplyForce=function(a,b,c){this.m_type===box2d.b2BodyType.b2_dynamicBody&&(0===(this.m_flags&box2d.b2BodyFlag.e_awakeFlag)&&this.SetAwake(!0),this.m_flags&box2d.b2BodyFlag.e_awakeFlag&&(this.m_force.x+=a.x,this.m_force.y+=a.y,this.m_torque+=(b.x-this.m_sweep.c.x)*a.y-(b.y-this.m_sweep.c.y)*a.x))};goog.exportProperty(box2d.b2Body.prototype,\"ApplyForce\",box2d.b2Body.prototype.ApplyForce);\nbox2d.b2Body.prototype.ApplyForceToCenter=function(a,b){this.m_type===box2d.b2BodyType.b2_dynamicBody&&(0===(this.m_flags&box2d.b2BodyFlag.e_awakeFlag)&&this.SetAwake(!0),this.m_flags&box2d.b2BodyFlag.e_awakeFlag&&(this.m_force.x+=a.x,this.m_force.y+=a.y))};goog.exportProperty(box2d.b2Body.prototype,\"ApplyForceToCenter\",box2d.b2Body.prototype.ApplyForceToCenter);\nbox2d.b2Body.prototype.ApplyTorque=function(a,b){this.m_type===box2d.b2BodyType.b2_dynamicBody&&(0===(this.m_flags&box2d.b2BodyFlag.e_awakeFlag)&&this.SetAwake(!0),this.m_flags&box2d.b2BodyFlag.e_awakeFlag&&(this.m_torque+=a))};goog.exportProperty(box2d.b2Body.prototype,\"ApplyTorque\",box2d.b2Body.prototype.ApplyTorque);\nbox2d.b2Body.prototype.ApplyLinearImpulse=function(a,b,c){this.m_type===box2d.b2BodyType.b2_dynamicBody&&(0===(this.m_flags&box2d.b2BodyFlag.e_awakeFlag)&&this.SetAwake(!0),this.m_flags&box2d.b2BodyFlag.e_awakeFlag&&(this.m_linearVelocity.x+=this.m_invMass*a.x,this.m_linearVelocity.y+=this.m_invMass*a.y,this.m_angularVelocity+=this.m_invI*((b.x-this.m_sweep.c.x)*a.y-(b.y-this.m_sweep.c.y)*a.x)))};goog.exportProperty(box2d.b2Body.prototype,\"ApplyLinearImpulse\",box2d.b2Body.prototype.ApplyLinearImpulse);\nbox2d.b2Body.prototype.ApplyAngularImpulse=function(a,b){this.m_type===box2d.b2BodyType.b2_dynamicBody&&(0===(this.m_flags&box2d.b2BodyFlag.e_awakeFlag)&&this.SetAwake(!0),this.m_flags&box2d.b2BodyFlag.e_awakeFlag&&(this.m_angularVelocity+=this.m_invI*a))};goog.exportProperty(box2d.b2Body.prototype,\"ApplyAngularImpulse\",box2d.b2Body.prototype.ApplyAngularImpulse);box2d.b2Body.prototype.GetMass=function(){return this.m_mass};goog.exportProperty(box2d.b2Body.prototype,\"GetMass\",box2d.b2Body.prototype.GetMass);\nbox2d.b2Body.prototype.GetInertia=function(){return this.m_I+this.m_mass*box2d.b2DotVV(this.m_sweep.localCenter,this.m_sweep.localCenter)};goog.exportProperty(box2d.b2Body.prototype,\"GetInertia\",box2d.b2Body.prototype.GetInertia);box2d.b2Body.prototype.GetMassData=function(a){a.mass=this.m_mass;a.I=this.m_I+this.m_mass*box2d.b2DotVV(this.m_sweep.localCenter,this.m_sweep.localCenter);a.center.Copy(this.m_sweep.localCenter);return a};goog.exportProperty(box2d.b2Body.prototype,\"GetMassData\",box2d.b2Body.prototype.GetMassData);\nbox2d.b2Body.prototype.SetMassData=function(a){box2d.ENABLE_ASSERTS&&box2d.b2Assert(!1===this.m_world.IsLocked());if(!0!==this.m_world.IsLocked()&&this.m_type===box2d.b2BodyType.b2_dynamicBody){this.m_invI=this.m_I=this.m_invMass=0;this.m_mass=a.mass;0>=this.m_mass&&(this.m_mass=1);this.m_invMass=1/this.m_mass;0<a.I&&0===(this.m_flags&box2d.b2BodyFlag.e_fixedRotationFlag)&&(this.m_I=a.I-this.m_mass*box2d.b2DotVV(a.center,a.center),box2d.ENABLE_ASSERTS&&box2d.b2Assert(0<this.m_I),this.m_invI=1/this.m_I);\nvar b=box2d.b2Body.prototype.SetMassData.s_oldCenter.Copy(this.m_sweep.c);this.m_sweep.localCenter.Copy(a.center);box2d.b2MulXV(this.m_xf,this.m_sweep.localCenter,this.m_sweep.c);this.m_sweep.c0.Copy(this.m_sweep.c);box2d.b2AddVCrossSV(this.m_linearVelocity,this.m_angularVelocity,box2d.b2SubVV(this.m_sweep.c,b,box2d.b2Vec2.s_t0),this.m_linearVelocity)}};goog.exportProperty(box2d.b2Body.prototype,\"SetMassData\",box2d.b2Body.prototype.SetMassData);box2d.b2Body.prototype.SetMassData.s_oldCenter=new box2d.b2Vec2;\nbox2d.b2Body.prototype.ResetMassData=function(){this.m_invI=this.m_I=this.m_invMass=this.m_mass=0;this.m_sweep.localCenter.SetZero();if(this.m_type===box2d.b2BodyType.b2_staticBody||this.m_type===box2d.b2BodyType.b2_kinematicBody)this.m_sweep.c0.Copy(this.m_xf.p),this.m_sweep.c.Copy(this.m_xf.p),this.m_sweep.a0=this.m_sweep.a;else{box2d.ENABLE_ASSERTS&&box2d.b2Assert(this.m_type===box2d.b2BodyType.b2_dynamicBody);for(var a=box2d.b2Body.prototype.ResetMassData.s_localCenter.SetZero(),b=this.m_fixtureList;b;b=\nb.m_next)if(0!==b.m_density){var c=b.GetMassData(box2d.b2Body.prototype.ResetMassData.s_massData);this.m_mass+=c.mass;a.x+=c.center.x*c.mass;a.y+=c.center.y*c.mass;this.m_I+=c.I}0<this.m_mass?(this.m_invMass=1/this.m_mass,a.x*=this.m_invMass,a.y*=this.m_invMass):this.m_invMass=this.m_mass=1;0<this.m_I&&0===(this.m_flags&box2d.b2BodyFlag.e_fixedRotationFlag)?(this.m_I-=this.m_mass*box2d.b2DotVV(a,a),box2d.ENABLE_ASSERTS&&box2d.b2Assert(0<this.m_I),this.m_invI=1/this.m_I):this.m_invI=this.m_I=0;b=box2d.b2Body.prototype.ResetMassData.s_oldCenter.Copy(this.m_sweep.c);\nthis.m_sweep.localCenter.Copy(a);box2d.b2MulXV(this.m_xf,this.m_sweep.localCenter,this.m_sweep.c);this.m_sweep.c0.Copy(this.m_sweep.c);box2d.b2AddVCrossSV(this.m_linearVelocity,this.m_angularVelocity,box2d.b2SubVV(this.m_sweep.c,b,box2d.b2Vec2.s_t0),this.m_linearVelocity)}};goog.exportProperty(box2d.b2Body.prototype,\"ResetMassData\",box2d.b2Body.prototype.ResetMassData);box2d.b2Body.prototype.ResetMassData.s_localCenter=new box2d.b2Vec2;box2d.b2Body.prototype.ResetMassData.s_oldCenter=new box2d.b2Vec2;\nbox2d.b2Body.prototype.ResetMassData.s_massData=new box2d.b2MassData;box2d.b2Body.prototype.GetWorldPoint=function(a,b){return box2d.b2MulXV(this.m_xf,a,b)};goog.exportProperty(box2d.b2Body.prototype,\"GetWorldPoint\",box2d.b2Body.prototype.GetWorldPoint);box2d.b2Body.prototype.GetWorldVector=function(a,b){return box2d.b2MulRV(this.m_xf.q,a,b)};goog.exportProperty(box2d.b2Body.prototype,\"GetWorldVector\",box2d.b2Body.prototype.GetWorldVector);\nbox2d.b2Body.prototype.GetLocalPoint=function(a,b){return box2d.b2MulTXV(this.m_xf,a,b)};goog.exportProperty(box2d.b2Body.prototype,\"GetLocalPoint\",box2d.b2Body.prototype.GetLocalPoint);box2d.b2Body.prototype.GetLocalVector=function(a,b){return box2d.b2MulTRV(this.m_xf.q,a,b)};goog.exportProperty(box2d.b2Body.prototype,\"GetLocalVector\",box2d.b2Body.prototype.GetLocalVector);\nbox2d.b2Body.prototype.GetLinearVelocityFromWorldPoint=function(a,b){return box2d.b2AddVCrossSV(this.m_linearVelocity,this.m_angularVelocity,box2d.b2SubVV(a,this.m_sweep.c,box2d.b2Vec2.s_t0),b)};goog.exportProperty(box2d.b2Body.prototype,\"GetLinearVelocityFromWorldPoint\",box2d.b2Body.prototype.GetLinearVelocityFromWorldPoint);box2d.b2Body.prototype.GetLinearVelocityFromLocalPoint=function(a,b){return this.GetLinearVelocityFromWorldPoint(this.GetWorldPoint(a,b),b)};\ngoog.exportProperty(box2d.b2Body.prototype,\"GetLinearVelocityFromLocalPoint\",box2d.b2Body.prototype.GetLinearVelocityFromLocalPoint);box2d.b2Body.prototype.GetLinearDamping=function(){return this.m_linearDamping};goog.exportProperty(box2d.b2Body.prototype,\"GetLinearDamping\",box2d.b2Body.prototype.GetLinearDamping);box2d.b2Body.prototype.SetLinearDamping=function(a){this.m_linearDamping=a};goog.exportProperty(box2d.b2Body.prototype,\"SetLinearDamping\",box2d.b2Body.prototype.SetLinearDamping);\nbox2d.b2Body.prototype.GetAngularDamping=function(){return this.m_angularDamping};goog.exportProperty(box2d.b2Body.prototype,\"GetAngularDamping\",box2d.b2Body.prototype.GetAngularDamping);box2d.b2Body.prototype.SetAngularDamping=function(a){this.m_angularDamping=a};goog.exportProperty(box2d.b2Body.prototype,\"SetAngularDamping\",box2d.b2Body.prototype.SetAngularDamping);box2d.b2Body.prototype.GetGravityScale=function(){return this.m_gravityScale};\ngoog.exportProperty(box2d.b2Body.prototype,\"GetGravityScale\",box2d.b2Body.prototype.GetGravityScale);box2d.b2Body.prototype.SetGravityScale=function(a){this.m_gravityScale=a};goog.exportProperty(box2d.b2Body.prototype,\"SetGravityScale\",box2d.b2Body.prototype.SetGravityScale);\nbox2d.b2Body.prototype.SetType=function(a){box2d.ENABLE_ASSERTS&&box2d.b2Assert(!1===this.m_world.IsLocked());if(!0!==this.m_world.IsLocked()&&this.m_type!==a){this.m_type=a;this.ResetMassData();this.m_type===box2d.b2BodyType.b2_staticBody&&(this.m_linearVelocity.SetZero(),this.m_angularVelocity=0,this.m_sweep.a0=this.m_sweep.a,this.m_sweep.c0.Copy(this.m_sweep.c),this.SynchronizeFixtures());this.SetAwake(!0);this.m_force.SetZero();this.m_torque=0;for(a=this.m_contactList;a;){var b=a;a=a.next;this.m_world.m_contactManager.Destroy(b.contact)}this.m_contactList=\nnull;a=this.m_world.m_contactManager.m_broadPhase;for(b=this.m_fixtureList;b;b=b.m_next)for(var c=b.m_proxyCount,e=0;e<c;++e)a.TouchProxy(b.m_proxies[e].proxy)}};goog.exportProperty(box2d.b2Body.prototype,\"SetType\",box2d.b2Body.prototype.SetType);box2d.b2Body.prototype.GetType=function(){return this.m_type};goog.exportProperty(box2d.b2Body.prototype,\"GetType\",box2d.b2Body.prototype.GetType);\nbox2d.b2Body.prototype.SetBullet=function(a){this.m_flags=a?this.m_flags|box2d.b2BodyFlag.e_bulletFlag:this.m_flags&~box2d.b2BodyFlag.e_bulletFlag};goog.exportProperty(box2d.b2Body.prototype,\"SetBullet\",box2d.b2Body.prototype.SetBullet);box2d.b2Body.prototype.IsBullet=function(){return(this.m_flags&box2d.b2BodyFlag.e_bulletFlag)===box2d.b2BodyFlag.e_bulletFlag};goog.exportProperty(box2d.b2Body.prototype,\"IsBullet\",box2d.b2Body.prototype.IsBullet);\nbox2d.b2Body.prototype.SetSleepingAllowed=function(a){a?this.m_flags|=box2d.b2BodyFlag.e_autoSleepFlag:(this.m_flags&=~box2d.b2BodyFlag.e_autoSleepFlag,this.SetAwake(!0))};goog.exportProperty(box2d.b2Body.prototype,\"SetSleepingAllowed\",box2d.b2Body.prototype.SetSleepingAllowed);box2d.b2Body.prototype.IsSleepingAllowed=function(){return(this.m_flags&box2d.b2BodyFlag.e_autoSleepFlag)===box2d.b2BodyFlag.e_autoSleepFlag};goog.exportProperty(box2d.b2Body.prototype,\"IsSleepingAllowed\",box2d.b2Body.prototype.IsSleepingAllowed);\nbox2d.b2Body.prototype.SetAwake=function(a){a?0===(this.m_flags&box2d.b2BodyFlag.e_awakeFlag)&&(this.m_flags|=box2d.b2BodyFlag.e_awakeFlag,this.m_sleepTime=0):(this.m_flags&=~box2d.b2BodyFlag.e_awakeFlag,this.m_sleepTime=0,this.m_linearVelocity.SetZero(),this.m_angularVelocity=0,this.m_force.SetZero(),this.m_torque=0)};goog.exportProperty(box2d.b2Body.prototype,\"SetAwake\",box2d.b2Body.prototype.SetAwake);\nbox2d.b2Body.prototype.IsAwake=function(){return(this.m_flags&box2d.b2BodyFlag.e_awakeFlag)===box2d.b2BodyFlag.e_awakeFlag};goog.exportProperty(box2d.b2Body.prototype,\"IsAwake\",box2d.b2Body.prototype.IsAwake);\nbox2d.b2Body.prototype.SetActive=function(a){box2d.ENABLE_ASSERTS&&box2d.b2Assert(!1===this.m_world.IsLocked());if(a!==this.IsActive())if(a){this.m_flags|=box2d.b2BodyFlag.e_activeFlag;a=this.m_world.m_contactManager.m_broadPhase;for(var b=this.m_fixtureList;b;b=b.m_next)b.CreateProxies(a,this.m_xf)}else{this.m_flags&=~box2d.b2BodyFlag.e_activeFlag;a=this.m_world.m_contactManager.m_broadPhase;for(b=this.m_fixtureList;b;b=b.m_next)b.DestroyProxies(a);for(a=this.m_contactList;a;)b=a,a=a.next,this.m_world.m_contactManager.Destroy(b.contact);\nthis.m_contactList=null}};goog.exportProperty(box2d.b2Body.prototype,\"SetActive\",box2d.b2Body.prototype.SetActive);box2d.b2Body.prototype.IsActive=function(){return(this.m_flags&box2d.b2BodyFlag.e_activeFlag)===box2d.b2BodyFlag.e_activeFlag};goog.exportProperty(box2d.b2Body.prototype,\"IsActive\",box2d.b2Body.prototype.IsActive);\nbox2d.b2Body.prototype.SetFixedRotation=function(a){(this.m_flags&box2d.b2BodyFlag.e_fixedRotationFlag)===box2d.b2BodyFlag.e_fixedRotationFlag!==a&&(this.m_flags=a?this.m_flags|box2d.b2BodyFlag.e_fixedRotationFlag:this.m_flags&~box2d.b2BodyFlag.e_fixedRotationFlag,this.m_angularVelocity=0,this.ResetMassData())};goog.exportProperty(box2d.b2Body.prototype,\"SetFixedRotation\",box2d.b2Body.prototype.SetFixedRotation);\nbox2d.b2Body.prototype.IsFixedRotation=function(){return(this.m_flags&box2d.b2BodyFlag.e_fixedRotationFlag)===box2d.b2BodyFlag.e_fixedRotationFlag};goog.exportProperty(box2d.b2Body.prototype,\"IsFixedRotation\",box2d.b2Body.prototype.IsFixedRotation);box2d.b2Body.prototype.GetFixtureList=function(){return this.m_fixtureList};goog.exportProperty(box2d.b2Body.prototype,\"GetFixtureList\",box2d.b2Body.prototype.GetFixtureList);box2d.b2Body.prototype.GetJointList=function(){return this.m_jointList};\ngoog.exportProperty(box2d.b2Body.prototype,\"GetJointList\",box2d.b2Body.prototype.GetJointList);box2d.b2Body.prototype.GetContactList=function(){return this.m_contactList};goog.exportProperty(box2d.b2Body.prototype,\"GetContactList\",box2d.b2Body.prototype.GetContactList);box2d.b2Body.prototype.GetNext=function(){return this.m_next};goog.exportProperty(box2d.b2Body.prototype,\"GetNext\",box2d.b2Body.prototype.GetNext);box2d.b2Body.prototype.GetUserData=function(){return this.m_userData};\ngoog.exportProperty(box2d.b2Body.prototype,\"GetUserData\",box2d.b2Body.prototype.GetUserData);box2d.b2Body.prototype.SetUserData=function(a){this.m_userData=a};goog.exportProperty(box2d.b2Body.prototype,\"SetUserData\",box2d.b2Body.prototype.SetUserData);box2d.b2Body.prototype.GetWorld=function(){return this.m_world};goog.exportProperty(box2d.b2Body.prototype,\"GetWorld\",box2d.b2Body.prototype.GetWorld);\nbox2d.b2Body.prototype.SynchronizeFixtures=function(){var a=box2d.b2Body.prototype.SynchronizeFixtures.s_xf1;a.q.SetAngleRadians(this.m_sweep.a0);box2d.b2MulRV(a.q,this.m_sweep.localCenter,a.p);box2d.b2SubVV(this.m_sweep.c0,a.p,a.p);for(var b=this.m_world.m_contactManager.m_broadPhase,c=this.m_fixtureList;c;c=c.m_next)c.Synchronize(b,a,this.m_xf)};goog.exportProperty(box2d.b2Body.prototype,\"SynchronizeFixtures\",box2d.b2Body.prototype.SynchronizeFixtures);\nbox2d.b2Body.prototype.SynchronizeFixtures.s_xf1=new box2d.b2Transform;box2d.b2Body.prototype.SynchronizeTransform=function(){this.m_xf.q.SetAngleRadians(this.m_sweep.a);box2d.b2MulRV(this.m_xf.q,this.m_sweep.localCenter,this.m_xf.p);box2d.b2SubVV(this.m_sweep.c,this.m_xf.p,this.m_xf.p)};goog.exportProperty(box2d.b2Body.prototype,\"SynchronizeTransform\",box2d.b2Body.prototype.SynchronizeTransform);\nbox2d.b2Body.prototype.ShouldCollide=function(a){if(this.m_type!==box2d.b2BodyType.b2_dynamicBody&&a.m_type!==box2d.b2BodyType.b2_dynamicBody)return!1;for(var b=this.m_jointList;b;b=b.next)if(b.other===a&&!1===b.joint.m_collideConnected)return!1;return!0};goog.exportProperty(box2d.b2Body.prototype,\"ShouldCollide\",box2d.b2Body.prototype.ShouldCollide);\nbox2d.b2Body.prototype.Advance=function(a){this.m_sweep.Advance(a);this.m_sweep.c.Copy(this.m_sweep.c0);this.m_sweep.a=this.m_sweep.a0;this.m_xf.q.SetAngleRadians(this.m_sweep.a);box2d.b2MulRV(this.m_xf.q,this.m_sweep.localCenter,this.m_xf.p);box2d.b2SubVV(this.m_sweep.c,this.m_xf.p,this.m_xf.p)};goog.exportProperty(box2d.b2Body.prototype,\"Advance\",box2d.b2Body.prototype.Advance);\nbox2d.b2Body.prototype.Dump=function(){if(box2d.DEBUG){var a=this.m_islandIndex;box2d.b2Log(\"if (true)\\n\");box2d.b2Log(\"{\\n\");box2d.b2Log(\"  /*box2d.b2BodyDef*/ var bd = new box2d.b2BodyDef();\\n\");var b=\"\";switch(this.m_type){case box2d.b2BodyType.b2_staticBody:b=\"box2d.b2BodyType.b2_staticBody\";break;case box2d.b2BodyType.b2_kinematicBody:b=\"box2d.b2BodyType.b2_kinematicBody\";break;case box2d.b2BodyType.b2_dynamicBody:b=\"box2d.b2BodyType.b2_dynamicBody\";break;default:box2d.ENABLE_ASSERTS&&box2d.b2Assert(!1)}box2d.b2Log(\"  bd.type = %s;\\n\",\nb);box2d.b2Log(\"  bd.position.SetXY(%.15f, %.15f);\\n\",this.m_xf.p.x,this.m_xf.p.y);box2d.b2Log(\"  bd.angle = %.15f;\\n\",this.m_sweep.a);box2d.b2Log(\"  bd.linearVelocity.SetXY(%.15f, %.15f);\\n\",this.m_linearVelocity.x,this.m_linearVelocity.y);box2d.b2Log(\"  bd.angularVelocity = %.15f;\\n\",this.m_angularVelocity);box2d.b2Log(\"  bd.linearDamping = %.15f;\\n\",this.m_linearDamping);box2d.b2Log(\"  bd.angularDamping = %.15f;\\n\",this.m_angularDamping);box2d.b2Log(\"  bd.allowSleep = %s;\\n\",this.m_flags&box2d.b2BodyFlag.e_autoSleepFlag?\n\"true\":\"false\");box2d.b2Log(\"  bd.awake = %s;\\n\",this.m_flags&box2d.b2BodyFlag.e_awakeFlag?\"true\":\"false\");box2d.b2Log(\"  bd.fixedRotation = %s;\\n\",this.m_flags&box2d.b2BodyFlag.e_fixedRotationFlag?\"true\":\"false\");box2d.b2Log(\"  bd.bullet = %s;\\n\",this.m_flags&box2d.b2BodyFlag.e_bulletFlag?\"true\":\"false\");box2d.b2Log(\"  bd.active = %s;\\n\",this.m_flags&box2d.b2BodyFlag.e_activeFlag?\"true\":\"false\");box2d.b2Log(\"  bd.gravityScale = %.15f;\\n\",this.m_gravityScale);box2d.b2Log(\"\\n\");box2d.b2Log(\"  bodies[%d] = this.m_world.CreateBody(bd);\\n\",\nthis.m_islandIndex);box2d.b2Log(\"\\n\");for(b=this.m_fixtureList;b;b=b.m_next)box2d.b2Log(\"  if (true)\\n\"),box2d.b2Log(\"  {\\n\"),b.Dump(a),box2d.b2Log(\"  }\\n\");box2d.b2Log(\"}\\n\")}};goog.exportProperty(box2d.b2Body.prototype,\"Dump\",box2d.b2Body.prototype.Dump);box2d.b2Body.prototype.GetControllerList=function(){return this.m_controllerList};goog.exportProperty(box2d.b2Body.prototype,\"GetControllerList\",box2d.b2Body.prototype.GetControllerList);box2d.b2Body.prototype.GetControllerCount=function(){return this.m_controllerCount};\ngoog.exportProperty(box2d.b2Body.prototype,\"GetControllerCount\",box2d.b2Body.prototype.GetControllerCount);box2d.b2WorldFlag={e_none:0,e_newFixture:1,e_locked:2,e_clearForces:4};goog.exportSymbol(\"box2d.b2WorldFlag\",box2d.b2WorldFlag);goog.exportProperty(box2d.b2WorldFlag,\"e_none\",box2d.b2WorldFlag.e_none);goog.exportProperty(box2d.b2WorldFlag,\"e_newFixture\",box2d.b2WorldFlag.e_newFixture);goog.exportProperty(box2d.b2WorldFlag,\"e_locked\",box2d.b2WorldFlag.e_locked);goog.exportProperty(box2d.b2WorldFlag,\"e_clearForces\",box2d.b2WorldFlag.e_clearForces);\nbox2d.b2World=function(a){this.m_flags=box2d.b2WorldFlag.e_clearForces;this.m_contactManager=new box2d.b2ContactManager;this.m_gravity=a.Clone();this.m_out_gravity=new box2d.b2Vec2;this.m_allowSleep=!0;this.m_debugDraw=this.m_destructionListener=null;this.m_continuousPhysics=this.m_warmStarting=!0;this.m_subStepping=!1;this.m_stepComplete=!0;this.m_profile=new box2d.b2Profile;this.m_island=new box2d.b2Island;this.s_stack=[]};goog.exportSymbol(\"box2d.b2World\",box2d.b2World);\nbox2d.b2World.prototype.m_flags=box2d.b2WorldFlag.e_none;goog.exportProperty(box2d.b2World.prototype,\"m_flags\",box2d.b2World.prototype.m_flags);box2d.b2World.prototype.m_contactManager=null;goog.exportProperty(box2d.b2World.prototype,\"m_contactManager\",box2d.b2World.prototype.m_contactManager);box2d.b2World.prototype.m_bodyList=null;goog.exportProperty(box2d.b2World.prototype,\"m_bodyList\",box2d.b2World.prototype.m_bodyList);box2d.b2World.prototype.m_jointList=null;\ngoog.exportProperty(box2d.b2World.prototype,\"m_jointList\",box2d.b2World.prototype.m_jointList);box2d.b2World.prototype.m_bodyCount=0;goog.exportProperty(box2d.b2World.prototype,\"m_bodyCount\",box2d.b2World.prototype.m_bodyCount);box2d.b2World.prototype.m_jointCount=0;goog.exportProperty(box2d.b2World.prototype,\"m_jointCount\",box2d.b2World.prototype.m_jointCount);box2d.b2World.prototype.m_gravity=null;goog.exportProperty(box2d.b2World.prototype,\"m_gravity\",box2d.b2World.prototype.m_gravity);\nbox2d.b2World.prototype.m_out_gravity=null;goog.exportProperty(box2d.b2World.prototype,\"m_out_gravity\",box2d.b2World.prototype.m_out_gravity);box2d.b2World.prototype.m_allowSleep=!0;goog.exportProperty(box2d.b2World.prototype,\"m_allowSleep\",box2d.b2World.prototype.m_allowSleep);box2d.b2World.prototype.m_destructionListener=null;goog.exportProperty(box2d.b2World.prototype,\"m_destructionListener\",box2d.b2World.prototype.m_destructionListener);box2d.b2World.prototype.m_debugDraw=null;\ngoog.exportProperty(box2d.b2World.prototype,\"m_debugDraw\",box2d.b2World.prototype.m_debugDraw);box2d.b2World.prototype.m_inv_dt0=0;goog.exportProperty(box2d.b2World.prototype,\"m_inv_dt0\",box2d.b2World.prototype.m_inv_dt0);box2d.b2World.prototype.m_warmStarting=!0;goog.exportProperty(box2d.b2World.prototype,\"m_warmStarting\",box2d.b2World.prototype.m_warmStarting);box2d.b2World.prototype.m_continuousPhysics=!0;goog.exportProperty(box2d.b2World.prototype,\"m_continuousPhysics\",box2d.b2World.prototype.m_continuousPhysics);\nbox2d.b2World.prototype.m_subStepping=!1;goog.exportProperty(box2d.b2World.prototype,\"m_subStepping\",box2d.b2World.prototype.m_subStepping);box2d.b2World.prototype.m_stepComplete=!0;goog.exportProperty(box2d.b2World.prototype,\"m_stepComplete\",box2d.b2World.prototype.m_stepComplete);box2d.b2World.prototype.m_profile=null;goog.exportProperty(box2d.b2World.prototype,\"m_profile\",box2d.b2World.prototype.m_profile);box2d.b2World.prototype.m_island=null;\ngoog.exportProperty(box2d.b2World.prototype,\"m_island\",box2d.b2World.prototype.m_island);box2d.b2World.prototype.s_stack=null;goog.exportProperty(box2d.b2World.prototype,\"s_stack\",box2d.b2World.prototype.s_stack);box2d.b2World.prototype.m_controllerList=null;goog.exportProperty(box2d.b2World.prototype,\"m_controllerList\",box2d.b2World.prototype.m_controllerList);box2d.b2World.prototype.m_controllerCount=0;goog.exportProperty(box2d.b2World.prototype,\"m_controllerCount\",box2d.b2World.prototype.m_controllerCount);\nbox2d.b2World.prototype.SetAllowSleeping=function(a){if(a!==this.m_allowSleep&&(this.m_allowSleep=a,!1===this.m_allowSleep))for(a=this.m_bodyList;a;a=a.m_next)a.SetAwake(!0)};goog.exportProperty(box2d.b2World.prototype,\"SetAllowSleeping\",box2d.b2World.prototype.SetAllowSleeping);box2d.b2World.prototype.GetAllowSleeping=function(){return this.m_allowSleep};goog.exportProperty(box2d.b2World.prototype,\"GetAllowSleeping\",box2d.b2World.prototype.GetAllowSleeping);\nbox2d.b2World.prototype.SetWarmStarting=function(a){this.m_warmStarting=a};goog.exportProperty(box2d.b2World.prototype,\"SetWarmStarting\",box2d.b2World.prototype.SetWarmStarting);box2d.b2World.prototype.GetWarmStarting=function(){return this.m_warmStarting};goog.exportProperty(box2d.b2World.prototype,\"GetWarmStarting\",box2d.b2World.prototype.GetWarmStarting);box2d.b2World.prototype.SetContinuousPhysics=function(a){this.m_continuousPhysics=a};\ngoog.exportProperty(box2d.b2World.prototype,\"SetContinuousPhysics\",box2d.b2World.prototype.SetContinuousPhysics);box2d.b2World.prototype.GetContinuousPhysics=function(){return this.m_continuousPhysics};goog.exportProperty(box2d.b2World.prototype,\"GetContinuousPhysics\",box2d.b2World.prototype.GetContinuousPhysics);box2d.b2World.prototype.SetSubStepping=function(a){this.m_subStepping=a};goog.exportProperty(box2d.b2World.prototype,\"SetSubStepping\",box2d.b2World.prototype.SetSubStepping);\nbox2d.b2World.prototype.GetSubStepping=function(){return this.m_subStepping};goog.exportProperty(box2d.b2World.prototype,\"GetSubStepping\",box2d.b2World.prototype.GetSubStepping);box2d.b2World.prototype.GetBodyList=function(){return this.m_bodyList};goog.exportProperty(box2d.b2World.prototype,\"GetBodyList\",box2d.b2World.prototype.GetBodyList);box2d.b2World.prototype.GetJointList=function(){return this.m_jointList};goog.exportProperty(box2d.b2World.prototype,\"GetJointList\",box2d.b2World.prototype.GetJointList);\nbox2d.b2World.prototype.GetContactList=function(){return this.m_contactManager.m_contactList};goog.exportProperty(box2d.b2World.prototype,\"GetContactList\",box2d.b2World.prototype.GetContactList);box2d.b2World.prototype.GetBodyCount=function(){return this.m_bodyCount};goog.exportProperty(box2d.b2World.prototype,\"GetBodyCount\",box2d.b2World.prototype.GetBodyCount);box2d.b2World.prototype.GetJointCount=function(){return this.m_jointCount};goog.exportProperty(box2d.b2World.prototype,\"GetJointCount\",box2d.b2World.prototype.GetJointCount);\nbox2d.b2World.prototype.GetContactCount=function(){return this.m_contactManager.m_contactCount};goog.exportProperty(box2d.b2World.prototype,\"GetContactCount\",box2d.b2World.prototype.GetContactCount);box2d.b2World.prototype.SetGravity=function(a,b){b=b||!0;if(this.m_gravity.x!==a.x||this.m_gravity.y!==a.y)if(this.m_gravity.Copy(a),b)for(var c=this.m_bodyList;c;c=c.m_next)c.SetAwake(!0)};goog.exportProperty(box2d.b2World.prototype,\"SetGravity\",box2d.b2World.prototype.SetGravity);\nbox2d.b2World.prototype.GetGravity=function(a){a=a||this.m_out_gravity;return a.Copy(this.m_gravity)};goog.exportProperty(box2d.b2World.prototype,\"GetGravity\",box2d.b2World.prototype.GetGravity);box2d.b2World.prototype.IsLocked=function(){return 0<(this.m_flags&box2d.b2WorldFlag.e_locked)};goog.exportProperty(box2d.b2World.prototype,\"IsLocked\",box2d.b2World.prototype.IsLocked);\nbox2d.b2World.prototype.SetAutoClearForces=function(a){this.m_flags=a?this.m_flags|box2d.b2WorldFlag.e_clearForces:this.m_flags&~box2d.b2WorldFlag.e_clearForces};goog.exportProperty(box2d.b2World.prototype,\"SetAutoClearForces\",box2d.b2World.prototype.SetAutoClearForces);box2d.b2World.prototype.GetAutoClearForces=function(){return(this.m_flags&box2d.b2WorldFlag.e_clearForces)===box2d.b2WorldFlag.e_clearForces};goog.exportProperty(box2d.b2World.prototype,\"GetAutoClearForces\",box2d.b2World.prototype.GetAutoClearForces);\nbox2d.b2World.prototype.GetContactManager=function(){return this.m_contactManager};goog.exportProperty(box2d.b2World.prototype,\"GetContactManager\",box2d.b2World.prototype.GetContactManager);box2d.b2World.prototype.GetProfile=function(){return this.m_profile};goog.exportProperty(box2d.b2World.prototype,\"GetProfile\",box2d.b2World.prototype.GetProfile);box2d.b2World.prototype.SetDestructionListener=function(a){this.m_destructionListener=a};\ngoog.exportProperty(box2d.b2World.prototype,\"SetDestructionListener\",box2d.b2World.prototype.SetDestructionListener);box2d.b2World.prototype.SetContactFilter=function(a){this.m_contactManager.m_contactFilter=a};goog.exportProperty(box2d.b2World.prototype,\"SetContactFilter\",box2d.b2World.prototype.SetContactFilter);box2d.b2World.prototype.SetContactListener=function(a){this.m_contactManager.m_contactListener=a};goog.exportProperty(box2d.b2World.prototype,\"SetContactListener\",box2d.b2World.prototype.SetContactListener);\nbox2d.b2World.prototype.SetDebugDraw=function(a){this.m_debugDraw=a};goog.exportProperty(box2d.b2World.prototype,\"SetDebugDraw\",box2d.b2World.prototype.SetDebugDraw);box2d.b2World.prototype.CreateBody=function(a){box2d.ENABLE_ASSERTS&&box2d.b2Assert(!1===this.IsLocked());if(this.IsLocked())return null;a=new box2d.b2Body(a,this);a.m_prev=null;if(a.m_next=this.m_bodyList)this.m_bodyList.m_prev=a;this.m_bodyList=a;++this.m_bodyCount;return a};\ngoog.exportProperty(box2d.b2World.prototype,\"CreateBody\",box2d.b2World.prototype.CreateBody);\nbox2d.b2World.prototype.DestroyBody=function(a){box2d.ENABLE_ASSERTS&&box2d.b2Assert(0<this.m_bodyCount);box2d.ENABLE_ASSERTS&&box2d.b2Assert(!1===this.IsLocked());if(!this.IsLocked()){for(var b=a.m_jointList;b;){var c=b,b=b.next;this.m_destructionListener&&this.m_destructionListener.SayGoodbyeJoint(c.joint);this.DestroyJoint(c.joint);a.m_jointList=b}a.m_jointList=null;for(b=a.m_controllerList;b;)c=b,b=b.nextController,c.controller.RemoveBody(a);for(b=a.m_contactList;b;)c=b,b=b.next,this.m_contactManager.Destroy(c.contact);\na.m_contactList=null;for(b=a.m_fixtureList;b;)c=b,b=b.m_next,this.m_destructionListener&&this.m_destructionListener.SayGoodbyeFixture(c),c.DestroyProxies(this.m_contactManager.m_broadPhase),c.Destroy(),a.m_fixtureList=b,a.m_fixtureCount-=1;a.m_fixtureList=null;a.m_fixtureCount=0;a.m_prev&&(a.m_prev.m_next=a.m_next);a.m_next&&(a.m_next.m_prev=a.m_prev);a===this.m_bodyList&&(this.m_bodyList=a.m_next);--this.m_bodyCount}};goog.exportProperty(box2d.b2World.prototype,\"DestroyBody\",box2d.b2World.prototype.DestroyBody);\nbox2d.b2World.prototype.CreateJoint=function(a){box2d.ENABLE_ASSERTS&&box2d.b2Assert(!1===this.IsLocked());if(this.IsLocked())return null;var b=box2d.b2JointFactory.Create(a,null);b.m_prev=null;if(b.m_next=this.m_jointList)this.m_jointList.m_prev=b;this.m_jointList=b;++this.m_jointCount;b.m_edgeA.joint=b;b.m_edgeA.other=b.m_bodyB;b.m_edgeA.prev=null;if(b.m_edgeA.next=b.m_bodyA.m_jointList)b.m_bodyA.m_jointList.prev=b.m_edgeA;b.m_bodyA.m_jointList=b.m_edgeA;b.m_edgeB.joint=b;b.m_edgeB.other=b.m_bodyA;\nb.m_edgeB.prev=null;if(b.m_edgeB.next=b.m_bodyB.m_jointList)b.m_bodyB.m_jointList.prev=b.m_edgeB;b.m_bodyB.m_jointList=b.m_edgeB;var c=a.bodyA,e=a.bodyB;if(!1===a.collideConnected)for(a=e.GetContactList();a;)a.other===c&&a.contact.FlagForFiltering(),a=a.next;return b};goog.exportProperty(box2d.b2World.prototype,\"CreateJoint\",box2d.b2World.prototype.CreateJoint);\nbox2d.b2World.prototype.DestroyJoint=function(a){box2d.ENABLE_ASSERTS&&box2d.b2Assert(!1===this.IsLocked());if(!this.IsLocked()){var b=a.m_collideConnected;a.m_prev&&(a.m_prev.m_next=a.m_next);a.m_next&&(a.m_next.m_prev=a.m_prev);a===this.m_jointList&&(this.m_jointList=a.m_next);var c=a.m_bodyA,e=a.m_bodyB;c.SetAwake(!0);e.SetAwake(!0);a.m_edgeA.prev&&(a.m_edgeA.prev.next=a.m_edgeA.next);a.m_edgeA.next&&(a.m_edgeA.next.prev=a.m_edgeA.prev);a.m_edgeA===c.m_jointList&&(c.m_jointList=a.m_edgeA.next);\na.m_edgeA.prev=null;a.m_edgeA.next=null;a.m_edgeB.prev&&(a.m_edgeB.prev.next=a.m_edgeB.next);a.m_edgeB.next&&(a.m_edgeB.next.prev=a.m_edgeB.prev);a.m_edgeB===e.m_jointList&&(e.m_jointList=a.m_edgeB.next);a.m_edgeB.prev=null;a.m_edgeB.next=null;box2d.b2JointFactory.Destroy(a,null);box2d.ENABLE_ASSERTS&&box2d.b2Assert(0<this.m_jointCount);--this.m_jointCount;if(!1===b)for(a=e.GetContactList();a;)a.other===c&&a.contact.FlagForFiltering(),a=a.next}};\ngoog.exportProperty(box2d.b2World.prototype,\"DestroyJoint\",box2d.b2World.prototype.DestroyJoint);\nbox2d.b2World.prototype.Solve=function(a){for(var b=this.m_controllerList;b;b=b.m_next)b.Step(a);this.m_profile.solveInit=0;this.m_profile.solveVelocity=0;this.m_profile.solvePosition=0;b=this.m_island;b.Initialize(this.m_bodyCount,this.m_contactManager.m_contactCount,this.m_jointCount,null,this.m_contactManager.m_contactListener);for(var c=this.m_bodyList;c;c=c.m_next)c.m_flags&=~box2d.b2BodyFlag.e_islandFlag;for(var e=this.m_contactManager.m_contactList;e;e=e.m_next)e.m_flags&=~box2d.b2ContactFlag.e_islandFlag;\nfor(e=this.m_jointList;e;e=e.m_next)e.m_islandFlag=!1;for(var e=this.m_bodyCount,d=this.s_stack,f=this.m_bodyList;f;f=f.m_next)if(!(f.m_flags&box2d.b2BodyFlag.e_islandFlag)&&!1!==f.IsAwake()&&!1!==f.IsActive()&&f.GetType()!==box2d.b2BodyType.b2_staticBody){b.Clear();var g=0;d[g++]=f;for(f.m_flags|=box2d.b2BodyFlag.e_islandFlag;0<g;)if(c=d[--g],box2d.ENABLE_ASSERTS&&box2d.b2Assert(!0===c.IsActive()),b.AddBody(c),c.SetAwake(!0),c.GetType()!==box2d.b2BodyType.b2_staticBody){for(var h=c.m_contactList;h;h=\nh.next){var l=h.contact;if(!(l.m_flags&box2d.b2ContactFlag.e_islandFlag)&&!1!==l.IsEnabled()&&!1!==l.IsTouching()){var k=l.m_fixtureB.m_isSensor;l.m_fixtureA.m_isSensor||k||(b.AddContact(l),l.m_flags|=box2d.b2ContactFlag.e_islandFlag,l=h.other,l.m_flags&box2d.b2BodyFlag.e_islandFlag||(box2d.ENABLE_ASSERTS&&box2d.b2Assert(g<e),d[g++]=l,l.m_flags|=box2d.b2BodyFlag.e_islandFlag))}}for(c=c.m_jointList;c;c=c.next)!0!==c.joint.m_islandFlag&&(l=c.other,!1!==l.IsActive()&&(b.AddJoint(c.joint),c.joint.m_islandFlag=\n!0,l.m_flags&box2d.b2BodyFlag.e_islandFlag||(box2d.ENABLE_ASSERTS&&box2d.b2Assert(g<e),d[g++]=l,l.m_flags|=box2d.b2BodyFlag.e_islandFlag)))}c=new box2d.b2Profile;b.Solve(c,a,this.m_gravity,this.m_allowSleep);this.m_profile.solveInit+=c.solveInit;this.m_profile.solveVelocity+=c.solveVelocity;this.m_profile.solvePosition+=c.solvePosition;for(g=0;g<b.m_bodyCount;++g)c=b.m_bodies[g],c.GetType()===box2d.b2BodyType.b2_staticBody&&(c.m_flags&=~box2d.b2BodyFlag.e_islandFlag)}for(g=0;g<d.length&&d[g];++g)d[g]=\nnull;a=new box2d.b2Timer;for(c=this.m_bodyList;c;c=c.m_next)0!==(c.m_flags&box2d.b2BodyFlag.e_islandFlag)&&c.GetType()!==box2d.b2BodyType.b2_staticBody&&c.SynchronizeFixtures();this.m_contactManager.FindNewContacts();this.m_profile.broadphase=a.GetMilliseconds()};goog.exportProperty(box2d.b2World.prototype,\"Solve\",box2d.b2World.prototype.Solve);\nbox2d.b2World.prototype.SolveTOI=function(a){var b=this.m_island;b.Initialize(2*box2d.b2_maxTOIContacts,box2d.b2_maxTOIContacts,0,null,this.m_contactManager.m_contactListener);if(this.m_stepComplete){for(var c=this.m_bodyList;c;c=c.m_next)c.m_flags&=~box2d.b2BodyFlag.e_islandFlag,c.m_sweep.alpha0=0;for(var e=this.m_contactManager.m_contactList;e;e=e.m_next)e.m_flags&=~(box2d.b2ContactFlag.e_toiFlag|box2d.b2ContactFlag.e_islandFlag),e.m_toiCount=0,e.m_toi=1}for(;;){for(var d=null,c=1,e=this.m_contactManager.m_contactList;e;e=\ne.m_next)if(!1!==e.IsEnabled()&&!(e.m_toiCount>box2d.b2_maxSubSteps)){var f=1;if(e.m_flags&box2d.b2ContactFlag.e_toiFlag)f=e.m_toi;else{var g=e.GetFixtureA(),h=e.GetFixtureB();if(g.IsSensor()||h.IsSensor())continue;var f=g.GetBody(),l=h.GetBody(),k=f.m_type,m=l.m_type;box2d.ENABLE_ASSERTS&&box2d.b2Assert(k===box2d.b2BodyType.b2_dynamicBody||m===box2d.b2BodyType.b2_dynamicBody);var n=f.IsAwake()&&k!==box2d.b2BodyType.b2_staticBody,p=l.IsAwake()&&m!==box2d.b2BodyType.b2_staticBody;if(!1===n&&!1===p)continue;\nk=f.IsBullet()||k!==box2d.b2BodyType.b2_dynamicBody;m=l.IsBullet()||m!==box2d.b2BodyType.b2_dynamicBody;if(!1===k&&!1===m)continue;m=f.m_sweep.alpha0;f.m_sweep.alpha0<l.m_sweep.alpha0?(m=l.m_sweep.alpha0,f.m_sweep.Advance(m)):l.m_sweep.alpha0<f.m_sweep.alpha0&&(m=f.m_sweep.alpha0,l.m_sweep.Advance(m));box2d.ENABLE_ASSERTS&&box2d.b2Assert(1>m);n=e.GetChildIndexA();p=e.GetChildIndexB();k=box2d.b2World.prototype.SolveTOI.s_toi_input;k.proxyA.SetShape(g.GetShape(),n);k.proxyB.SetShape(h.GetShape(),p);\nk.sweepA.Copy(f.m_sweep);k.sweepB.Copy(l.m_sweep);k.tMax=1;f=box2d.b2World.prototype.SolveTOI.s_toi_output;box2d.b2TimeOfImpact(f,k);l=f.t;f=f.state===box2d.b2TOIOutputState.e_touching?box2d.b2Min(m+(1-m)*l,1):1;e.m_toi=f;e.m_flags|=box2d.b2ContactFlag.e_toiFlag}f<c&&(d=e,c=f)}if(null===d||1-10*box2d.b2_epsilon<c){this.m_stepComplete=!0;break}g=d.GetFixtureA();h=d.GetFixtureB();f=g.GetBody();l=h.GetBody();e=box2d.b2World.prototype.SolveTOI.s_backup1.Copy(f.m_sweep);g=box2d.b2World.prototype.SolveTOI.s_backup2.Copy(l.m_sweep);\nf.Advance(c);l.Advance(c);d.Update(this.m_contactManager.m_contactListener);d.m_flags&=~box2d.b2ContactFlag.e_toiFlag;++d.m_toiCount;if(!1===d.IsEnabled()||!1===d.IsTouching())d.SetEnabled(!1),f.m_sweep.Copy(e),l.m_sweep.Copy(g),f.SynchronizeTransform(),l.SynchronizeTransform();else{f.SetAwake(!0);l.SetAwake(!0);b.Clear();b.AddBody(f);b.AddBody(l);b.AddContact(d);f.m_flags|=box2d.b2BodyFlag.e_islandFlag;l.m_flags|=box2d.b2BodyFlag.e_islandFlag;d.m_flags|=box2d.b2ContactFlag.e_islandFlag;for(d=0;2>\nd;++d)if(e=0===d?f:l,e.m_type===box2d.b2BodyType.b2_dynamicBody)for(g=e.m_contactList;g&&b.m_bodyCount!==b.m_bodyCapacity&&b.m_contactCount!==b.m_contactCapacity;g=g.next)h=g.contact,h.m_flags&box2d.b2ContactFlag.e_islandFlag||(m=g.other,m.m_type===box2d.b2BodyType.b2_dynamicBody&&!1===e.IsBullet()&&!1===m.IsBullet())||(k=h.m_fixtureB.m_isSensor,h.m_fixtureA.m_isSensor||k||(k=box2d.b2World.prototype.SolveTOI.s_backup.Copy(m.m_sweep),0===(m.m_flags&box2d.b2BodyFlag.e_islandFlag)&&m.Advance(c),h.Update(this.m_contactManager.m_contactListener),\n!1===h.IsEnabled()?(m.m_sweep.Copy(k),m.SynchronizeTransform()):!1===h.IsTouching()?(m.m_sweep.Copy(k),m.SynchronizeTransform()):(h.m_flags|=box2d.b2ContactFlag.e_islandFlag,b.AddContact(h),m.m_flags&box2d.b2BodyFlag.e_islandFlag||(m.m_flags|=box2d.b2BodyFlag.e_islandFlag,m.m_type!==box2d.b2BodyType.b2_staticBody&&m.SetAwake(!0),b.AddBody(m)))));d=box2d.b2World.prototype.SolveTOI.s_subStep;d.dt=(1-c)*a.dt;d.inv_dt=1/d.dt;d.dtRatio=1;d.positionIterations=20;d.velocityIterations=a.velocityIterations;\nd.warmStarting=!1;b.SolveTOI(d,f.m_islandIndex,l.m_islandIndex);for(d=0;d<b.m_bodyCount;++d)if(e=b.m_bodies[d],e.m_flags&=~box2d.b2BodyFlag.e_islandFlag,e.m_type===box2d.b2BodyType.b2_dynamicBody)for(e.SynchronizeFixtures(),g=e.m_contactList;g;g=g.next)g.contact.m_flags&=~(box2d.b2ContactFlag.e_toiFlag|box2d.b2ContactFlag.e_islandFlag);this.m_contactManager.FindNewContacts();if(this.m_subStepping){this.m_stepComplete=!1;break}}}};goog.exportProperty(box2d.b2World.prototype,\"SolveTOI\",box2d.b2World.prototype.SolveTOI);\nbox2d.b2World.prototype.SolveTOI.s_subStep=new box2d.b2TimeStep;box2d.b2World.prototype.SolveTOI.s_backup=new box2d.b2Sweep;box2d.b2World.prototype.SolveTOI.s_backup1=new box2d.b2Sweep;box2d.b2World.prototype.SolveTOI.s_backup2=new box2d.b2Sweep;box2d.b2World.prototype.SolveTOI.s_toi_input=new box2d.b2TOIInput;box2d.b2World.prototype.SolveTOI.s_toi_output=new box2d.b2TOIOutput;\nbox2d.b2World.prototype.Step=function(a,b,c){var e=new box2d.b2Timer;this.m_flags&box2d.b2WorldFlag.e_newFixture&&(this.m_contactManager.FindNewContacts(),this.m_flags&=~box2d.b2WorldFlag.e_newFixture);this.m_flags|=box2d.b2WorldFlag.e_locked;var d=box2d.b2World.prototype.Step.s_step;d.dt=a;d.velocityIterations=b;d.positionIterations=c;d.inv_dt=0<a?1/a:0;d.dtRatio=this.m_inv_dt0*a;d.warmStarting=this.m_warmStarting;a=new box2d.b2Timer;this.m_contactManager.Collide();this.m_profile.collide=a.GetMilliseconds();\nthis.m_stepComplete&&0<d.dt&&(a=new box2d.b2Timer,this.Solve(d),this.m_profile.solve=a.GetMilliseconds());this.m_continuousPhysics&&0<d.dt&&(a=new box2d.b2Timer,this.SolveTOI(d),this.m_profile.solveTOI=a.GetMilliseconds());0<d.dt&&(this.m_inv_dt0=d.inv_dt);this.m_flags&box2d.b2WorldFlag.e_clearForces&&this.ClearForces();this.m_flags&=~box2d.b2WorldFlag.e_locked;this.m_profile.step=e.GetMilliseconds()};goog.exportProperty(box2d.b2World.prototype,\"Step\",box2d.b2World.prototype.Step);\nbox2d.b2World.prototype.Step.s_step=new box2d.b2TimeStep;box2d.b2World.prototype.ClearForces=function(){for(var a=this.m_bodyList;a;a=a.m_next)a.m_force.SetZero(),a.m_torque=0};goog.exportProperty(box2d.b2World.prototype,\"ClearForces\",box2d.b2World.prototype.ClearForces);\nbox2d.b2World.prototype.QueryAABB=function(a,b){var c=this.m_contactManager.m_broadPhase;c.Query(function(b){b=c.GetUserData(b);box2d.ENABLE_ASSERTS&&box2d.b2Assert(b instanceof box2d.b2FixtureProxy);b=b.fixture;return a instanceof box2d.b2QueryCallback?a.ReportFixture(b):a(b)},b)};goog.exportProperty(box2d.b2World.prototype,\"QueryAABB\",box2d.b2World.prototype.QueryAABB);\nbox2d.b2World.prototype.QueryShape=function(a,b,c){var e=this.m_contactManager.m_broadPhase,d=box2d.b2World.prototype.QueryShape.s_aabb;b.ComputeAABB(d,c,0);e.Query(function(d){d=e.GetUserData(d);box2d.ENABLE_ASSERTS&&box2d.b2Assert(d instanceof box2d.b2FixtureProxy);d=d.fixture;return box2d.b2TestOverlapShape(b,0,d.GetShape(),0,c,d.GetBody().GetTransform())?a instanceof box2d.b2QueryCallback?a.ReportFixture(d):a(d):!0},d)};goog.exportProperty(box2d.b2World.prototype,\"QueryShape\",box2d.b2World.prototype.QueryShape);\nbox2d.b2World.prototype.QueryShape.s_aabb=new box2d.b2AABB;\nbox2d.b2World.prototype.QueryPoint=function(a,b){var c=this.m_contactManager.m_broadPhase,e=box2d.b2World.prototype.QueryPoint.s_aabb;e.lowerBound.SetXY(b.x-box2d.b2_linearSlop,b.y-box2d.b2_linearSlop);e.upperBound.SetXY(b.x+box2d.b2_linearSlop,b.y+box2d.b2_linearSlop);c.Query(function(d){d=c.GetUserData(d);box2d.ENABLE_ASSERTS&&box2d.b2Assert(d instanceof box2d.b2FixtureProxy);d=d.fixture;return d.TestPoint(b)?a instanceof box2d.b2QueryCallback?a.ReportFixture(d):a(d):!0},e)};\ngoog.exportProperty(box2d.b2World.prototype,\"QueryPoint\",box2d.b2World.prototype.QueryPoint);box2d.b2World.prototype.QueryPoint.s_aabb=new box2d.b2AABB;\nbox2d.b2World.prototype.RayCast=function(a,b,c){var e=this.m_contactManager.m_broadPhase,d=box2d.b2World.prototype.RayCast.s_input;d.maxFraction=1;d.p1.Copy(b);d.p2.Copy(c);e.RayCast(function(d,g){var h=e.GetUserData(g);box2d.ENABLE_ASSERTS&&box2d.b2Assert(h instanceof box2d.b2FixtureProxy);var l=h.fixture,k=box2d.b2World.prototype.RayCast.s_output;if(l.RayCast(k,d,h.childIndex)){var h=k.fraction,m=box2d.b2World.prototype.RayCast.s_point;m.SetXY((1-h)*b.x+h*c.x,(1-h)*b.y+h*c.y);return a instanceof\nbox2d.b2RayCastCallback?a.ReportFixture(l,m,k.normal,h):a(l,m,k.normal,h)}return d.maxFraction},d)};goog.exportProperty(box2d.b2World.prototype,\"RayCast\",box2d.b2World.prototype.RayCast);box2d.b2World.prototype.RayCast.s_input=new box2d.b2RayCastInput;box2d.b2World.prototype.RayCast.s_output=new box2d.b2RayCastOutput;box2d.b2World.prototype.RayCast.s_point=new box2d.b2Vec2;\nbox2d.b2World.prototype.RayCastOne=function(a,b){var c=null,e=1;this.RayCast(function(a,b,g,h){h<e&&(e=h,c=a);return e},a,b);return c};goog.exportProperty(box2d.b2World.prototype,\"RayCastOne\",box2d.b2World.prototype.RayCastOne);box2d.b2World.prototype.RayCastAll=function(a,b,c){c.length=0;this.RayCast(function(a,b,f,g){c.push(a);return 1},a,b);return c};goog.exportProperty(box2d.b2World.prototype,\"RayCastAll\",box2d.b2World.prototype.RayCastAll);\nbox2d.b2World.prototype.DrawShape=function(a,b){var c=a.GetShape();switch(c.m_type){case box2d.b2ShapeType.e_circleShape:c=c instanceof box2d.b2CircleShape?c:null;this.m_debugDraw.DrawSolidCircle(c.m_p,c.m_radius,box2d.b2Vec2.UNITX,b);break;case box2d.b2ShapeType.e_edgeShape:var e=c instanceof box2d.b2EdgeShape?c:null,c=e.m_vertex1,d=e.m_vertex2;this.m_debugDraw.DrawSegment(c,d,b);break;case box2d.b2ShapeType.e_chainShape:var c=c instanceof box2d.b2ChainShape?c:null,e=c.m_count,f=c.m_vertices,c=f[0];\nthis.m_debugDraw.DrawCircle(c,0.05,b);for(var g=1;g<e;++g)d=f[g],this.m_debugDraw.DrawSegment(c,d,b),this.m_debugDraw.DrawCircle(d,0.05,b),c=d;break;case box2d.b2ShapeType.e_polygonShape:e=c instanceof box2d.b2PolygonShape?c:null,c=e.m_count,f=e.m_vertices,this.m_debugDraw.DrawSolidPolygon(f,c,b)}};goog.exportProperty(box2d.b2World.prototype,\"DrawShape\",box2d.b2World.prototype.DrawShape);\nbox2d.b2World.prototype.DrawJoint=function(a){var b=a.GetBodyA(),c=a.GetBodyB(),e=b.m_xf.p,d=c.m_xf.p,c=a.GetAnchorA(box2d.b2World.prototype.DrawJoint.s_p1),b=a.GetAnchorB(box2d.b2World.prototype.DrawJoint.s_p2),f=box2d.b2World.prototype.DrawJoint.s_color.SetRGB(0.5,0.8,0.8);switch(a.m_type){case box2d.b2JointType.e_distanceJoint:this.m_debugDraw.DrawSegment(c,b,f);break;case box2d.b2JointType.e_pulleyJoint:e=a instanceof box2d.b2PulleyJoint?a:null;a=e.GetGroundAnchorA(box2d.b2World.prototype.DrawJoint.s_s1);\ne=e.GetGroundAnchorB(box2d.b2World.prototype.DrawJoint.s_s2);this.m_debugDraw.DrawSegment(a,c,f);this.m_debugDraw.DrawSegment(e,b,f);this.m_debugDraw.DrawSegment(a,e,f);break;case box2d.b2JointType.e_mouseJoint:this.m_debugDraw.DrawSegment(c,b,f);break;default:this.m_debugDraw.DrawSegment(e,c,f),this.m_debugDraw.DrawSegment(c,b,f),this.m_debugDraw.DrawSegment(d,b,f)}};goog.exportProperty(box2d.b2World.prototype,\"DrawJoint\",box2d.b2World.prototype.DrawJoint);\nbox2d.b2World.prototype.DrawJoint.s_p1=new box2d.b2Vec2;box2d.b2World.prototype.DrawJoint.s_p2=new box2d.b2Vec2;box2d.b2World.prototype.DrawJoint.s_color=new box2d.b2Color(0.5,0.8,0.8);box2d.b2World.prototype.DrawJoint.s_s1=new box2d.b2Vec2;box2d.b2World.prototype.DrawJoint.s_s2=new box2d.b2Vec2;\nbox2d.b2World.prototype.DrawDebugData=function(){if(null!==this.m_debugDraw){var a=this.m_debugDraw.GetFlags(),b=box2d.b2World.prototype.DrawDebugData.s_color.SetRGB(0,0,0);if(a&box2d.b2DrawFlags.e_shapeBit)for(var c=this.m_bodyList;c;c=c.m_next){var e=c.m_xf;this.m_debugDraw.PushTransform(e);for(var d=c.GetFixtureList();d;d=d.m_next)!1===c.IsActive()?b.SetRGB(0.5,0.5,0.3):c.GetType()===box2d.b2BodyType.b2_staticBody?b.SetRGB(0.5,0.9,0.5):c.GetType()===box2d.b2BodyType.b2_kinematicBody?b.SetRGB(0.5,\n0.5,0.9):!1===c.IsAwake()?b.SetRGB(0.6,0.6,0.6):b.SetRGB(0.9,0.7,0.7),this.DrawShape(d,b);this.m_debugDraw.PopTransform(e)}if(a&box2d.b2DrawFlags.e_jointBit)for(c=this.m_jointList;c;c=c.m_next)this.DrawJoint(c);if(a&box2d.b2DrawFlags.e_aabbBit){b.SetRGB(0.9,0.3,0.9);for(var e=this.m_contactManager.m_broadPhase,f=box2d.b2World.prototype.DrawDebugData.s_vs,c=this.m_bodyList;c;c=c.m_next)if(!1!==c.IsActive())for(d=c.GetFixtureList();d;d=d.m_next)for(var g=0;g<d.m_proxyCount;++g){var h=e.GetFatAABB(d.m_proxies[g].proxy);\nf[0].SetXY(h.lowerBound.x,h.lowerBound.y);f[1].SetXY(h.upperBound.x,h.lowerBound.y);f[2].SetXY(h.upperBound.x,h.upperBound.y);f[3].SetXY(h.lowerBound.x,h.upperBound.y);this.m_debugDraw.DrawPolygon(f,4,b)}}if(a&box2d.b2DrawFlags.e_centerOfMassBit)for(c=this.m_bodyList;c;c=c.m_next)e=box2d.b2World.prototype.DrawDebugData.s_xf,e.q.Copy(c.m_xf.q),e.p.Copy(c.GetWorldCenter()),this.m_debugDraw.DrawTransform(e);if(a&box2d.b2DrawFlags.e_controllerBit)for(a=this.m_controllerList;a;a=a.m_next)a.Draw(this.m_debugDraw)}};\ngoog.exportProperty(box2d.b2World.prototype,\"DrawDebugData\",box2d.b2World.prototype.DrawDebugData);box2d.b2World.prototype.DrawDebugData.s_color=new box2d.b2Color(0,0,0);box2d.b2World.prototype.DrawDebugData.s_vs=box2d.b2Vec2.MakeArray(4);box2d.b2World.prototype.DrawDebugData.s_xf=new box2d.b2Transform;\nbox2d.b2World.prototype.SetBroadPhase=function(a){var b=this.m_contactManager.m_broadPhase;this.m_contactManager.m_broadPhase=a;for(var c=this.m_bodyList;c;c=c.m_next)for(var e=c.m_fixtureList;e;e=e.m_next)e.m_proxy=a.CreateProxy(b.GetFatAABB(e.m_proxy),e)};goog.exportProperty(box2d.b2World.prototype,\"SetBroadPhase\",box2d.b2World.prototype.SetBroadPhase);box2d.b2World.prototype.GetProxyCount=function(){return this.m_contactManager.m_broadPhase.GetProxyCount()};\ngoog.exportProperty(box2d.b2World.prototype,\"GetProxyCount\",box2d.b2World.prototype.GetProxyCount);box2d.b2World.prototype.GetTreeHeight=function(){return this.m_contactManager.m_broadPhase.GetTreeHeight()};goog.exportProperty(box2d.b2World.prototype,\"GetTreeHeight\",box2d.b2World.prototype.GetTreeHeight);box2d.b2World.prototype.GetTreeBalance=function(){return this.m_contactManager.m_broadPhase.GetTreeBalance()};goog.exportProperty(box2d.b2World.prototype,\"GetTreeBalance\",box2d.b2World.prototype.GetTreeBalance);\nbox2d.b2World.prototype.GetTreeQuality=function(){return this.m_contactManager.m_broadPhase.GetTreeQuality()};goog.exportProperty(box2d.b2World.prototype,\"GetTreeQuality\",box2d.b2World.prototype.GetTreeQuality);box2d.b2World.prototype.ShiftOrigin=function(a){box2d.ENABLE_ASSERTS&&box2d.b2Assert(!1===this.IsLocked());if(!this.IsLocked()){for(var b=this.m_bodyList;b;b=b.m_next)b.m_xf.p.SelfSub(a),b.m_sweep.c0.SelfSub(a),b.m_sweep.c.SelfSub(a);for(b=this.m_jointList;b;b=b.m_next)b.ShiftOrigin(a);this.m_contactManager.m_broadPhase.ShiftOrigin(a)}};\ngoog.exportProperty(box2d.b2World.prototype,\"ShiftOrigin\",box2d.b2World.prototype.ShiftOrigin);\nbox2d.b2World.prototype.Dump=function(){if(box2d.DEBUG&&(this.m_flags&box2d.b2WorldFlag.e_locked)!==box2d.b2WorldFlag.e_locked){box2d.b2Log(\"/** @type {box2d.b2Vec2} */ var g = new box2d.b2Vec2(%.15f, %.15f);\\n\",this.m_gravity.x,this.m_gravity.y);box2d.b2Log(\"this.m_world.SetGravity(g);\\n\");box2d.b2Log(\"/** @type {Array.<box2d.b2Body>} */ var bodies = new Array(%d);\\n\",this.m_bodyCount);box2d.b2Log(\"/** @type {Array.<box2d.b2Joint>} */ var joints = new Array(%d);\\n\",this.m_jointCount);for(var a=0,\nb=this.m_bodyList;b;b=b.m_next)b.m_islandIndex=a,b.Dump(),++a;a=0;for(b=this.m_jointList;b;b=b.m_next)b.m_index=a,++a;for(b=this.m_jointList;b;b=b.m_next)b.m_type!==box2d.b2JointType.e_gearJoint&&(box2d.b2Log(\"if (true)\\n\"),box2d.b2Log(\"{\\n\"),b.Dump(),box2d.b2Log(\"}\\n\"));for(b=this.m_jointList;b;b=b.m_next)b.m_type===box2d.b2JointType.e_gearJoint&&(box2d.b2Log(\"if (true)\\n\"),box2d.b2Log(\"{\\n\"),b.Dump(),box2d.b2Log(\"}\\n\"))}};goog.exportProperty(box2d.b2World.prototype,\"Dump\",box2d.b2World.prototype.Dump);\nbox2d.b2World.prototype.AddController=function(a){box2d.ENABLE_ASSERTS&&box2d.b2Assert(null===a.m_world,\"Controller can only be a member of one world\");a.m_world=this;a.m_next=this.m_controllerList;a.m_prev=null;this.m_controllerList&&(this.m_controllerList.m_prev=a);this.m_controllerList=a;++this.m_controllerCount;return a};goog.exportProperty(box2d.b2World.prototype,\"AddController\",box2d.b2World.prototype.AddController);\nbox2d.b2World.prototype.RemoveController=function(a){box2d.ENABLE_ASSERTS&&box2d.b2Assert(a.m_world===this,\"Controller is not a member of this world\");a.m_prev&&(a.m_prev.m_next=a.m_next);a.m_next&&(a.m_next.m_prev=a.m_prev);this.m_controllerList===a&&(this.m_controllerList=a.m_next);--this.m_controllerCount;a.m_prev=null;a.m_next=null;a.m_world=null};goog.exportProperty(box2d.b2World.prototype,\"RemoveController\",box2d.b2World.prototype.RemoveController);box2d.b2AreaJointDef=function(){box2d.b2JointDef.call(this,box2d.b2JointType.e_areaJoint);this.bodies=[]};goog.inherits(box2d.b2AreaJointDef,box2d.b2JointDef);goog.exportSymbol(\"box2d.b2AreaJointDef\",box2d.b2AreaJointDef);box2d.b2AreaJointDef.prototype.world=null;goog.exportProperty(box2d.b2AreaJointDef.prototype,\"world\",box2d.b2AreaJointDef.prototype.world);box2d.b2AreaJointDef.prototype.bodies=null;goog.exportProperty(box2d.b2AreaJointDef.prototype,\"bodies\",box2d.b2AreaJointDef.prototype.bodies);\nbox2d.b2AreaJointDef.prototype.frequencyHz=0;goog.exportProperty(box2d.b2AreaJointDef.prototype,\"frequencyHz\",box2d.b2AreaJointDef.prototype.frequencyHz);box2d.b2AreaJointDef.prototype.dampingRatio=0;goog.exportProperty(box2d.b2AreaJointDef.prototype,\"dampingRatio\",box2d.b2AreaJointDef.prototype.dampingRatio);box2d.b2AreaJointDef.prototype.AddBody=function(a){this.bodies.push(a);1===this.bodies.length?this.bodyA=a:2===this.bodies.length&&(this.bodyB=a)};\ngoog.exportProperty(box2d.b2AreaJointDef.prototype,\"AddBody\",box2d.b2AreaJointDef.prototype.AddBody);\nbox2d.b2AreaJoint=function(a){box2d.b2Joint.call(this,a);box2d.ENABLE_ASSERTS&&box2d.b2Assert(3<=a.bodies.length,\"You cannot create an area joint with less than three bodies.\");this.m_bodies=a.bodies;this.m_frequencyHz=a.frequencyHz;this.m_dampingRatio=a.dampingRatio;this.m_targetLengths=box2d.b2MakeNumberArray(a.bodies.length);this.m_normals=box2d.b2Vec2.MakeArray(a.bodies.length);this.m_joints=Array(a.bodies.length);this.m_deltas=box2d.b2Vec2.MakeArray(a.bodies.length);this.m_delta=new box2d.b2Vec2;\nvar b=new box2d.b2DistanceJointDef;b.frequencyHz=a.frequencyHz;b.dampingRatio=a.dampingRatio;for(var c=this.m_targetArea=0,e=this.m_bodies.length;c<e;++c){var d=this.m_bodies[c],f=this.m_bodies[(c+1)%e],g=d.GetWorldCenter(),h=f.GetWorldCenter();this.m_targetLengths[c]=box2d.b2DistanceVV(g,h);this.m_targetArea+=box2d.b2CrossVV(g,h);b.Initialize(d,f,g,h);this.m_joints[c]=a.world.CreateJoint(b)}this.m_targetArea*=0.5};goog.inherits(box2d.b2AreaJoint,box2d.b2Joint);\ngoog.exportSymbol(\"box2d.b2AreaJoint\",box2d.b2AreaJoint);box2d.b2AreaJoint.prototype.m_bodies=null;goog.exportProperty(box2d.b2AreaJoint.prototype,\"m_bodies\",box2d.b2AreaJoint.prototype.m_bodies);box2d.b2AreaJoint.prototype.m_frequencyHz=0;goog.exportProperty(box2d.b2AreaJoint.prototype,\"m_frequencyHz\",box2d.b2AreaJoint.prototype.m_frequencyHz);box2d.b2AreaJoint.prototype.m_dampingRatio=0;goog.exportProperty(box2d.b2AreaJoint.prototype,\"m_dampingRatio\",box2d.b2AreaJoint.prototype.m_dampingRatio);\nbox2d.b2AreaJoint.prototype.m_impulse=0;goog.exportProperty(box2d.b2AreaJoint.prototype,\"m_impulse\",box2d.b2AreaJoint.prototype.m_impulse);box2d.b2AreaJoint.prototype.m_targetLengths=null;box2d.b2AreaJoint.prototype.m_targetArea=0;box2d.b2AreaJoint.prototype.m_normals=null;box2d.b2AreaJoint.prototype.m_joints=null;box2d.b2AreaJoint.prototype.m_deltas=null;box2d.b2AreaJoint.prototype.m_delta=null;box2d.b2AreaJoint.prototype.GetAnchorA=function(a){return a.SetZero()};\ngoog.exportProperty(box2d.b2AreaJoint.prototype,\"GetAnchorA\",box2d.b2AreaJoint.prototype.GetAnchorA);box2d.b2AreaJoint.prototype.GetAnchorB=function(a){return a.SetZero()};goog.exportProperty(box2d.b2AreaJoint.prototype,\"GetAnchorB\",box2d.b2AreaJoint.prototype.GetAnchorB);box2d.b2AreaJoint.prototype.GetReactionForce=function(a,b){return b.SetZero()};goog.exportProperty(box2d.b2AreaJoint.prototype,\"GetReactionForce\",box2d.b2AreaJoint.prototype.GetReactionForce);\nbox2d.b2AreaJoint.prototype.GetReactionTorque=function(a){return 0};goog.exportProperty(box2d.b2AreaJoint.prototype,\"GetReactionTorque\",box2d.b2AreaJoint.prototype.GetReactionTorque);box2d.b2AreaJoint.prototype.SetFrequency=function(a){this.m_frequencyHz=a;for(var b=0,c=this.m_joints.length;b<c;++b)this.m_joints[b].SetFrequency(a)};goog.exportProperty(box2d.b2AreaJoint.prototype,\"SetFrequency\",box2d.b2AreaJoint.prototype.SetFrequency);box2d.b2AreaJoint.prototype.GetFrequency=function(){return this.m_frequencyHz};\ngoog.exportProperty(box2d.b2AreaJoint.prototype,\"GetFrequency\",box2d.b2AreaJoint.prototype.GetFrequency);box2d.b2AreaJoint.prototype.SetDampingRatio=function(a){this.m_dampingRatio=a;for(var b=0,c=this.m_joints.length;b<c;++b)this.m_joints[b].SetDampingRatio(a)};goog.exportProperty(box2d.b2AreaJoint.prototype,\"SetDampingRatio\",box2d.b2AreaJoint.prototype.SetDampingRatio);box2d.b2AreaJoint.prototype.GetDampingRatio=function(){return this.m_dampingRatio};\ngoog.exportProperty(box2d.b2AreaJoint.prototype,\"GetDampingRatio\",box2d.b2AreaJoint.prototype.GetDampingRatio);box2d.b2AreaJoint.prototype.Dump=function(){box2d.DEBUG&&box2d.b2Log(\"Area joint dumping is not supported.\\n\")};goog.exportProperty(box2d.b2AreaJoint.prototype,\"Dump\",box2d.b2AreaJoint.prototype.Dump);\nbox2d.b2AreaJoint.prototype.InitVelocityConstraints=function(a){for(var b=0,c=this.m_bodies.length;b<c;++b){var e=this.m_deltas[b];box2d.b2SubVV(a.positions[this.m_bodies[(b+1)%c].m_islandIndex].c,a.positions[this.m_bodies[(b+c-1)%c].m_islandIndex].c,e)}if(a.step.warmStarting)for(this.m_impulse*=a.step.dtRatio,b=0,c=this.m_bodies.length;b<c;++b){var d=this.m_bodies[b],f=a.velocities[d.m_islandIndex].v,e=this.m_deltas[b];f.x+=d.m_invMass*e.y*0.5*this.m_impulse;f.y+=d.m_invMass*-e.x*0.5*this.m_impulse}else this.m_impulse=\n0};goog.exportProperty(box2d.b2AreaJoint.prototype,\"InitVelocityConstraints\",box2d.b2AreaJoint.prototype.InitVelocityConstraints);\nbox2d.b2AreaJoint.prototype.SolveVelocityConstraints=function(a){for(var b=0,c=0,e=0,d=this.m_bodies.length;e<d;++e)var f=this.m_bodies[e],g=a.velocities[f.m_islandIndex].v,h=this.m_deltas[e],b=b+h.GetLengthSquared()/f.GetMass(),c=c+box2d.b2CrossVV(g,h);b=-2*c/b;this.m_impulse+=b;e=0;for(d=this.m_bodies.length;e<d;++e)f=this.m_bodies[e],g=a.velocities[f.m_islandIndex].v,h=this.m_deltas[e],g.x+=f.m_invMass*h.y*0.5*b,g.y+=f.m_invMass*-h.x*0.5*b};\ngoog.exportProperty(box2d.b2AreaJoint.prototype,\"SolveVelocityConstraints\",box2d.b2AreaJoint.prototype.SolveVelocityConstraints);\nbox2d.b2AreaJoint.prototype.SolvePositionConstraints=function(a){for(var b=0,c=0,e=0,d=this.m_bodies.length;e<d;++e){var f=this.m_bodies[e],f=a.positions[f.m_islandIndex].c,g=a.positions[this.m_bodies[(e+1)%d].m_islandIndex].c,h=box2d.b2SubVV(g,f,this.m_delta),l=h.GetLength();l<box2d.b2_epsilon&&(l=1);this.m_normals[e].x=h.y/l;this.m_normals[e].y=-h.x/l;b+=l;c+=box2d.b2CrossVV(f,g)}b=0.5*(this.m_targetArea-0.5*c)/b;c=!0;e=0;for(d=this.m_bodies.length;e<d;++e)f=this.m_bodies[e],f=a.positions[f.m_islandIndex].c,\nh=box2d.b2AddVV(this.m_normals[e],this.m_normals[(e+1)%d],this.m_delta),h.SelfMul(b),g=h.GetLengthSquared(),g>box2d.b2Sq(box2d.b2_maxLinearCorrection)&&h.SelfMul(box2d.b2_maxLinearCorrection/box2d.b2Sqrt(g)),g>box2d.b2Sq(box2d.b2_linearSlop)&&(c=!1),f.x+=h.x,f.y+=h.y;return c};goog.exportProperty(box2d.b2AreaJoint.prototype,\"SolvePositionConstraints\",box2d.b2AreaJoint.prototype.SolvePositionConstraints);box2d.b2BuoyancyController=function(){box2d.b2Controller.call(this);this.normal=new box2d.b2Vec2(0,1);this.velocity=new box2d.b2Vec2(0,0);this.gravity=new box2d.b2Vec2(0,0)};goog.inherits(box2d.b2BuoyancyController,box2d.b2Controller);goog.exportSymbol(\"box2d.b2BuoyancyController\",box2d.b2BuoyancyController);box2d.b2BuoyancyController.prototype.normal=null;goog.exportProperty(box2d.b2BuoyancyController.prototype,\"normal\",box2d.b2BuoyancyController.prototype.normal);\nbox2d.b2BuoyancyController.prototype.offset=0;goog.exportProperty(box2d.b2BuoyancyController.prototype,\"offset\",box2d.b2BuoyancyController.prototype.offset);box2d.b2BuoyancyController.prototype.density=0;goog.exportProperty(box2d.b2BuoyancyController.prototype,\"density\",box2d.b2BuoyancyController.prototype.density);box2d.b2BuoyancyController.prototype.velocity=null;goog.exportProperty(box2d.b2BuoyancyController.prototype,\"velocity\",box2d.b2BuoyancyController.prototype.velocity);\nbox2d.b2BuoyancyController.prototype.linearDrag=0;goog.exportProperty(box2d.b2BuoyancyController.prototype,\"linearDrag\",box2d.b2BuoyancyController.prototype.linearDrag);box2d.b2BuoyancyController.prototype.angularDrag=0;goog.exportProperty(box2d.b2BuoyancyController.prototype,\"angularDrag\",box2d.b2BuoyancyController.prototype.angularDrag);box2d.b2BuoyancyController.prototype.useDensity=!1;goog.exportProperty(box2d.b2BuoyancyController.prototype,\"useDensity\",box2d.b2BuoyancyController.prototype.useDensity);\nbox2d.b2BuoyancyController.prototype.useWorldGravity=!0;goog.exportProperty(box2d.b2BuoyancyController.prototype,\"useWorldGravity\",box2d.b2BuoyancyController.prototype.useWorldGravity);box2d.b2BuoyancyController.prototype.gravity=null;goog.exportProperty(box2d.b2BuoyancyController.prototype,\"gravity\",box2d.b2BuoyancyController.prototype.gravity);\nbox2d.b2BuoyancyController.prototype.Step=function(a){if(this.m_bodyList)for(this.useWorldGravity&&this.gravity.Copy(this.GetWorld().GetGravity()),a=this.m_bodyList;a;a=a.nextBody){var b=a.body;if(!1!==b.IsAwake()){for(var c=new box2d.b2Vec2,e=new box2d.b2Vec2,d=0,f=0,g=b.GetFixtureList();g;g=g.m_next){var h=new box2d.b2Vec2,l=g.GetShape().ComputeSubmergedArea(this.normal,this.offset,b.GetTransform(),h),d=d+l;c.x+=l*h.x;c.y+=l*h.y;var k=0,k=this.useDensity?g.GetDensity():1,f=f+l*k;e.x+=l*h.x*k;e.y+=\nl*h.y*k}c.x/=d;c.y/=d;e.x/=f;e.y/=f;d<box2d.b2_epsilon||(f=box2d.b2NegV(this.gravity,new box2d.b2Vec2),f.SelfMul(this.density*d),b.ApplyForce(f,e),e=b.GetLinearVelocityFromWorldPoint(c,new box2d.b2Vec2),e.SelfSub(this.velocity),e.SelfMul(-this.linearDrag*d),b.ApplyForce(e,c),b.ApplyTorque(-b.GetInertia()/b.GetMass()*d*b.GetAngularVelocity()*this.angularDrag))}}};goog.exportProperty(box2d.b2BuoyancyController.prototype,\"Step\",box2d.b2BuoyancyController.prototype.Step);\nbox2d.b2BuoyancyController.prototype.Draw=function(a){var b=new box2d.b2Vec2,c=new box2d.b2Vec2;b.x=this.normal.x*this.offset+100*this.normal.y;b.y=this.normal.y*this.offset-100*this.normal.x;c.x=this.normal.x*this.offset-100*this.normal.y;c.y=this.normal.y*this.offset+100*this.normal.x;var e=new box2d.b2Color(0,0,0.8);a.DrawSegment(b,c,e)};goog.exportProperty(box2d.b2BuoyancyController.prototype,\"Draw\",box2d.b2BuoyancyController.prototype.Draw);box2d.b2TensorDampingController=function(){box2d.b2Controller.call(this);this.T=new box2d.b2Mat22;this.maxTimestep=0};goog.inherits(box2d.b2TensorDampingController,box2d.b2Controller);goog.exportSymbol(\"box2d.b2TensorDampingController\",box2d.b2TensorDampingController);box2d.b2TensorDampingController.prototype.T=new box2d.b2Mat22;goog.exportProperty(box2d.b2TensorDampingController.prototype,\"T\",box2d.b2TensorDampingController.prototype.T);box2d.b2TensorDampingController.prototype.maxTimestep=0;\ngoog.exportProperty(box2d.b2TensorDampingController.prototype,\"maxTimestep\",box2d.b2TensorDampingController.prototype.maxTimestep);\nbox2d.b2TensorDampingController.prototype.Step=function(a){a=a.dt;if(!(a<=box2d.b2_epsilon)){a>this.maxTimestep&&0<this.maxTimestep&&(a=this.maxTimestep);for(var b=this.m_bodyList;b;b=b.nextBody){var c=b.body;if(c.IsAwake()){var e=c.GetWorldVector(box2d.b2MulMV(this.T,c.GetLocalVector(c.GetLinearVelocity(),box2d.b2Vec2.s_t0),box2d.b2Vec2.s_t1),box2d.b2TensorDampingController.prototype.Step.s_damping);c.SetLinearVelocity(box2d.b2AddVV(c.GetLinearVelocity(),box2d.b2MulSV(a,e,box2d.b2Vec2.s_t0),box2d.b2Vec2.s_t1))}}}};\nbox2d.b2TensorDampingController.prototype.Step.s_damping=new box2d.b2Vec2;box2d.b2TensorDampingController.prototype.SetAxisAligned=function(a,b){this.T.ex.x=-a;this.T.ex.y=0;this.T.ey.x=0;this.T.ey.y=-b;this.maxTimestep=0<a||0<b?1/box2d.b2Max(a,b):0};box2d.b2DistanceJointDef=function(){box2d.b2JointDef.call(this,box2d.b2JointType.e_distanceJoint);this.localAnchorA=new box2d.b2Vec2;this.localAnchorB=new box2d.b2Vec2};goog.inherits(box2d.b2DistanceJointDef,box2d.b2JointDef);goog.exportSymbol(\"box2d.b2DistanceJointDef\",box2d.b2DistanceJointDef);box2d.b2DistanceJointDef.prototype.localAnchorA=null;goog.exportProperty(box2d.b2DistanceJointDef.prototype,\"localAnchorA\",box2d.b2DistanceJointDef.prototype.localAnchorA);\nbox2d.b2DistanceJointDef.prototype.localAnchorB=null;goog.exportProperty(box2d.b2DistanceJointDef.prototype,\"localAnchorB\",box2d.b2DistanceJointDef.prototype.localAnchorB);box2d.b2DistanceJointDef.prototype.length=1;goog.exportProperty(box2d.b2DistanceJointDef.prototype,\"length\",box2d.b2DistanceJointDef.prototype.length);box2d.b2DistanceJointDef.prototype.frequencyHz=0;goog.exportProperty(box2d.b2DistanceJointDef.prototype,\"frequencyHz\",box2d.b2DistanceJointDef.prototype.frequencyHz);\nbox2d.b2DistanceJointDef.prototype.dampingRatio=0;goog.exportProperty(box2d.b2DistanceJointDef.prototype,\"dampingRatio\",box2d.b2DistanceJointDef.prototype.dampingRatio);box2d.b2DistanceJointDef.prototype.Initialize=function(a,b,c,e){this.bodyA=a;this.bodyB=b;this.bodyA.GetLocalPoint(c,this.localAnchorA);this.bodyB.GetLocalPoint(e,this.localAnchorB);this.length=box2d.b2DistanceVV(c,e);this.dampingRatio=this.frequencyHz=0};goog.exportProperty(box2d.b2DistanceJointDef.prototype,\"Initialize\",box2d.b2DistanceJointDef.prototype.Initialize);\nbox2d.b2DistanceJoint=function(a){box2d.b2Joint.call(this,a);this.m_u=new box2d.b2Vec2;this.m_rA=new box2d.b2Vec2;this.m_rB=new box2d.b2Vec2;this.m_localCenterA=new box2d.b2Vec2;this.m_localCenterB=new box2d.b2Vec2;this.m_qA=new box2d.b2Rot;this.m_qB=new box2d.b2Rot;this.m_lalcA=new box2d.b2Vec2;this.m_lalcB=new box2d.b2Vec2;this.m_frequencyHz=a.frequencyHz;this.m_dampingRatio=a.dampingRatio;this.m_localAnchorA=a.localAnchorA.Clone();this.m_localAnchorB=a.localAnchorB.Clone();this.m_length=a.length};\ngoog.inherits(box2d.b2DistanceJoint,box2d.b2Joint);goog.exportSymbol(\"box2d.b2DistanceJoint\",box2d.b2DistanceJoint);box2d.b2DistanceJoint.prototype.m_frequencyHz=0;goog.exportProperty(box2d.b2DistanceJoint.prototype,\"m_frequencyHz\",box2d.b2DistanceJoint.prototype.m_frequencyHz);box2d.b2DistanceJoint.prototype.m_dampingRatio=0;goog.exportProperty(box2d.b2DistanceJoint.prototype,\"m_dampingRatio\",box2d.b2DistanceJoint.prototype.m_dampingRatio);box2d.b2DistanceJoint.prototype.m_bias=0;\ngoog.exportProperty(box2d.b2DistanceJoint.prototype,\"m_bias\",box2d.b2DistanceJoint.prototype.m_bias);box2d.b2DistanceJoint.prototype.m_localAnchorA=null;goog.exportProperty(box2d.b2DistanceJoint.prototype,\"m_localAnchorA\",box2d.b2DistanceJoint.prototype.m_localAnchorA);box2d.b2DistanceJoint.prototype.m_localAnchorB=null;goog.exportProperty(box2d.b2DistanceJoint.prototype,\"m_localAnchorB\",box2d.b2DistanceJoint.prototype.m_localAnchorB);box2d.b2DistanceJoint.prototype.m_gamma=0;\ngoog.exportProperty(box2d.b2DistanceJoint.prototype,\"m_gamma\",box2d.b2DistanceJoint.prototype.m_gamma);box2d.b2DistanceJoint.prototype.m_impulse=0;goog.exportProperty(box2d.b2DistanceJoint.prototype,\"m_impulse\",box2d.b2DistanceJoint.prototype.m_impulse);box2d.b2DistanceJoint.prototype.m_length=0;goog.exportProperty(box2d.b2DistanceJoint.prototype,\"m_length\",box2d.b2DistanceJoint.prototype.m_length);box2d.b2DistanceJoint.prototype.m_indexA=0;\ngoog.exportProperty(box2d.b2DistanceJoint.prototype,\"m_indexA\",box2d.b2DistanceJoint.prototype.m_indexA);box2d.b2DistanceJoint.prototype.m_indexB=0;goog.exportProperty(box2d.b2DistanceJoint.prototype,\"m_indexB\",box2d.b2DistanceJoint.prototype.m_indexB);box2d.b2DistanceJoint.prototype.m_u=null;goog.exportProperty(box2d.b2DistanceJoint.prototype,\"m_u\",box2d.b2DistanceJoint.prototype.m_u);box2d.b2DistanceJoint.prototype.m_rA=null;goog.exportProperty(box2d.b2DistanceJoint.prototype,\"m_rA\",box2d.b2DistanceJoint.prototype.m_rA);\nbox2d.b2DistanceJoint.prototype.m_rB=null;goog.exportProperty(box2d.b2DistanceJoint.prototype,\"m_rB\",box2d.b2DistanceJoint.prototype.m_rB);box2d.b2DistanceJoint.prototype.m_localCenterA=null;goog.exportProperty(box2d.b2DistanceJoint.prototype,\"m_localCenterA\",box2d.b2DistanceJoint.prototype.m_localCenterA);box2d.b2DistanceJoint.prototype.m_localCenterB=null;goog.exportProperty(box2d.b2DistanceJoint.prototype,\"m_localCenterB\",box2d.b2DistanceJoint.prototype.m_localCenterB);\nbox2d.b2DistanceJoint.prototype.m_invMassA=0;goog.exportProperty(box2d.b2DistanceJoint.prototype,\"m_invMassA\",box2d.b2DistanceJoint.prototype.m_invMassA);box2d.b2DistanceJoint.prototype.m_invMassB=0;goog.exportProperty(box2d.b2DistanceJoint.prototype,\"m_invMassB\",box2d.b2DistanceJoint.prototype.m_invMassB);box2d.b2DistanceJoint.prototype.m_invIA=0;goog.exportProperty(box2d.b2DistanceJoint.prototype,\"m_invIA\",box2d.b2DistanceJoint.prototype.m_invIA);box2d.b2DistanceJoint.prototype.m_invIB=0;\ngoog.exportProperty(box2d.b2DistanceJoint.prototype,\"m_invIB\",box2d.b2DistanceJoint.prototype.m_invIB);box2d.b2DistanceJoint.prototype.m_mass=0;goog.exportProperty(box2d.b2DistanceJoint.prototype,\"m_mass\",box2d.b2DistanceJoint.prototype.m_mass);box2d.b2DistanceJoint.prototype.m_qA=null;goog.exportProperty(box2d.b2DistanceJoint.prototype,\"m_qA\",box2d.b2DistanceJoint.prototype.m_qA);box2d.b2DistanceJoint.prototype.m_qB=null;goog.exportProperty(box2d.b2DistanceJoint.prototype,\"m_qB\",box2d.b2DistanceJoint.prototype.m_qB);\nbox2d.b2DistanceJoint.prototype.m_lalcA=null;goog.exportProperty(box2d.b2DistanceJoint.prototype,\"m_lalcA\",box2d.b2DistanceJoint.prototype.m_lalcA);box2d.b2DistanceJoint.prototype.m_lalcB=null;goog.exportProperty(box2d.b2DistanceJoint.prototype,\"m_lalcB\",box2d.b2DistanceJoint.prototype.m_lalcB);box2d.b2DistanceJoint.prototype.GetAnchorA=function(a){return this.m_bodyA.GetWorldPoint(this.m_localAnchorA,a)};goog.exportProperty(box2d.b2DistanceJoint.prototype,\"GetAnchorA\",box2d.b2DistanceJoint.prototype.GetAnchorA);\nbox2d.b2DistanceJoint.prototype.GetAnchorB=function(a){return this.m_bodyB.GetWorldPoint(this.m_localAnchorB,a)};goog.exportProperty(box2d.b2DistanceJoint.prototype,\"GetAnchorB\",box2d.b2DistanceJoint.prototype.GetAnchorB);box2d.b2DistanceJoint.prototype.GetReactionForce=function(a,b){return b.SetXY(a*this.m_impulse*this.m_u.x,a*this.m_impulse*this.m_u.y)};goog.exportProperty(box2d.b2DistanceJoint.prototype,\"GetReactionForce\",box2d.b2DistanceJoint.prototype.GetReactionForce);\nbox2d.b2DistanceJoint.prototype.GetReactionTorque=function(a){return 0};goog.exportProperty(box2d.b2DistanceJoint.prototype,\"GetReactionTorque\",box2d.b2DistanceJoint.prototype.GetReactionTorque);box2d.b2DistanceJoint.prototype.GetLocalAnchorA=function(a){return a.Copy(this.m_localAnchorA)};goog.exportProperty(box2d.b2DistanceJoint.prototype,\"GetLocalAnchorA\",box2d.b2DistanceJoint.prototype.GetLocalAnchorA);box2d.b2DistanceJoint.prototype.GetLocalAnchorB=function(a){return a.Copy(this.m_localAnchorB)};\ngoog.exportProperty(box2d.b2DistanceJoint.prototype,\"GetLocalAnchorB\",box2d.b2DistanceJoint.prototype.GetLocalAnchorB);box2d.b2DistanceJoint.prototype.SetLength=function(a){this.m_length=a};goog.exportProperty(box2d.b2DistanceJoint.prototype,\"SetLength\",box2d.b2DistanceJoint.prototype.SetLength);box2d.b2DistanceJoint.prototype.GetLength=function(){return this.m_length};goog.exportProperty(box2d.b2DistanceJoint.prototype,\"GetLength\",box2d.b2DistanceJoint.prototype.GetLength);\nbox2d.b2DistanceJoint.prototype.SetFrequency=function(a){this.m_frequencyHz=a};goog.exportProperty(box2d.b2DistanceJoint.prototype,\"SetFrequency\",box2d.b2DistanceJoint.prototype.SetFrequency);box2d.b2DistanceJoint.prototype.GetFrequency=function(){return this.m_frequencyHz};goog.exportProperty(box2d.b2DistanceJoint.prototype,\"GetFrequency\",box2d.b2DistanceJoint.prototype.GetFrequency);box2d.b2DistanceJoint.prototype.SetDampingRatio=function(a){this.m_dampingRatio=a};\ngoog.exportProperty(box2d.b2DistanceJoint.prototype,\"SetDampingRatio\",box2d.b2DistanceJoint.prototype.SetDampingRatio);box2d.b2DistanceJoint.prototype.GetDampingRatio=function(){return this.m_dampingRatio};goog.exportProperty(box2d.b2DistanceJoint.prototype,\"GetDampingRatio\",box2d.b2DistanceJoint.prototype.GetDampingRatio);\nbox2d.b2DistanceJoint.prototype.Dump=function(){if(box2d.DEBUG){var a=this.m_bodyA.m_islandIndex,b=this.m_bodyB.m_islandIndex;box2d.b2Log(\"  /*box2d.b2DistanceJointDef*/ var jd = new box2d.b2DistanceJointDef();\\n\");box2d.b2Log(\"  jd.bodyA = bodies[%d];\\n\",a);box2d.b2Log(\"  jd.bodyB = bodies[%d];\\n\",b);box2d.b2Log(\"  jd.collideConnected = %s;\\n\",this.m_collideConnected?\"true\":\"false\");box2d.b2Log(\"  jd.localAnchorA.SetXY(%.15f, %.15f);\\n\",this.m_localAnchorA.x,this.m_localAnchorA.y);box2d.b2Log(\"  jd.localAnchorB.SetXY(%.15f, %.15f);\\n\",\nthis.m_localAnchorB.x,this.m_localAnchorB.y);box2d.b2Log(\"  jd.length = %.15f;\\n\",this.m_length);box2d.b2Log(\"  jd.frequencyHz = %.15f;\\n\",this.m_frequencyHz);box2d.b2Log(\"  jd.dampingRatio = %.15f;\\n\",this.m_dampingRatio);box2d.b2Log(\"  joints[%d] = this.m_world.CreateJoint(jd);\\n\",this.m_index)}};goog.exportProperty(box2d.b2DistanceJoint.prototype,\"Dump\",box2d.b2DistanceJoint.prototype.Dump);\nbox2d.b2DistanceJoint.prototype.InitVelocityConstraints=function(a){this.m_indexA=this.m_bodyA.m_islandIndex;this.m_indexB=this.m_bodyB.m_islandIndex;this.m_localCenterA.Copy(this.m_bodyA.m_sweep.localCenter);this.m_localCenterB.Copy(this.m_bodyB.m_sweep.localCenter);this.m_invMassA=this.m_bodyA.m_invMass;this.m_invMassB=this.m_bodyB.m_invMass;this.m_invIA=this.m_bodyA.m_invI;this.m_invIB=this.m_bodyB.m_invI;var b=a.positions[this.m_indexA].c,c=a.velocities[this.m_indexA].v,e=a.velocities[this.m_indexA].w,\nd=a.positions[this.m_indexB].c,f=a.positions[this.m_indexB].a,g=a.velocities[this.m_indexB].v,h=a.velocities[this.m_indexB].w,l=this.m_qA.SetAngleRadians(a.positions[this.m_indexA].a),f=this.m_qB.SetAngleRadians(f);box2d.b2SubVV(this.m_localAnchorA,this.m_localCenterA,this.m_lalcA);box2d.b2MulRV(l,this.m_lalcA,this.m_rA);box2d.b2SubVV(this.m_localAnchorB,this.m_localCenterB,this.m_lalcB);box2d.b2MulRV(f,this.m_lalcB,this.m_rB);this.m_u.x=d.x+this.m_rB.x-b.x-this.m_rA.x;this.m_u.y=d.y+this.m_rB.y-\nb.y-this.m_rA.y;d=this.m_u.GetLength();d>box2d.b2_linearSlop?this.m_u.SelfMul(1/d):this.m_u.SetZero();b=box2d.b2CrossVV(this.m_rA,this.m_u);l=box2d.b2CrossVV(this.m_rB,this.m_u);b=this.m_invMassA+this.m_invIA*b*b+this.m_invMassB+this.m_invIB*l*l;this.m_mass=0!==b?1/b:0;if(0<this.m_frequencyHz){var d=d-this.m_length,l=2*box2d.b2_pi*this.m_frequencyHz,f=this.m_mass*l*l,k=a.step.dt;this.m_gamma=k*(2*this.m_mass*this.m_dampingRatio*l+k*f);this.m_gamma=0!==this.m_gamma?1/this.m_gamma:0;this.m_bias=d*k*\nf*this.m_gamma;b+=this.m_gamma;this.m_mass=0!==b?1/b:0}else this.m_bias=this.m_gamma=0;a.step.warmStarting?(this.m_impulse*=a.step.dtRatio,b=box2d.b2MulSV(this.m_impulse,this.m_u,box2d.b2DistanceJoint.prototype.InitVelocityConstraints.s_P),c.SelfMulSub(this.m_invMassA,b),e-=this.m_invIA*box2d.b2CrossVV(this.m_rA,b),g.SelfMulAdd(this.m_invMassB,b),h+=this.m_invIB*box2d.b2CrossVV(this.m_rB,b)):this.m_impulse=0;a.velocities[this.m_indexA].w=e;a.velocities[this.m_indexB].w=h};\ngoog.exportProperty(box2d.b2DistanceJoint.prototype,\"InitVelocityConstraints\",box2d.b2DistanceJoint.prototype.InitVelocityConstraints);box2d.b2DistanceJoint.prototype.InitVelocityConstraints.s_P=new box2d.b2Vec2;\nbox2d.b2DistanceJoint.prototype.SolveVelocityConstraints=function(a){var b=a.velocities[this.m_indexA].v,c=a.velocities[this.m_indexA].w,e=a.velocities[this.m_indexB].v,d=a.velocities[this.m_indexB].w,f=box2d.b2AddVCrossSV(b,c,this.m_rA,box2d.b2DistanceJoint.prototype.SolveVelocityConstraints.s_vpA),g=box2d.b2AddVCrossSV(e,d,this.m_rB,box2d.b2DistanceJoint.prototype.SolveVelocityConstraints.s_vpB),f=box2d.b2DotVV(this.m_u,box2d.b2SubVV(g,f,box2d.b2Vec2.s_t0)),f=-this.m_mass*(f+this.m_bias+this.m_gamma*\nthis.m_impulse);this.m_impulse+=f;f=box2d.b2MulSV(f,this.m_u,box2d.b2DistanceJoint.prototype.SolveVelocityConstraints.s_P);b.SelfMulSub(this.m_invMassA,f);c-=this.m_invIA*box2d.b2CrossVV(this.m_rA,f);e.SelfMulAdd(this.m_invMassB,f);d+=this.m_invIB*box2d.b2CrossVV(this.m_rB,f);a.velocities[this.m_indexA].w=c;a.velocities[this.m_indexB].w=d};goog.exportProperty(box2d.b2DistanceJoint.prototype,\"SolveVelocityConstraints\",box2d.b2DistanceJoint.prototype.SolveVelocityConstraints);\nbox2d.b2DistanceJoint.prototype.SolveVelocityConstraints.s_vpA=new box2d.b2Vec2;box2d.b2DistanceJoint.prototype.SolveVelocityConstraints.s_vpB=new box2d.b2Vec2;box2d.b2DistanceJoint.prototype.SolveVelocityConstraints.s_P=new box2d.b2Vec2;\nbox2d.b2DistanceJoint.prototype.SolvePositionConstraints=function(a){if(0<this.m_frequencyHz)return!0;var b=a.positions[this.m_indexA].c,c=a.positions[this.m_indexA].a,e=a.positions[this.m_indexB].c,d=a.positions[this.m_indexB].a;this.m_qA.SetAngleRadians(c);this.m_qB.SetAngleRadians(d);var f=box2d.b2MulRV(this.m_qA,this.m_lalcA,this.m_rA),g=box2d.b2MulRV(this.m_qB,this.m_lalcB,this.m_rB),h=this.m_u;h.x=e.x+g.x-b.x-f.x;h.y=e.y+g.y-b.y-f.y;var l=this.m_u.Normalize()-this.m_length,l=box2d.b2Clamp(l,\n-box2d.b2_maxLinearCorrection,box2d.b2_maxLinearCorrection),h=box2d.b2MulSV(-this.m_mass*l,h,box2d.b2DistanceJoint.prototype.SolvePositionConstraints.s_P);b.SelfMulSub(this.m_invMassA,h);c-=this.m_invIA*box2d.b2CrossVV(f,h);e.SelfMulAdd(this.m_invMassB,h);d+=this.m_invIB*box2d.b2CrossVV(g,h);a.positions[this.m_indexA].a=c;a.positions[this.m_indexB].a=d;return box2d.b2Abs(l)<box2d.b2_linearSlop};goog.exportProperty(box2d.b2DistanceJoint.prototype,\"SolvePositionConstraints\",box2d.b2DistanceJoint.prototype.SolvePositionConstraints);\nbox2d.b2DistanceJoint.prototype.SolvePositionConstraints.s_P=new box2d.b2Vec2;box2d.b2FrictionJointDef=function(){box2d.b2JointDef.call(this,box2d.b2JointType.e_frictionJoint);this.localAnchorA=new box2d.b2Vec2;this.localAnchorB=new box2d.b2Vec2};goog.inherits(box2d.b2FrictionJointDef,box2d.b2JointDef);goog.exportSymbol(\"box2d.b2FrictionJointDef\",box2d.b2FrictionJointDef);box2d.b2FrictionJointDef.prototype.localAnchorA=null;goog.exportProperty(box2d.b2FrictionJointDef.prototype,\"localAnchorA\",box2d.b2FrictionJointDef.prototype.localAnchorA);\nbox2d.b2FrictionJointDef.prototype.localAnchorB=null;goog.exportProperty(box2d.b2FrictionJointDef.prototype,\"localAnchorB\",box2d.b2FrictionJointDef.prototype.localAnchorB);box2d.b2FrictionJointDef.prototype.maxForce=0;goog.exportProperty(box2d.b2FrictionJointDef.prototype,\"maxForce\",box2d.b2FrictionJointDef.prototype.maxForce);box2d.b2FrictionJointDef.prototype.maxTorque=0;goog.exportProperty(box2d.b2FrictionJointDef.prototype,\"maxTorque\",box2d.b2FrictionJointDef.prototype.maxTorque);\nbox2d.b2FrictionJointDef.prototype.Initialize=function(a,b,c){this.bodyA=a;this.bodyB=b;this.bodyA.GetLocalPoint(c,this.localAnchorA);this.bodyB.GetLocalPoint(c,this.localAnchorB)};goog.exportProperty(box2d.b2FrictionJointDef.prototype,\"Initialize\",box2d.b2FrictionJointDef.prototype.Initialize);\nbox2d.b2FrictionJoint=function(a){box2d.b2Joint.call(this,a);this.m_localAnchorA=a.localAnchorA.Clone();this.m_localAnchorB=a.localAnchorB.Clone();this.m_linearImpulse=(new box2d.b2Vec2).SetZero();this.m_maxForce=a.maxForce;this.m_maxTorque=a.maxTorque;this.m_rA=new box2d.b2Vec2;this.m_rB=new box2d.b2Vec2;this.m_localCenterA=new box2d.b2Vec2;this.m_localCenterB=new box2d.b2Vec2;this.m_linearMass=(new box2d.b2Mat22).SetZero();this.m_qA=new box2d.b2Rot;this.m_qB=new box2d.b2Rot;this.m_lalcA=new box2d.b2Vec2;\nthis.m_lalcB=new box2d.b2Vec2;this.m_K=new box2d.b2Mat22};goog.inherits(box2d.b2FrictionJoint,box2d.b2Joint);goog.exportSymbol(\"box2d.b2FrictionJoint\",box2d.b2FrictionJoint);box2d.b2FrictionJoint.prototype.m_localAnchorA=null;goog.exportProperty(box2d.b2FrictionJoint.prototype,\"m_localAnchorA\",box2d.b2FrictionJoint.prototype.m_localAnchorA);box2d.b2FrictionJoint.prototype.m_localAnchorB=null;goog.exportProperty(box2d.b2FrictionJoint.prototype,\"m_localAnchorB\",box2d.b2FrictionJoint.prototype.m_localAnchorB);\nbox2d.b2FrictionJoint.prototype.m_linearImpulse=null;goog.exportProperty(box2d.b2FrictionJoint.prototype,\"m_linearImpulse\",box2d.b2FrictionJoint.prototype.m_linearImpulse);box2d.b2FrictionJoint.prototype.m_angularImpulse=0;goog.exportProperty(box2d.b2FrictionJoint.prototype,\"m_angularImpulse\",box2d.b2FrictionJoint.prototype.m_angularImpulse);box2d.b2FrictionJoint.prototype.m_maxForce=0;goog.exportProperty(box2d.b2FrictionJoint.prototype,\"m_maxForce\",box2d.b2FrictionJoint.prototype.m_maxForce);\nbox2d.b2FrictionJoint.prototype.m_maxTorque=0;goog.exportProperty(box2d.b2FrictionJoint.prototype,\"m_maxTorque\",box2d.b2FrictionJoint.prototype.m_maxTorque);box2d.b2FrictionJoint.prototype.m_indexA=0;goog.exportProperty(box2d.b2FrictionJoint.prototype,\"m_indexA\",box2d.b2FrictionJoint.prototype.m_indexA);box2d.b2FrictionJoint.prototype.m_indexB=0;goog.exportProperty(box2d.b2FrictionJoint.prototype,\"m_indexB\",box2d.b2FrictionJoint.prototype.m_indexB);box2d.b2FrictionJoint.prototype.m_rA=null;\ngoog.exportProperty(box2d.b2FrictionJoint.prototype,\"m_rA\",box2d.b2FrictionJoint.prototype.m_rA);box2d.b2FrictionJoint.prototype.m_rB=null;goog.exportProperty(box2d.b2FrictionJoint.prototype,\"m_rB\",box2d.b2FrictionJoint.prototype.m_rB);box2d.b2FrictionJoint.prototype.m_localCenterA=null;goog.exportProperty(box2d.b2FrictionJoint.prototype,\"m_localCenterA\",box2d.b2FrictionJoint.prototype.m_localCenterA);box2d.b2FrictionJoint.prototype.m_localCenterB=null;\ngoog.exportProperty(box2d.b2FrictionJoint.prototype,\"m_localCenterB\",box2d.b2FrictionJoint.prototype.m_localCenterB);box2d.b2FrictionJoint.prototype.m_invMassA=0;goog.exportProperty(box2d.b2FrictionJoint.prototype,\"m_invMassA\",box2d.b2FrictionJoint.prototype.m_invMassA);box2d.b2FrictionJoint.prototype.m_invMassB=0;goog.exportProperty(box2d.b2FrictionJoint.prototype,\"m_invMassB\",box2d.b2FrictionJoint.prototype.m_invMassB);box2d.b2FrictionJoint.prototype.m_invIA=0;\ngoog.exportProperty(box2d.b2FrictionJoint.prototype,\"m_invIA\",box2d.b2FrictionJoint.prototype.m_invIA);box2d.b2FrictionJoint.prototype.m_invIB=0;goog.exportProperty(box2d.b2FrictionJoint.prototype,\"m_invIB\",box2d.b2FrictionJoint.prototype.m_invIB);box2d.b2FrictionJoint.prototype.m_linearMass=null;goog.exportProperty(box2d.b2FrictionJoint.prototype,\"m_linearMass\",box2d.b2FrictionJoint.prototype.m_linearMass);box2d.b2FrictionJoint.prototype.m_angularMass=0;\ngoog.exportProperty(box2d.b2FrictionJoint.prototype,\"m_angularMass\",box2d.b2FrictionJoint.prototype.m_angularMass);box2d.b2FrictionJoint.prototype.m_qA=null;goog.exportProperty(box2d.b2FrictionJoint.prototype,\"m_qA\",box2d.b2FrictionJoint.prototype.m_qA);box2d.b2FrictionJoint.prototype.m_qB=null;goog.exportProperty(box2d.b2FrictionJoint.prototype,\"m_qB\",box2d.b2FrictionJoint.prototype.m_qB);box2d.b2FrictionJoint.prototype.m_lalcA=null;goog.exportProperty(box2d.b2FrictionJoint.prototype,\"m_lalcA\",box2d.b2FrictionJoint.prototype.m_lalcA);\nbox2d.b2FrictionJoint.prototype.m_lalcB=null;goog.exportProperty(box2d.b2FrictionJoint.prototype,\"m_lalcB\",box2d.b2FrictionJoint.prototype.m_lalcB);box2d.b2FrictionJoint.prototype.m_K=null;goog.exportProperty(box2d.b2FrictionJoint.prototype,\"m_K\",box2d.b2FrictionJoint.prototype.m_K);\nbox2d.b2FrictionJoint.prototype.InitVelocityConstraints=function(a){this.m_indexA=this.m_bodyA.m_islandIndex;this.m_indexB=this.m_bodyB.m_islandIndex;this.m_localCenterA.Copy(this.m_bodyA.m_sweep.localCenter);this.m_localCenterB.Copy(this.m_bodyB.m_sweep.localCenter);this.m_invMassA=this.m_bodyA.m_invMass;this.m_invMassB=this.m_bodyB.m_invMass;this.m_invIA=this.m_bodyA.m_invI;this.m_invIB=this.m_bodyB.m_invI;var b=a.velocities[this.m_indexA].v,c=a.velocities[this.m_indexA].w,e=a.positions[this.m_indexB].a,\nd=a.velocities[this.m_indexB].v,f=a.velocities[this.m_indexB].w,g=this.m_qA.SetAngleRadians(a.positions[this.m_indexA].a),e=this.m_qB.SetAngleRadians(e);box2d.b2SubVV(this.m_localAnchorA,this.m_localCenterA,this.m_lalcA);g=box2d.b2MulRV(g,this.m_lalcA,this.m_rA);box2d.b2SubVV(this.m_localAnchorB,this.m_localCenterB,this.m_lalcB);var h=box2d.b2MulRV(e,this.m_lalcB,this.m_rB),e=this.m_invMassA,l=this.m_invMassB,k=this.m_invIA,m=this.m_invIB,n=this.m_K;n.ex.x=e+l+k*g.y*g.y+m*h.y*h.y;n.ex.y=-k*g.x*g.y-\nm*h.x*h.y;n.ey.x=n.ex.y;n.ey.y=e+l+k*g.x*g.x+m*h.x*h.x;n.GetInverse(this.m_linearMass);this.m_angularMass=k+m;0<this.m_angularMass&&(this.m_angularMass=1/this.m_angularMass);a.step.warmStarting?(this.m_linearImpulse.SelfMul(a.step.dtRatio),this.m_angularImpulse*=a.step.dtRatio,g=this.m_linearImpulse,b.SelfMulSub(e,g),c-=k*(box2d.b2CrossVV(this.m_rA,g)+this.m_angularImpulse),d.SelfMulAdd(l,g),f+=m*(box2d.b2CrossVV(this.m_rB,g)+this.m_angularImpulse)):(this.m_linearImpulse.SetZero(),this.m_angularImpulse=\n0);a.velocities[this.m_indexA].w=c;a.velocities[this.m_indexB].w=f};goog.exportProperty(box2d.b2FrictionJoint.prototype,\"InitVelocityConstraints\",box2d.b2FrictionJoint.prototype.InitVelocityConstraints);\nbox2d.b2FrictionJoint.prototype.SolveVelocityConstraints=function(a){var b=a.velocities[this.m_indexA].v,c=a.velocities[this.m_indexA].w,e=a.velocities[this.m_indexB].v,d=a.velocities[this.m_indexB].w,f=this.m_invMassA,g=this.m_invMassB,h=this.m_invIA,l=this.m_invIB,k=a.step.dt,m,n=-this.m_angularMass*(d-c),p=this.m_angularImpulse;m=k*this.m_maxTorque;this.m_angularImpulse=box2d.b2Clamp(this.m_angularImpulse+n,-m,m);n=this.m_angularImpulse-p;c-=h*n;d+=l*n;m=box2d.b2SubVV(box2d.b2AddVCrossSV(e,d,this.m_rB,\nbox2d.b2Vec2.s_t0),box2d.b2AddVCrossSV(b,c,this.m_rA,box2d.b2Vec2.s_t1),box2d.b2FrictionJoint.prototype.SolveVelocityConstraints.s_Cdot);n=box2d.b2MulMV(this.m_linearMass,m,box2d.b2FrictionJoint.prototype.SolveVelocityConstraints.s_impulseV).SelfNeg();p=box2d.b2FrictionJoint.prototype.SolveVelocityConstraints.s_oldImpulseV.Copy(this.m_linearImpulse);this.m_linearImpulse.SelfAdd(n);m=k*this.m_maxForce;this.m_linearImpulse.GetLengthSquared()>m*m&&(this.m_linearImpulse.Normalize(),this.m_linearImpulse.SelfMul(m));\nbox2d.b2SubVV(this.m_linearImpulse,p,n);b.SelfMulSub(f,n);c-=h*box2d.b2CrossVV(this.m_rA,n);e.SelfMulAdd(g,n);d+=l*box2d.b2CrossVV(this.m_rB,n);a.velocities[this.m_indexA].w=c;a.velocities[this.m_indexB].w=d};goog.exportProperty(box2d.b2FrictionJoint.prototype,\"SolveVelocityConstraints\",box2d.b2FrictionJoint.prototype.SolveVelocityConstraints);box2d.b2FrictionJoint.prototype.SolveVelocityConstraints.s_Cdot=new box2d.b2Vec2;box2d.b2FrictionJoint.prototype.SolveVelocityConstraints.s_impulseV=new box2d.b2Vec2;\nbox2d.b2FrictionJoint.prototype.SolveVelocityConstraints.s_oldImpulseV=new box2d.b2Vec2;box2d.b2FrictionJoint.prototype.SolvePositionConstraints=function(a){return!0};goog.exportProperty(box2d.b2FrictionJoint.prototype,\"SolvePositionConstraints\",box2d.b2FrictionJoint.prototype.SolvePositionConstraints);box2d.b2FrictionJoint.prototype.GetAnchorA=function(a){return this.m_bodyA.GetWorldPoint(this.m_localAnchorA,a)};goog.exportProperty(box2d.b2FrictionJoint.prototype,\"GetAnchorA\",box2d.b2FrictionJoint.prototype.GetAnchorA);\nbox2d.b2FrictionJoint.prototype.GetAnchorB=function(a){return this.m_bodyB.GetWorldPoint(this.m_localAnchorB,a)};goog.exportProperty(box2d.b2FrictionJoint.prototype,\"GetAnchorB\",box2d.b2FrictionJoint.prototype.GetAnchorB);box2d.b2FrictionJoint.prototype.GetReactionForce=function(a,b){return b.SetXY(a*this.m_linearImpulse.x,a*this.m_linearImpulse.y)};goog.exportProperty(box2d.b2FrictionJoint.prototype,\"GetReactionForce\",box2d.b2FrictionJoint.prototype.GetReactionForce);\nbox2d.b2FrictionJoint.prototype.GetReactionTorque=function(a){return a*this.m_angularImpulse};goog.exportProperty(box2d.b2FrictionJoint.prototype,\"GetReactionTorque\",box2d.b2FrictionJoint.prototype.GetReactionTorque);box2d.b2FrictionJoint.prototype.GetLocalAnchorA=function(a){return a.Copy(this.m_localAnchorA)};goog.exportProperty(box2d.b2FrictionJoint.prototype,\"GetLocalAnchorA\",box2d.b2FrictionJoint.prototype.GetLocalAnchorA);box2d.b2FrictionJoint.prototype.GetLocalAnchorB=function(a){return a.Copy(this.m_localAnchorB)};\ngoog.exportProperty(box2d.b2FrictionJoint.prototype,\"GetLocalAnchorB\",box2d.b2FrictionJoint.prototype.GetLocalAnchorB);box2d.b2FrictionJoint.prototype.SetMaxForce=function(a){this.m_maxForce=a};goog.exportProperty(box2d.b2FrictionJoint.prototype,\"SetMaxForce\",box2d.b2FrictionJoint.prototype.SetMaxForce);box2d.b2FrictionJoint.prototype.GetMaxForce=function(){return this.m_maxForce};goog.exportProperty(box2d.b2FrictionJoint.prototype,\"GetMaxForce\",box2d.b2FrictionJoint.prototype.GetMaxForce);\nbox2d.b2FrictionJoint.prototype.SetMaxTorque=function(a){this.m_maxTorque=a};goog.exportProperty(box2d.b2FrictionJoint.prototype,\"SetMaxTorque\",box2d.b2FrictionJoint.prototype.SetMaxTorque);box2d.b2FrictionJoint.prototype.GetMaxTorque=function(){return this.m_maxTorque};goog.exportProperty(box2d.b2FrictionJoint.prototype,\"GetMaxTorque\",box2d.b2FrictionJoint.prototype.GetMaxTorque);\nbox2d.b2FrictionJoint.prototype.Dump=function(){if(box2d.DEBUG){var a=this.m_bodyA.m_islandIndex,b=this.m_bodyB.m_islandIndex;box2d.b2Log(\"  /*box2d.b2FrictionJointDef*/ var jd = new box2d.b2FrictionJointDef();\\n\");box2d.b2Log(\"  jd.bodyA = bodies[%d];\\n\",a);box2d.b2Log(\"  jd.bodyB = bodies[%d];\\n\",b);box2d.b2Log(\"  jd.collideConnected = %s;\\n\",this.m_collideConnected?\"true\":\"false\");box2d.b2Log(\"  jd.localAnchorA.SetXY(%.15f, %.15f);\\n\",this.m_localAnchorA.x,this.m_localAnchorA.y);box2d.b2Log(\"  jd.localAnchorB.SetXY(%.15f, %.15f);\\n\",\nthis.m_localAnchorB.x,this.m_localAnchorB.y);box2d.b2Log(\"  jd.maxForce = %.15f;\\n\",this.m_maxForce);box2d.b2Log(\"  jd.maxTorque = %.15f;\\n\",this.m_maxTorque);box2d.b2Log(\"  joints[%d] = this.m_world.CreateJoint(jd);\\n\",this.m_index)}};goog.exportProperty(box2d.b2FrictionJoint.prototype,\"Dump\",box2d.b2FrictionJoint.prototype.Dump);box2d.b2MouseJointDef=function(){box2d.b2JointDef.call(this,box2d.b2JointType.e_mouseJoint);this.target=new box2d.b2Vec2};goog.inherits(box2d.b2MouseJointDef,box2d.b2JointDef);goog.exportSymbol(\"box2d.b2MouseJointDef\",box2d.b2MouseJointDef);box2d.b2MouseJointDef.prototype.target=null;goog.exportProperty(box2d.b2MouseJointDef.prototype,\"target\",box2d.b2MouseJointDef.prototype.target);box2d.b2MouseJointDef.prototype.maxForce=0;goog.exportProperty(box2d.b2MouseJointDef.prototype,\"maxForce\",box2d.b2MouseJointDef.prototype.maxForce);\nbox2d.b2MouseJointDef.prototype.frequencyHz=5;goog.exportProperty(box2d.b2MouseJointDef.prototype,\"frequencyHz\",box2d.b2MouseJointDef.prototype.frequencyHz);box2d.b2MouseJointDef.prototype.dampingRatio=0.7;goog.exportProperty(box2d.b2MouseJointDef.prototype,\"dampingRatio\",box2d.b2MouseJointDef.prototype.dampingRatio);\nbox2d.b2MouseJoint=function(a){box2d.b2Joint.call(this,a);this.m_localAnchorB=new box2d.b2Vec2;this.m_targetA=new box2d.b2Vec2;this.m_impulse=new box2d.b2Vec2;this.m_rB=new box2d.b2Vec2;this.m_localCenterB=new box2d.b2Vec2;this.m_mass=new box2d.b2Mat22;this.m_C=new box2d.b2Vec2;this.m_qB=new box2d.b2Rot;this.m_lalcB=new box2d.b2Vec2;this.m_K=new box2d.b2Mat22;box2d.ENABLE_ASSERTS&&box2d.b2Assert(a.target.IsValid());box2d.ENABLE_ASSERTS&&box2d.b2Assert(box2d.b2IsValid(a.maxForce)&&0<=a.maxForce);box2d.ENABLE_ASSERTS&&\nbox2d.b2Assert(box2d.b2IsValid(a.frequencyHz)&&0<=a.frequencyHz);box2d.ENABLE_ASSERTS&&box2d.b2Assert(box2d.b2IsValid(a.dampingRatio)&&0<=a.dampingRatio);this.m_targetA.Copy(a.target);box2d.b2MulTXV(this.m_bodyB.GetTransform(),this.m_targetA,this.m_localAnchorB);this.m_maxForce=a.maxForce;this.m_impulse.SetZero();this.m_frequencyHz=a.frequencyHz;this.m_dampingRatio=a.dampingRatio;this.m_gamma=this.m_beta=0};goog.inherits(box2d.b2MouseJoint,box2d.b2Joint);goog.exportSymbol(\"box2d.b2MouseJoint\",box2d.b2MouseJoint);\nbox2d.b2MouseJoint.prototype.m_localAnchorB=null;goog.exportProperty(box2d.b2MouseJoint.prototype,\"m_localAnchorB\",box2d.b2MouseJoint.prototype.m_localAnchorB);box2d.b2MouseJoint.prototype.m_targetA=null;goog.exportProperty(box2d.b2MouseJoint.prototype,\"m_targetA\",box2d.b2MouseJoint.prototype.m_targetA);box2d.b2MouseJoint.prototype.m_frequencyHz=0;goog.exportProperty(box2d.b2MouseJoint.prototype,\"m_frequencyHz\",box2d.b2MouseJoint.prototype.m_frequencyHz);\nbox2d.b2MouseJoint.prototype.m_dampingRatio=0;goog.exportProperty(box2d.b2MouseJoint.prototype,\"m_dampingRatio\",box2d.b2MouseJoint.prototype.m_dampingRatio);box2d.b2MouseJoint.prototype.m_beta=0;goog.exportProperty(box2d.b2MouseJoint.prototype,\"m_beta\",box2d.b2MouseJoint.prototype.m_beta);box2d.b2MouseJoint.prototype.m_impulse=null;goog.exportProperty(box2d.b2MouseJoint.prototype,\"m_impulse\",box2d.b2MouseJoint.prototype.m_impulse);box2d.b2MouseJoint.prototype.m_maxForce=0;\ngoog.exportProperty(box2d.b2MouseJoint.prototype,\"m_maxForce\",box2d.b2MouseJoint.prototype.m_maxForce);box2d.b2MouseJoint.prototype.m_gamma=0;goog.exportProperty(box2d.b2MouseJoint.prototype,\"m_gamma\",box2d.b2MouseJoint.prototype.m_gamma);box2d.b2MouseJoint.prototype.m_indexA=0;goog.exportProperty(box2d.b2MouseJoint.prototype,\"m_indexA\",box2d.b2MouseJoint.prototype.m_indexA);box2d.b2MouseJoint.prototype.m_indexB=0;goog.exportProperty(box2d.b2MouseJoint.prototype,\"m_indexB\",box2d.b2MouseJoint.prototype.m_indexB);\nbox2d.b2MouseJoint.prototype.m_rB=null;goog.exportProperty(box2d.b2MouseJoint.prototype,\"m_rB\",box2d.b2MouseJoint.prototype.m_rB);box2d.b2MouseJoint.prototype.m_localCenterB=null;goog.exportProperty(box2d.b2MouseJoint.prototype,\"m_localCenterB\",box2d.b2MouseJoint.prototype.m_localCenterB);box2d.b2MouseJoint.prototype.m_invMassB=0;goog.exportProperty(box2d.b2MouseJoint.prototype,\"m_invMassB\",box2d.b2MouseJoint.prototype.m_invMassB);box2d.b2MouseJoint.prototype.m_invIB=0;\ngoog.exportProperty(box2d.b2MouseJoint.prototype,\"m_invIB\",box2d.b2MouseJoint.prototype.m_invIB);box2d.b2MouseJoint.prototype.m_mass=null;goog.exportProperty(box2d.b2MouseJoint.prototype,\"m_mass\",box2d.b2MouseJoint.prototype.m_mass);box2d.b2MouseJoint.prototype.m_C=null;goog.exportProperty(box2d.b2MouseJoint.prototype,\"m_C\",box2d.b2MouseJoint.prototype.m_C);box2d.b2MouseJoint.prototype.m_qB=null;goog.exportProperty(box2d.b2MouseJoint.prototype,\"m_qB\",box2d.b2MouseJoint.prototype.m_qB);\nbox2d.b2MouseJoint.prototype.m_lalcB=null;goog.exportProperty(box2d.b2MouseJoint.prototype,\"m_lalcB\",box2d.b2MouseJoint.prototype.m_lalcB);box2d.b2MouseJoint.prototype.m_K=null;goog.exportProperty(box2d.b2MouseJoint.prototype,\"m_K\",box2d.b2MouseJoint.prototype.m_K);box2d.b2MouseJoint.prototype.SetTarget=function(a){!1===this.m_bodyB.IsAwake()&&this.m_bodyB.SetAwake(!0);this.m_targetA.Copy(a)};goog.exportProperty(box2d.b2MouseJoint.prototype,\"SetTarget\",box2d.b2MouseJoint.prototype.SetTarget);\nbox2d.b2MouseJoint.prototype.GetTarget=function(a){return a.Copy(this.m_targetA)};goog.exportProperty(box2d.b2MouseJoint.prototype,\"GetTarget\",box2d.b2MouseJoint.prototype.GetTarget);box2d.b2MouseJoint.prototype.SetMaxForce=function(a){this.m_maxForce=a};goog.exportProperty(box2d.b2MouseJoint.prototype,\"SetMaxForce\",box2d.b2MouseJoint.prototype.SetMaxForce);box2d.b2MouseJoint.prototype.GetMaxForce=function(){return this.m_maxForce};goog.exportProperty(box2d.b2MouseJoint.prototype,\"GetMaxForce\",box2d.b2MouseJoint.prototype.GetMaxForce);\nbox2d.b2MouseJoint.prototype.SetFrequency=function(a){this.m_frequencyHz=a};goog.exportProperty(box2d.b2MouseJoint.prototype,\"SetFrequency\",box2d.b2MouseJoint.prototype.SetFrequency);box2d.b2MouseJoint.prototype.GetFrequency=function(){return this.m_frequencyHz};goog.exportProperty(box2d.b2MouseJoint.prototype,\"GetFrequency\",box2d.b2MouseJoint.prototype.GetFrequency);box2d.b2MouseJoint.prototype.SetDampingRatio=function(a){this.m_dampingRatio=a};\ngoog.exportProperty(box2d.b2MouseJoint.prototype,\"SetDampingRatio\",box2d.b2MouseJoint.prototype.SetDampingRatio);box2d.b2MouseJoint.prototype.GetDampingRatio=function(){return this.m_dampingRatio};goog.exportProperty(box2d.b2MouseJoint.prototype,\"GetDampingRatio\",box2d.b2MouseJoint.prototype.GetDampingRatio);\nbox2d.b2MouseJoint.prototype.InitVelocityConstraints=function(a){this.m_indexB=this.m_bodyB.m_islandIndex;this.m_localCenterB.Copy(this.m_bodyB.m_sweep.localCenter);this.m_invMassB=this.m_bodyB.m_invMass;this.m_invIB=this.m_bodyB.m_invI;var b=a.positions[this.m_indexB].c,c=a.velocities[this.m_indexB].v,e=a.velocities[this.m_indexB].w,d=this.m_qB.SetAngleRadians(a.positions[this.m_indexB].a),f=this.m_bodyB.GetMass(),g=2*box2d.b2_pi*this.m_frequencyHz,h=2*f*this.m_dampingRatio*g,f=f*g*g,g=a.step.dt;\nbox2d.ENABLE_ASSERTS&&box2d.b2Assert(h+g*f>box2d.b2_epsilon);this.m_gamma=g*(h+g*f);0!==this.m_gamma&&(this.m_gamma=1/this.m_gamma);this.m_beta=g*f*this.m_gamma;box2d.b2SubVV(this.m_localAnchorB,this.m_localCenterB,this.m_lalcB);box2d.b2MulRV(d,this.m_lalcB,this.m_rB);d=this.m_K;d.ex.x=this.m_invMassB+this.m_invIB*this.m_rB.y*this.m_rB.y+this.m_gamma;d.ex.y=-this.m_invIB*this.m_rB.x*this.m_rB.y;d.ey.x=d.ex.y;d.ey.y=this.m_invMassB+this.m_invIB*this.m_rB.x*this.m_rB.x+this.m_gamma;d.GetInverse(this.m_mass);\nthis.m_C.x=b.x+this.m_rB.x-this.m_targetA.x;this.m_C.y=b.y+this.m_rB.y-this.m_targetA.y;this.m_C.SelfMul(this.m_beta);e*=0.98;a.step.warmStarting?(this.m_impulse.SelfMul(a.step.dtRatio),c.x+=this.m_invMassB*this.m_impulse.x,c.y+=this.m_invMassB*this.m_impulse.y,e+=this.m_invIB*box2d.b2CrossVV(this.m_rB,this.m_impulse)):this.m_impulse.SetZero();a.velocities[this.m_indexB].w=e};goog.exportProperty(box2d.b2MouseJoint.prototype,\"InitVelocityConstraints\",box2d.b2MouseJoint.prototype.InitVelocityConstraints);\nbox2d.b2MouseJoint.prototype.SolveVelocityConstraints=function(a){var b=a.velocities[this.m_indexB].v,c=a.velocities[this.m_indexB].w,e=box2d.b2AddVCrossSV(b,c,this.m_rB,box2d.b2MouseJoint.prototype.SolveVelocityConstraints.s_Cdot),e=box2d.b2MulMV(this.m_mass,box2d.b2AddVV(e,box2d.b2AddVV(this.m_C,box2d.b2MulSV(this.m_gamma,this.m_impulse,box2d.b2Vec2.s_t0),box2d.b2Vec2.s_t0),box2d.b2Vec2.s_t0).SelfNeg(),box2d.b2MouseJoint.prototype.SolveVelocityConstraints.s_impulse),d=box2d.b2MouseJoint.prototype.SolveVelocityConstraints.s_oldImpulse.Copy(this.m_impulse);\nthis.m_impulse.SelfAdd(e);var f=a.step.dt*this.m_maxForce;this.m_impulse.GetLengthSquared()>f*f&&this.m_impulse.SelfMul(f/this.m_impulse.GetLength());box2d.b2SubVV(this.m_impulse,d,e);b.SelfMulAdd(this.m_invMassB,e);c+=this.m_invIB*box2d.b2CrossVV(this.m_rB,e);a.velocities[this.m_indexB].w=c};goog.exportProperty(box2d.b2MouseJoint.prototype,\"SolveVelocityConstraints\",box2d.b2MouseJoint.prototype.SolveVelocityConstraints);box2d.b2MouseJoint.prototype.SolveVelocityConstraints.s_Cdot=new box2d.b2Vec2;\nbox2d.b2MouseJoint.prototype.SolveVelocityConstraints.s_impulse=new box2d.b2Vec2;box2d.b2MouseJoint.prototype.SolveVelocityConstraints.s_oldImpulse=new box2d.b2Vec2;box2d.b2MouseJoint.prototype.SolvePositionConstraints=function(a){return!0};goog.exportProperty(box2d.b2MouseJoint.prototype,\"SolvePositionConstraints\",box2d.b2MouseJoint.prototype.SolvePositionConstraints);box2d.b2MouseJoint.prototype.GetAnchorA=function(a){if(\"undefined\"==typeof a)a=new box2d.b2Vec2();return a.Copy(this.m_targetA)};\ngoog.exportProperty(box2d.b2MouseJoint.prototype,\"GetAnchorA\",box2d.b2MouseJoint.prototype.GetAnchorA);box2d.b2MouseJoint.prototype.GetAnchorB=function(a){if(\"undefined\"==typeof a)a=new box2d.b2Vec2();return this.m_bodyB.GetWorldPoint(this.m_localAnchorB,a)};goog.exportProperty(box2d.b2MouseJoint.prototype,\"GetAnchorB\",box2d.b2MouseJoint.prototype.GetAnchorB);box2d.b2MouseJoint.prototype.GetReactionForce=function(a,b){return box2d.b2MulSV(a,this.m_impulse,b)};goog.exportProperty(box2d.b2MouseJoint.prototype,\"GetReactionForce\",box2d.b2MouseJoint.prototype.GetReactionForce);\nbox2d.b2MouseJoint.prototype.GetReactionTorque=function(a){return 0};goog.exportProperty(box2d.b2MouseJoint.prototype,\"GetReactionTorque\",box2d.b2MouseJoint.prototype.GetReactionTorque);box2d.b2MouseJoint.prototype.Dump=function(){box2d.DEBUG&&box2d.b2Log(\"Mouse joint dumping is not supported.\\n\")};goog.exportProperty(box2d.b2MouseJoint.prototype,\"Dump\",box2d.b2MouseJoint.prototype.Dump);box2d.b2MouseJoint.prototype.ShiftOrigin=function(a){this.m_targetA.SelfSub(a)};\ngoog.exportProperty(box2d.b2MouseJoint.prototype,\"ShiftOrigin\",box2d.b2MouseJoint.prototype.ShiftOrigin);box2d.b2ConstantForceController=function(){box2d.b2Controller.call(this);this.F=new box2d.b2Vec2(0,0)};goog.inherits(box2d.b2ConstantForceController,box2d.b2Controller);goog.exportSymbol(\"box2d.b2ConstantForceController\",box2d.b2ConstantForceController);box2d.b2ConstantAccelController.prototype.F=null;goog.exportProperty(box2d.b2ConstantAccelController.prototype,\"F\",box2d.b2ConstantAccelController.prototype.F);\nbox2d.b2ConstantForceController.prototype.Step=function(a){for(a=this.m_bodyList;a;a=a.nextBody){var b=a.body;b.IsAwake()&&b.ApplyForce(this.F,b.GetWorldCenter())}};goog.exportProperty(box2d.b2ConstantForceController.prototype,\"Step\",box2d.b2ConstantForceController.prototype.Step);box2d.b2_minPulleyLength=2;goog.exportSymbol(\"box2d.b2_minPulleyLength\",box2d.b2_minPulleyLength);box2d.b2PulleyJointDef=function(){box2d.b2JointDef.call(this,box2d.b2JointType.e_pulleyJoint);this.collideConnected=!0;this.groundAnchorA=new box2d.b2Vec2(-1,1);this.groundAnchorB=new box2d.b2Vec2(1,1);this.localAnchorA=new box2d.b2Vec2(-1,0);this.localAnchorB=new box2d.b2Vec2(1,0)};goog.inherits(box2d.b2PulleyJointDef,box2d.b2JointDef);goog.exportSymbol(\"box2d.b2PulleyJointDef\",box2d.b2PulleyJointDef);\nbox2d.b2PulleyJointDef.prototype.groundAnchorA=null;goog.exportProperty(box2d.b2PulleyJointDef.prototype,\"groundAnchorA\",box2d.b2PulleyJointDef.prototype.groundAnchorA);box2d.b2PulleyJointDef.prototype.groundAnchorB=null;goog.exportProperty(box2d.b2PulleyJointDef.prototype,\"groundAnchorB\",box2d.b2PulleyJointDef.prototype.groundAnchorB);box2d.b2PulleyJointDef.prototype.localAnchorA=null;goog.exportProperty(box2d.b2PulleyJointDef.prototype,\"localAnchorA\",box2d.b2PulleyJointDef.prototype.localAnchorA);\nbox2d.b2PulleyJointDef.prototype.localAnchorB=null;goog.exportProperty(box2d.b2PulleyJointDef.prototype,\"localAnchorB\",box2d.b2PulleyJointDef.prototype.localAnchorB);box2d.b2PulleyJointDef.prototype.lengthA=0;goog.exportProperty(box2d.b2PulleyJointDef.prototype,\"lengthA\",box2d.b2PulleyJointDef.prototype.lengthA);box2d.b2PulleyJointDef.prototype.lengthB=0;goog.exportProperty(box2d.b2PulleyJointDef.prototype,\"lengthB\",box2d.b2PulleyJointDef.prototype.lengthB);\nbox2d.b2PulleyJointDef.prototype.ratio=1;goog.exportProperty(box2d.b2PulleyJointDef.prototype,\"ratio\",box2d.b2PulleyJointDef.prototype.ratio);\nbox2d.b2PulleyJointDef.prototype.Initialize=function(a,b,c,e,d,f,g){this.bodyA=a;this.bodyB=b;this.groundAnchorA.Copy(c);this.groundAnchorB.Copy(e);this.bodyA.GetLocalPoint(d,this.localAnchorA);this.bodyB.GetLocalPoint(f,this.localAnchorB);this.lengthA=box2d.b2DistanceVV(d,c);this.lengthB=box2d.b2DistanceVV(f,e);this.ratio=g;box2d.ENABLE_ASSERTS&&box2d.b2Assert(this.ratio>box2d.b2_epsilon)};goog.exportProperty(box2d.b2PulleyJointDef.prototype,\"Initialize\",box2d.b2PulleyJointDef.prototype.Initialize);\nbox2d.b2PulleyJoint=function(a){box2d.b2Joint.call(this,a);this.m_groundAnchorA=new box2d.b2Vec2;this.m_groundAnchorB=new box2d.b2Vec2;this.m_localAnchorA=new box2d.b2Vec2;this.m_localAnchorB=new box2d.b2Vec2;this.m_uA=new box2d.b2Vec2;this.m_uB=new box2d.b2Vec2;this.m_rA=new box2d.b2Vec2;this.m_rB=new box2d.b2Vec2;this.m_localCenterA=new box2d.b2Vec2;this.m_localCenterB=new box2d.b2Vec2;this.m_qA=new box2d.b2Rot;this.m_qB=new box2d.b2Rot;this.m_lalcA=new box2d.b2Vec2;this.m_lalcB=new box2d.b2Vec2;\nthis.m_groundAnchorA.Copy(a.groundAnchorA);this.m_groundAnchorB.Copy(a.groundAnchorB);this.m_localAnchorA.Copy(a.localAnchorA);this.m_localAnchorB.Copy(a.localAnchorB);this.m_lengthA=a.lengthA;this.m_lengthB=a.lengthB;box2d.ENABLE_ASSERTS&&box2d.b2Assert(0!==a.ratio);this.m_ratio=a.ratio;this.m_constant=a.lengthA+this.m_ratio*a.lengthB;this.m_impulse=0};goog.inherits(box2d.b2PulleyJoint,box2d.b2Joint);goog.exportSymbol(\"box2d.b2PulleyJoint\",box2d.b2PulleyJoint);\nbox2d.b2PulleyJoint.prototype.m_groundAnchorA=null;goog.exportProperty(box2d.b2PulleyJoint.prototype,\"m_groundAnchorA\",box2d.b2PulleyJoint.prototype.m_groundAnchorA);box2d.b2PulleyJoint.prototype.m_groundAnchorB=null;goog.exportProperty(box2d.b2PulleyJoint.prototype,\"m_groundAnchorB\",box2d.b2PulleyJoint.prototype.m_groundAnchorB);box2d.b2PulleyJoint.prototype.m_lengthA=0;goog.exportProperty(box2d.b2PulleyJoint.prototype,\"m_lengthA\",box2d.b2PulleyJoint.prototype.m_lengthA);\nbox2d.b2PulleyJoint.prototype.m_lengthB=0;goog.exportProperty(box2d.b2PulleyJoint.prototype,\"m_lengthB\",box2d.b2PulleyJoint.prototype.m_lengthB);box2d.b2PulleyJoint.prototype.m_localAnchorA=null;goog.exportProperty(box2d.b2PulleyJoint.prototype,\"m_localAnchorA\",box2d.b2PulleyJoint.prototype.m_localAnchorA);box2d.b2PulleyJoint.prototype.m_localAnchorB=null;goog.exportProperty(box2d.b2PulleyJoint.prototype,\"m_localAnchorB\",box2d.b2PulleyJoint.prototype.m_localAnchorB);\nbox2d.b2PulleyJoint.prototype.m_constant=0;goog.exportProperty(box2d.b2PulleyJoint.prototype,\"m_constant\",box2d.b2PulleyJoint.prototype.m_constant);box2d.b2PulleyJoint.prototype.m_ratio=0;goog.exportProperty(box2d.b2PulleyJoint.prototype,\"m_ratio\",box2d.b2PulleyJoint.prototype.m_ratio);box2d.b2PulleyJoint.prototype.m_impulse=0;goog.exportProperty(box2d.b2PulleyJoint.prototype,\"m_impulse\",box2d.b2PulleyJoint.prototype.m_impulse);box2d.b2PulleyJoint.prototype.m_indexA=0;\ngoog.exportProperty(box2d.b2PulleyJoint.prototype,\"m_indexA\",box2d.b2PulleyJoint.prototype.m_indexA);box2d.b2PulleyJoint.prototype.m_indexB=0;goog.exportProperty(box2d.b2PulleyJoint.prototype,\"m_indexB\",box2d.b2PulleyJoint.prototype.m_indexB);box2d.b2PulleyJoint.prototype.m_uA=null;goog.exportProperty(box2d.b2PulleyJoint.prototype,\"m_uA\",box2d.b2PulleyJoint.prototype.m_uA);box2d.b2PulleyJoint.prototype.m_uB=null;goog.exportProperty(box2d.b2PulleyJoint.prototype,\"m_uB\",box2d.b2PulleyJoint.prototype.m_uB);\nbox2d.b2PulleyJoint.prototype.m_rA=null;goog.exportProperty(box2d.b2PulleyJoint.prototype,\"m_rA\",box2d.b2PulleyJoint.prototype.m_rA);box2d.b2PulleyJoint.prototype.m_rB=null;goog.exportProperty(box2d.b2PulleyJoint.prototype,\"m_rB\",box2d.b2PulleyJoint.prototype.m_rB);box2d.b2PulleyJoint.prototype.m_localCenterA=null;goog.exportProperty(box2d.b2PulleyJoint.prototype,\"m_localCenterA\",box2d.b2PulleyJoint.prototype.m_localCenterA);box2d.b2PulleyJoint.prototype.m_localCenterB=null;\ngoog.exportProperty(box2d.b2PulleyJoint.prototype,\"m_localCenterB\",box2d.b2PulleyJoint.prototype.m_localCenterB);box2d.b2PulleyJoint.prototype.m_invMassA=0;goog.exportProperty(box2d.b2PulleyJoint.prototype,\"m_invMassA\",box2d.b2PulleyJoint.prototype.m_invMassA);box2d.b2PulleyJoint.prototype.m_invMassB=0;goog.exportProperty(box2d.b2PulleyJoint.prototype,\"m_invMassB\",box2d.b2PulleyJoint.prototype.m_invMassB);box2d.b2PulleyJoint.prototype.m_invIA=0;\ngoog.exportProperty(box2d.b2PulleyJoint.prototype,\"m_invIA\",box2d.b2PulleyJoint.prototype.m_invIA);box2d.b2PulleyJoint.prototype.m_invIB=0;goog.exportProperty(box2d.b2PulleyJoint.prototype,\"m_invIB\",box2d.b2PulleyJoint.prototype.m_invIB);box2d.b2PulleyJoint.prototype.m_mass=0;goog.exportProperty(box2d.b2PulleyJoint.prototype,\"m_mass\",box2d.b2PulleyJoint.prototype.m_mass);box2d.b2PulleyJoint.prototype.m_qA=null;goog.exportProperty(box2d.b2PulleyJoint.prototype,\"m_qA\",box2d.b2PulleyJoint.prototype.m_qA);\nbox2d.b2PulleyJoint.prototype.m_qB=null;goog.exportProperty(box2d.b2PulleyJoint.prototype,\"m_qB\",box2d.b2PulleyJoint.prototype.m_qB);box2d.b2PulleyJoint.prototype.m_lalcA=null;goog.exportProperty(box2d.b2PulleyJoint.prototype,\"m_lalcA\",box2d.b2PulleyJoint.prototype.m_lalcA);box2d.b2PulleyJoint.prototype.m_lalcB=null;goog.exportProperty(box2d.b2PulleyJoint.prototype,\"m_lalcB\",box2d.b2PulleyJoint.prototype.m_lalcB);\nbox2d.b2PulleyJoint.prototype.InitVelocityConstraints=function(a){this.m_indexA=this.m_bodyA.m_islandIndex;this.m_indexB=this.m_bodyB.m_islandIndex;this.m_localCenterA.Copy(this.m_bodyA.m_sweep.localCenter);this.m_localCenterB.Copy(this.m_bodyB.m_sweep.localCenter);this.m_invMassA=this.m_bodyA.m_invMass;this.m_invMassB=this.m_bodyB.m_invMass;this.m_invIA=this.m_bodyA.m_invI;this.m_invIB=this.m_bodyB.m_invI;var b=a.positions[this.m_indexA].c,c=a.velocities[this.m_indexA].v,e=a.velocities[this.m_indexA].w,\nd=a.positions[this.m_indexB].c,f=a.positions[this.m_indexB].a,g=a.velocities[this.m_indexB].v,h=a.velocities[this.m_indexB].w,l=this.m_qA.SetAngleRadians(a.positions[this.m_indexA].a),f=this.m_qB.SetAngleRadians(f);box2d.b2SubVV(this.m_localAnchorA,this.m_localCenterA,this.m_lalcA);box2d.b2MulRV(l,this.m_lalcA,this.m_rA);box2d.b2SubVV(this.m_localAnchorB,this.m_localCenterB,this.m_lalcB);box2d.b2MulRV(f,this.m_lalcB,this.m_rB);this.m_uA.Copy(b).SelfAdd(this.m_rA).SelfSub(this.m_groundAnchorA);this.m_uB.Copy(d).SelfAdd(this.m_rB).SelfSub(this.m_groundAnchorB);\nb=this.m_uA.GetLength();d=this.m_uB.GetLength();b>10*box2d.b2_linearSlop?this.m_uA.SelfMul(1/b):this.m_uA.SetZero();d>10*box2d.b2_linearSlop?this.m_uB.SelfMul(1/d):this.m_uB.SetZero();b=box2d.b2CrossVV(this.m_rA,this.m_uA);d=box2d.b2CrossVV(this.m_rB,this.m_uB);this.m_mass=this.m_invMassA+this.m_invIA*b*b+this.m_ratio*this.m_ratio*(this.m_invMassB+this.m_invIB*d*d);0<this.m_mass&&(this.m_mass=1/this.m_mass);a.step.warmStarting?(this.m_impulse*=a.step.dtRatio,b=box2d.b2MulSV(-this.m_impulse,this.m_uA,\nbox2d.b2PulleyJoint.prototype.InitVelocityConstraints.s_PA),d=box2d.b2MulSV(-this.m_ratio*this.m_impulse,this.m_uB,box2d.b2PulleyJoint.prototype.InitVelocityConstraints.s_PB),c.SelfMulAdd(this.m_invMassA,b),e+=this.m_invIA*box2d.b2CrossVV(this.m_rA,b),g.SelfMulAdd(this.m_invMassB,d),h+=this.m_invIB*box2d.b2CrossVV(this.m_rB,d)):this.m_impulse=0;a.velocities[this.m_indexA].w=e;a.velocities[this.m_indexB].w=h};goog.exportProperty(box2d.b2PulleyJoint.prototype,\"InitVelocityConstraints\",box2d.b2PulleyJoint.prototype.InitVelocityConstraints);\nbox2d.b2PulleyJoint.prototype.InitVelocityConstraints.s_PA=new box2d.b2Vec2;box2d.b2PulleyJoint.prototype.InitVelocityConstraints.s_PB=new box2d.b2Vec2;\nbox2d.b2PulleyJoint.prototype.SolveVelocityConstraints=function(a){var b=a.velocities[this.m_indexA].v,c=a.velocities[this.m_indexA].w,e=a.velocities[this.m_indexB].v,d=a.velocities[this.m_indexB].w,f=box2d.b2AddVCrossSV(b,c,this.m_rA,box2d.b2PulleyJoint.prototype.SolveVelocityConstraints.s_vpA),g=box2d.b2AddVCrossSV(e,d,this.m_rB,box2d.b2PulleyJoint.prototype.SolveVelocityConstraints.s_vpB),f=-box2d.b2DotVV(this.m_uA,f)-this.m_ratio*box2d.b2DotVV(this.m_uB,g),g=-this.m_mass*f;this.m_impulse+=g;f=\nbox2d.b2MulSV(-g,this.m_uA,box2d.b2PulleyJoint.prototype.SolveVelocityConstraints.s_PA);g=box2d.b2MulSV(-this.m_ratio*g,this.m_uB,box2d.b2PulleyJoint.prototype.SolveVelocityConstraints.s_PB);b.SelfMulAdd(this.m_invMassA,f);c+=this.m_invIA*box2d.b2CrossVV(this.m_rA,f);e.SelfMulAdd(this.m_invMassB,g);d+=this.m_invIB*box2d.b2CrossVV(this.m_rB,g);a.velocities[this.m_indexA].w=c;a.velocities[this.m_indexB].w=d};goog.exportProperty(box2d.b2PulleyJoint.prototype,\"SolveVelocityConstraints\",box2d.b2PulleyJoint.prototype.SolveVelocityConstraints);\nbox2d.b2PulleyJoint.prototype.SolveVelocityConstraints.s_vpA=new box2d.b2Vec2;box2d.b2PulleyJoint.prototype.SolveVelocityConstraints.s_vpB=new box2d.b2Vec2;box2d.b2PulleyJoint.prototype.SolveVelocityConstraints.s_PA=new box2d.b2Vec2;box2d.b2PulleyJoint.prototype.SolveVelocityConstraints.s_PB=new box2d.b2Vec2;\nbox2d.b2PulleyJoint.prototype.SolvePositionConstraints=function(a){var b=a.positions[this.m_indexA].c,c=a.positions[this.m_indexA].a,e=a.positions[this.m_indexB].c,d=a.positions[this.m_indexB].a,f=this.m_qA.SetAngleRadians(c),g=this.m_qB.SetAngleRadians(d);box2d.b2SubVV(this.m_localAnchorA,this.m_localCenterA,this.m_lalcA);f=box2d.b2MulRV(f,this.m_lalcA,this.m_rA);box2d.b2SubVV(this.m_localAnchorB,this.m_localCenterB,this.m_lalcB);var g=box2d.b2MulRV(g,this.m_lalcB,this.m_rB),h=this.m_uA.Copy(b).SelfAdd(f).SelfSub(this.m_groundAnchorA),\nl=this.m_uB.Copy(e).SelfAdd(g).SelfSub(this.m_groundAnchorB),k=h.GetLength(),m=l.GetLength();k>10*box2d.b2_linearSlop?h.SelfMul(1/k):h.SetZero();m>10*box2d.b2_linearSlop?l.SelfMul(1/m):l.SetZero();var n=box2d.b2CrossVV(f,h),p=box2d.b2CrossVV(g,l),n=this.m_invMassA+this.m_invIA*n*n+this.m_ratio*this.m_ratio*(this.m_invMassB+this.m_invIB*p*p);0<n&&(n=1/n);m=this.m_constant-k-this.m_ratio*m;k=box2d.b2Abs(m);m*=-n;h=box2d.b2MulSV(-m,h,box2d.b2PulleyJoint.prototype.SolvePositionConstraints.s_PA);l=box2d.b2MulSV(-this.m_ratio*\nm,l,box2d.b2PulleyJoint.prototype.SolvePositionConstraints.s_PB);b.SelfMulAdd(this.m_invMassA,h);c+=this.m_invIA*box2d.b2CrossVV(f,h);e.SelfMulAdd(this.m_invMassB,l);d+=this.m_invIB*box2d.b2CrossVV(g,l);a.positions[this.m_indexA].a=c;a.positions[this.m_indexB].a=d;return k<box2d.b2_linearSlop};goog.exportProperty(box2d.b2PulleyJoint.prototype,\"SolvePositionConstraints\",box2d.b2PulleyJoint.prototype.SolvePositionConstraints);box2d.b2PulleyJoint.prototype.SolvePositionConstraints.s_PA=new box2d.b2Vec2;\nbox2d.b2PulleyJoint.prototype.SolvePositionConstraints.s_PB=new box2d.b2Vec2;box2d.b2PulleyJoint.prototype.GetAnchorA=function(a){return this.m_bodyA.GetWorldPoint(this.m_localAnchorA,a)};goog.exportProperty(box2d.b2PulleyJoint.prototype,\"GetAnchorA\",box2d.b2PulleyJoint.prototype.GetAnchorA);box2d.b2PulleyJoint.prototype.GetAnchorB=function(a){return this.m_bodyB.GetWorldPoint(this.m_localAnchorB,a)};goog.exportProperty(box2d.b2PulleyJoint.prototype,\"GetAnchorB\",box2d.b2PulleyJoint.prototype.GetAnchorB);\nbox2d.b2PulleyJoint.prototype.GetReactionForce=function(a,b){return b.SetXY(a*this.m_impulse*this.m_uB.x,a*this.m_impulse*this.m_uB.y)};goog.exportProperty(box2d.b2PulleyJoint.prototype,\"GetReactionForce\",box2d.b2PulleyJoint.prototype.GetReactionForce);box2d.b2PulleyJoint.prototype.GetReactionTorque=function(a){return 0};goog.exportProperty(box2d.b2PulleyJoint.prototype,\"GetReactionTorque\",box2d.b2PulleyJoint.prototype.GetReactionTorque);box2d.b2PulleyJoint.prototype.GetGroundAnchorA=function(a){return a.Copy(this.m_groundAnchorA)};\ngoog.exportProperty(box2d.b2PulleyJoint.prototype,\"GetGroundAnchorA\",box2d.b2PulleyJoint.prototype.GetGroundAnchorA);box2d.b2PulleyJoint.prototype.GetGroundAnchorB=function(a){return a.Copy(this.m_groundAnchorB)};goog.exportProperty(box2d.b2PulleyJoint.prototype,\"GetGroundAnchorB\",box2d.b2PulleyJoint.prototype.GetGroundAnchorB);box2d.b2PulleyJoint.prototype.GetLengthA=function(){return this.m_lengthA};goog.exportProperty(box2d.b2PulleyJoint.prototype,\"GetLengthA\",box2d.b2PulleyJoint.prototype.GetLengthA);\nbox2d.b2PulleyJoint.prototype.GetLengthB=function(){return this.m_lengthB};goog.exportProperty(box2d.b2PulleyJoint.prototype,\"GetLengthB\",box2d.b2PulleyJoint.prototype.GetLengthB);box2d.b2PulleyJoint.prototype.GetRatio=function(){return this.m_ratio};goog.exportProperty(box2d.b2PulleyJoint.prototype,\"GetRatio\",box2d.b2PulleyJoint.prototype.GetRatio);\nbox2d.b2PulleyJoint.prototype.GetCurrentLengthA=function(){var a=this.m_bodyA.GetWorldPoint(this.m_localAnchorA,box2d.b2PulleyJoint.prototype.GetCurrentLengthA.s_p);return box2d.b2DistanceVV(a,this.m_groundAnchorA)};goog.exportProperty(box2d.b2PulleyJoint.prototype,\"GetCurrentLengthA\",box2d.b2PulleyJoint.prototype.GetCurrentLengthA);box2d.b2PulleyJoint.prototype.GetCurrentLengthA.s_p=new box2d.b2Vec2;\nbox2d.b2PulleyJoint.prototype.GetCurrentLengthB=function(){var a=this.m_bodyB.GetWorldPoint(this.m_localAnchorB,box2d.b2PulleyJoint.prototype.GetCurrentLengthB.s_p);return box2d.b2DistanceVV(a,this.m_groundAnchorB)};goog.exportProperty(box2d.b2PulleyJoint.prototype,\"GetCurrentLengthB\",box2d.b2PulleyJoint.prototype.GetCurrentLengthB);box2d.b2PulleyJoint.prototype.GetCurrentLengthB.s_p=new box2d.b2Vec2;\nbox2d.b2PulleyJoint.prototype.Dump=function(){if(box2d.DEBUG){var a=this.m_bodyA.m_islandIndex,b=this.m_bodyB.m_islandIndex;box2d.b2Log(\"  /*box2d.b2PulleyJointDef*/ var jd = new box2d.b2PulleyJointDef();\\n\");box2d.b2Log(\"  jd.bodyA = bodies[%d];\\n\",a);box2d.b2Log(\"  jd.bodyB = bodies[%d];\\n\",b);box2d.b2Log(\"  jd.collideConnected = %s;\\n\",this.m_collideConnected?\"true\":\"false\");box2d.b2Log(\"  jd.groundAnchorA.SetXY(%.15f, %.15f);\\n\",this.m_groundAnchorA.x,this.m_groundAnchorA.y);box2d.b2Log(\"  jd.groundAnchorB.SetXY(%.15f, %.15f);\\n\",\nthis.m_groundAnchorB.x,this.m_groundAnchorB.y);box2d.b2Log(\"  jd.localAnchorA.SetXY(%.15f, %.15f);\\n\",this.m_localAnchorA.x,this.m_localAnchorA.y);box2d.b2Log(\"  jd.localAnchorB.SetXY(%.15f, %.15f);\\n\",this.m_localAnchorB.x,this.m_localAnchorB.y);box2d.b2Log(\"  jd.lengthA = %.15f;\\n\",this.m_lengthA);box2d.b2Log(\"  jd.lengthB = %.15f;\\n\",this.m_lengthB);box2d.b2Log(\"  jd.ratio = %.15f;\\n\",this.m_ratio);box2d.b2Log(\"  joints[%d] = this.m_world.CreateJoint(jd);\\n\",this.m_index)}};\ngoog.exportProperty(box2d.b2PulleyJoint.prototype,\"Dump\",box2d.b2PulleyJoint.prototype.Dump);box2d.b2PulleyJoint.prototype.ShiftOrigin=function(a){this.m_groundAnchorA.SelfSub(a);this.m_groundAnchorB.SelfSub(a)};goog.exportProperty(box2d.b2PulleyJoint.prototype,\"ShiftOrigin\",box2d.b2PulleyJoint.prototype.ShiftOrigin);box2d.b2CircleShape=function(a){box2d.b2Shape.call(this,box2d.b2ShapeType.e_circleShape,a||0);this.m_p=new box2d.b2Vec2};goog.inherits(box2d.b2CircleShape,box2d.b2Shape);goog.exportSymbol(\"box2d.b2CircleShape\",box2d.b2CircleShape);box2d.b2CircleShape.prototype.m_p=null;goog.exportProperty(box2d.b2CircleShape.prototype,\"m_p\",box2d.b2CircleShape.prototype.m_p);box2d.b2CircleShape.prototype.Clone=function(){return(new box2d.b2CircleShape).Copy(this)};\ngoog.exportProperty(box2d.b2CircleShape.prototype,\"Clone\",box2d.b2CircleShape.prototype.Clone);box2d.b2CircleShape.prototype.Copy=function(a){box2d.b2CircleShape.superClass_.Copy.call(this,a);box2d.ENABLE_ASSERTS&&box2d.b2Assert(a instanceof box2d.b2CircleShape);this.m_p.Copy(a.m_p);return this};goog.exportProperty(box2d.b2CircleShape.prototype,\"Copy\",box2d.b2CircleShape.prototype.Copy);box2d.b2CircleShape.prototype.GetChildCount=function(){return 1};\ngoog.exportProperty(box2d.b2CircleShape.prototype,\"GetChildCount\",box2d.b2CircleShape.prototype.GetChildCount);box2d.b2CircleShape.prototype.TestPoint=function(a,b){var c=box2d.b2MulXV(a,this.m_p,box2d.b2CircleShape.prototype.TestPoint.s_center),c=box2d.b2SubVV(b,c,box2d.b2CircleShape.prototype.TestPoint.s_d);return box2d.b2DotVV(c,c)<=box2d.b2Sq(this.m_radius)};goog.exportProperty(box2d.b2CircleShape.prototype,\"TestPoint\",box2d.b2CircleShape.prototype.TestPoint);\nbox2d.b2CircleShape.prototype.TestPoint.s_center=new box2d.b2Vec2;box2d.b2CircleShape.prototype.TestPoint.s_d=new box2d.b2Vec2;\nbox2d.b2CircleShape.prototype.RayCast=function(a,b,c,e){c=box2d.b2MulXV(c,this.m_p,box2d.b2CircleShape.prototype.RayCast.s_position);c=box2d.b2SubVV(b.p1,c,box2d.b2CircleShape.prototype.RayCast.s_s);var d=box2d.b2DotVV(c,c)-box2d.b2Sq(this.m_radius);e=box2d.b2SubVV(b.p2,b.p1,box2d.b2CircleShape.prototype.RayCast.s_r);var f=box2d.b2DotVV(c,e),g=box2d.b2DotVV(e,e),d=f*f-g*d;if(0>d||g<box2d.b2_epsilon)return!1;f=-(f+box2d.b2Sqrt(d));return 0<=f&&f<=b.maxFraction*g?(f/=g,a.fraction=f,box2d.b2AddVMulSV(c,\nf,e,a.normal).SelfNormalize(),!0):!1};goog.exportProperty(box2d.b2CircleShape.prototype,\"RayCast\",box2d.b2CircleShape.prototype.RayCast);box2d.b2CircleShape.prototype.RayCast.s_position=new box2d.b2Vec2;box2d.b2CircleShape.prototype.RayCast.s_s=new box2d.b2Vec2;box2d.b2CircleShape.prototype.RayCast.s_r=new box2d.b2Vec2;\nbox2d.b2CircleShape.prototype.ComputeAABB=function(a,b,c){b=box2d.b2MulXV(b,this.m_p,box2d.b2CircleShape.prototype.ComputeAABB.s_p);a.lowerBound.SetXY(b.x-this.m_radius,b.y-this.m_radius);a.upperBound.SetXY(b.x+this.m_radius,b.y+this.m_radius)};goog.exportProperty(box2d.b2CircleShape.prototype,\"ComputeAABB\",box2d.b2CircleShape.prototype.ComputeAABB);box2d.b2CircleShape.prototype.ComputeAABB.s_p=new box2d.b2Vec2;\nbox2d.b2CircleShape.prototype.ComputeMass=function(a,b){var c=box2d.b2Sq(this.m_radius);a.mass=b*box2d.b2_pi*c;a.center.Copy(this.m_p);a.I=a.mass*(0.5*c+box2d.b2DotVV(this.m_p,this.m_p))};goog.exportProperty(box2d.b2CircleShape.prototype,\"ComputeMass\",box2d.b2CircleShape.prototype.ComputeMass);box2d.b2CircleShape.prototype.SetupDistanceProxy=function(a,b){a.m_vertices=[1,!0];a.m_vertices[0]=this.m_p;a.m_count=1;a.m_radius=this.m_radius};\nbox2d.b2CircleShape.prototype.ComputeSubmergedArea=function(a,b,c,e){c=box2d.b2MulXV(c,this.m_p,new box2d.b2Vec2);var d=-(box2d.b2DotVV(a,c)-b);if(d<-this.m_radius+box2d.b2_epsilon)return 0;if(d>this.m_radius)return e.Copy(c),box2d.b2_pi*this.m_radius*this.m_radius;b=this.m_radius*this.m_radius;var f=d*d,d=b*(box2d.b2Asin(d/this.m_radius)+box2d.b2_pi/2)+d*box2d.b2Sqrt(b-f);b=-2/3*box2d.b2Pow(b-f,1.5)/d;e.x=c.x+a.x*b;e.y=c.y+a.y*b;return d};\ngoog.exportProperty(box2d.b2CircleShape.prototype,\"ComputeSubmergedArea\",box2d.b2CircleShape.prototype.ComputeSubmergedArea);box2d.b2CircleShape.prototype.Dump=function(){box2d.b2Log(\"    /*box2d.b2CircleShape*/ var shape = new box2d.b2CircleShape();\\n\");box2d.b2Log(\"    shape.m_radius = %.15f;\\n\",this.m_radius);box2d.b2Log(\"    shape.m_p.SetXY(%.15f, %.15f);\\n\",this.m_p.x,this.m_p.y)};goog.exportProperty(box2d.b2CircleShape.prototype,\"Dump\",box2d.b2CircleShape.prototype.Dump);box2d.b2RopeDef=function(){this.vertices=[];this.masses=[];this.gravity=new box2d.b2Vec2};goog.exportSymbol(\"box2d.b2RopeDef\",box2d.b2RopeDef);box2d.b2RopeDef.prototype.vertices=null;box2d.b2RopeDef.prototype.count=0;box2d.b2RopeDef.prototype.masses=null;box2d.b2RopeDef.prototype.gravity=null;box2d.b2RopeDef.prototype.damping=0.1;box2d.b2RopeDef.prototype.k2=0.9;box2d.b2RopeDef.prototype.k3=0.1;box2d.b2Rope=function(){this.m_gravity=new box2d.b2Vec2};goog.exportSymbol(\"box2d.b2Rope\",box2d.b2Rope);\nbox2d.b2Rope.prototype.m_count=0;box2d.b2Rope.prototype.m_ps=null;box2d.b2Rope.prototype.m_p0s=null;box2d.b2Rope.prototype.m_vs=null;box2d.b2Rope.prototype.m_ims=null;box2d.b2Rope.prototype.m_Ls=null;box2d.b2Rope.prototype.m_as=null;box2d.b2Rope.prototype.m_gravity=null;box2d.b2Rope.prototype.m_damping=0;box2d.b2Rope.prototype.m_k2=1;box2d.b2Rope.prototype.m_k3=0.1;box2d.b2Rope.prototype.GetVertexCount=function(){return this.m_count};goog.exportProperty(box2d.b2Rope.prototype,\"GetVertexCount\",box2d.b2Rope.prototype.GetVertexCount);\nbox2d.b2Rope.prototype.GetVertices=function(){return this.m_ps};goog.exportProperty(box2d.b2Rope.prototype,\"GetVertices\",box2d.b2Rope.prototype.GetVertices);\nbox2d.b2Rope.prototype.Initialize=function(a){box2d.ENABLE_ASSERTS&&box2d.b2Assert(3<=a.count);this.m_count=a.count;this.m_ps=box2d.b2Vec2.MakeArray(this.m_count);this.m_p0s=box2d.b2Vec2.MakeArray(this.m_count);this.m_vs=box2d.b2Vec2.MakeArray(this.m_count);this.m_ims=box2d.b2MakeNumberArray(this.m_count);for(var b=0;b<this.m_count;++b){this.m_ps[b].Copy(a.vertices[b]);this.m_p0s[b].Copy(a.vertices[b]);this.m_vs[b].SetZero();var c=a.masses[b];this.m_ims[b]=0<c?1/c:0}var e=this.m_count-1,c=this.m_count-\n2;this.m_Ls=box2d.b2MakeNumberArray(e);this.m_as=box2d.b2MakeNumberArray(c);for(b=0;b<e;++b){var d=this.m_ps[b],f=this.m_ps[b+1];this.m_Ls[b]=box2d.b2DistanceVV(d,f)}for(b=0;b<c;++b)d=this.m_ps[b],f=this.m_ps[b+1],e=this.m_ps[b+2],d=box2d.b2SubVV(f,d,box2d.b2Vec2.s_t0),e=box2d.b2SubVV(e,f,box2d.b2Vec2.s_t1),f=box2d.b2CrossVV(d,e),d=box2d.b2DotVV(d,e),this.m_as[b]=box2d.b2Atan2(f,d);this.m_gravity.Copy(a.gravity);this.m_damping=a.damping;this.m_k2=a.k2;this.m_k3=a.k3};\ngoog.exportProperty(box2d.b2Rope.prototype,\"Initialize\",box2d.b2Rope.prototype.Initialize);\nbox2d.b2Rope.prototype.Step=function(a,b){if(0!==a){for(var c=Math.exp(-a*this.m_damping),e=0;e<this.m_count;++e)this.m_p0s[e].Copy(this.m_ps[e]),0<this.m_ims[e]&&this.m_vs[e].SelfMulAdd(a,this.m_gravity),this.m_vs[e].SelfMul(c),this.m_ps[e].SelfMulAdd(a,this.m_vs[e]);for(e=0;e<b;++e)this.SolveC2(),this.SolveC3(),this.SolveC2();c=1/a;for(e=0;e<this.m_count;++e)box2d.b2MulSV(c,box2d.b2SubVV(this.m_ps[e],this.m_p0s[e],box2d.b2Vec2.s_t0),this.m_vs[e])}};\ngoog.exportProperty(box2d.b2Rope.prototype,\"Step\",box2d.b2Rope.prototype.Step);box2d.b2Rope.prototype.SolveC2=function(){for(var a=this.m_count-1,b=0;b<a;++b){var c=this.m_ps[b],e=this.m_ps[b+1],d=box2d.b2SubVV(e,c,box2d.b2Rope.s_d),f=d.Normalize(),g=this.m_ims[b],h=this.m_ims[b+1];if(0!==g+h){var l=h/(g+h);c.SelfMulSub(g/(g+h)*this.m_k2*(this.m_Ls[b]-f),d);e.SelfMulAdd(this.m_k2*l*(this.m_Ls[b]-f),d)}}};goog.exportProperty(box2d.b2Rope.prototype,\"SolveC2\",box2d.b2Rope.prototype.SolveC2);\nbox2d.b2Rope.s_d=new box2d.b2Vec2;box2d.b2Rope.prototype.SetAngleRadians=function(a){for(var b=this.m_count-2,c=0;c<b;++c)this.m_as[c]=a};goog.exportProperty(box2d.b2Rope.prototype,\"SetAngleRadians\",box2d.b2Rope.prototype.SetAngleRadians);\nbox2d.b2Rope.prototype.SolveC3=function(){for(var a=this.m_count-2,b=0;b<a;++b){var c=this.m_ps[b],e=this.m_ps[b+1],d=this.m_ps[b+2],f=this.m_ims[b],g=this.m_ims[b+1],h=this.m_ims[b+2],l=box2d.b2SubVV(e,c,box2d.b2Rope.s_d1),k=box2d.b2SubVV(d,e,box2d.b2Rope.s_d2),m=l.GetLengthSquared(),n=k.GetLengthSquared();if(0!==m*n){var p=box2d.b2CrossVV(l,k),q=box2d.b2DotVV(l,k),p=box2d.b2Atan2(p,q),l=box2d.b2MulSV(-1/m,l.SelfSkew(),box2d.b2Rope.s_Jd1),m=box2d.b2MulSV(1/n,k.SelfSkew(),box2d.b2Rope.s_Jd2),k=box2d.b2NegV(l,\nbox2d.b2Rope.s_J1),n=box2d.b2SubVV(l,m,box2d.b2Rope.s_J2),l=m,m=f*box2d.b2DotVV(k,k)+g*box2d.b2DotVV(n,n)+h*box2d.b2DotVV(l,l);if(0!==m){m=1/m;for(q=p-this.m_as[b];q>box2d.b2_pi;)p-=2*box2d.b2_pi,q=p-this.m_as[b];for(;q<-box2d.b2_pi;)p+=2*box2d.b2_pi,q=p-this.m_as[b];p=-this.m_k3*m*q;c.SelfMulAdd(f*p,k);e.SelfMulAdd(g*p,n);d.SelfMulAdd(h*p,l)}}}};goog.exportProperty(box2d.b2Rope.prototype,\"SolveC3\",box2d.b2Rope.prototype.SolveC3);box2d.b2Rope.s_d1=new box2d.b2Vec2;box2d.b2Rope.s_d2=new box2d.b2Vec2;\nbox2d.b2Rope.s_Jd1=new box2d.b2Vec2;box2d.b2Rope.s_Jd2=new box2d.b2Vec2;box2d.b2Rope.s_J1=new box2d.b2Vec2;box2d.b2Rope.s_J2=new box2d.b2Vec2;box2d.b2Rope.prototype.Draw=function(a){for(var b=new box2d.b2Color(0.4,0.5,0.7),c=0;c<this.m_count-1;++c)a.DrawSegment(this.m_ps[c],this.m_ps[c+1],b)};goog.exportProperty(box2d.b2Rope.prototype,\"Draw\",box2d.b2Rope.prototype.Draw);box2d.b2WheelJointDef=function(){box2d.b2JointDef.call(this,box2d.b2JointType.e_wheelJoint);this.localAnchorA=new box2d.b2Vec2(0,0);this.localAnchorB=new box2d.b2Vec2(0,0);this.localAxisA=new box2d.b2Vec2(1,0)};goog.inherits(box2d.b2WheelJointDef,box2d.b2JointDef);goog.exportSymbol(\"box2d.b2WheelJointDef\",box2d.b2WheelJointDef);box2d.b2WheelJointDef.prototype.localAnchorA=null;goog.exportProperty(box2d.b2WheelJointDef.prototype,\"localAnchorA\",box2d.b2WheelJointDef.prototype.localAnchorA);\nbox2d.b2WheelJointDef.prototype.localAnchorB=null;goog.exportProperty(box2d.b2WheelJointDef.prototype,\"localAnchorB\",box2d.b2WheelJointDef.prototype.localAnchorB);box2d.b2WheelJointDef.prototype.localAxisA=null;goog.exportProperty(box2d.b2WheelJointDef.prototype,\"localAxisA\",box2d.b2WheelJointDef.prototype.localAxisA);box2d.b2WheelJointDef.prototype.enableMotor=!1;goog.exportProperty(box2d.b2WheelJointDef.prototype,\"enableMotor\",box2d.b2WheelJointDef.prototype.enableMotor);\nbox2d.b2WheelJointDef.prototype.maxMotorTorque=0;goog.exportProperty(box2d.b2WheelJointDef.prototype,\"maxMotorTorque\",box2d.b2WheelJointDef.prototype.maxMotorTorque);box2d.b2WheelJointDef.prototype.motorSpeed=0;goog.exportProperty(box2d.b2WheelJointDef.prototype,\"motorSpeed\",box2d.b2WheelJointDef.prototype.motorSpeed);box2d.b2WheelJointDef.prototype.frequencyHz=2;goog.exportProperty(box2d.b2WheelJointDef.prototype,\"frequencyHz\",box2d.b2WheelJointDef.prototype.frequencyHz);\nbox2d.b2WheelJointDef.prototype.dampingRatio=0.7;goog.exportProperty(box2d.b2WheelJointDef.prototype,\"dampingRatio\",box2d.b2WheelJointDef.prototype.dampingRatio);box2d.b2WheelJointDef.prototype.Initialize=function(a,b,c,e){this.bodyA=a;this.bodyB=b;this.bodyA.GetLocalPoint(c,this.localAnchorA);this.bodyB.GetLocalPoint(c,this.localAnchorB);this.bodyA.GetLocalVector(e,this.localAxisA)};goog.exportProperty(box2d.b2WheelJointDef.prototype,\"Initialize\",box2d.b2WheelJointDef.prototype.Initialize);\nbox2d.b2WheelJoint=function(a){box2d.b2Joint.call(this,a);this.m_frequencyHz=a.frequencyHz;this.m_dampingRatio=a.dampingRatio;this.m_localAnchorA=a.localAnchorA.Clone();this.m_localAnchorB=a.localAnchorB.Clone();this.m_localXAxisA=a.localAxisA.Clone();this.m_localYAxisA=box2d.b2CrossOneV(this.m_localXAxisA,new box2d.b2Vec2);this.m_maxMotorTorque=a.maxMotorTorque;this.m_motorSpeed=a.motorSpeed;this.m_enableMotor=a.enableMotor;this.m_localCenterA=new box2d.b2Vec2;this.m_localCenterB=new box2d.b2Vec2;\nthis.m_ax=new box2d.b2Vec2;this.m_ay=new box2d.b2Vec2;this.m_qA=new box2d.b2Rot;this.m_qB=new box2d.b2Rot;this.m_lalcA=new box2d.b2Vec2;this.m_lalcB=new box2d.b2Vec2;this.m_rA=new box2d.b2Vec2;this.m_rB=new box2d.b2Vec2;this.m_ax.SetZero();this.m_ay.SetZero()};goog.inherits(box2d.b2WheelJoint,box2d.b2Joint);goog.exportSymbol(\"box2d.b2WheelJoint\",box2d.b2WheelJoint);box2d.b2WheelJoint.prototype.m_frequencyHz=0;goog.exportProperty(box2d.b2WheelJoint.prototype,\"m_frequencyHz\",box2d.b2WheelJoint.prototype.m_frequencyHz);\nbox2d.b2WheelJoint.prototype.m_dampingRatio=0;goog.exportProperty(box2d.b2WheelJoint.prototype,\"m_dampingRatio\",box2d.b2WheelJoint.prototype.m_dampingRatio);box2d.b2WheelJoint.prototype.m_localAnchorA=null;goog.exportProperty(box2d.b2WheelJoint.prototype,\"m_localAnchorA\",box2d.b2WheelJoint.prototype.m_localAnchorA);box2d.b2WheelJoint.prototype.m_localAnchorB=null;goog.exportProperty(box2d.b2WheelJoint.prototype,\"m_localAnchorB\",box2d.b2WheelJoint.prototype.m_localAnchorB);\nbox2d.b2WheelJoint.prototype.m_localXAxisA=null;goog.exportProperty(box2d.b2WheelJoint.prototype,\"m_localXAxisA\",box2d.b2WheelJoint.prototype.m_localXAxisA);box2d.b2WheelJoint.prototype.m_localYAxisA=null;goog.exportProperty(box2d.b2WheelJoint.prototype,\"m_localYAxisA\",box2d.b2WheelJoint.prototype.m_localYAxisA);box2d.b2WheelJoint.prototype.m_impulse=0;goog.exportProperty(box2d.b2WheelJoint.prototype,\"m_impulse\",box2d.b2WheelJoint.prototype.m_impulse);box2d.b2WheelJoint.prototype.m_motorImpulse=0;\ngoog.exportProperty(box2d.b2WheelJoint.prototype,\"m_motorImpulse\",box2d.b2WheelJoint.prototype.m_motorImpulse);box2d.b2WheelJoint.prototype.m_springImpulse=0;goog.exportProperty(box2d.b2WheelJoint.prototype,\"m_springImpulse\",box2d.b2WheelJoint.prototype.m_springImpulse);box2d.b2WheelJoint.prototype.m_maxMotorTorque=0;goog.exportProperty(box2d.b2WheelJoint.prototype,\"m_maxMotorTorque\",box2d.b2WheelJoint.prototype.m_maxMotorTorque);box2d.b2WheelJoint.prototype.m_motorSpeed=0;\ngoog.exportProperty(box2d.b2WheelJoint.prototype,\"m_motorSpeed\",box2d.b2WheelJoint.prototype.m_motorSpeed);box2d.b2WheelJoint.prototype.m_enableMotor=!1;goog.exportProperty(box2d.b2WheelJoint.prototype,\"m_enableMotor\",box2d.b2WheelJoint.prototype.m_enableMotor);box2d.b2WheelJoint.prototype.m_indexA=0;goog.exportProperty(box2d.b2WheelJoint.prototype,\"m_indexA\",box2d.b2WheelJoint.prototype.m_indexA);box2d.b2WheelJoint.prototype.m_indexB=0;\ngoog.exportProperty(box2d.b2WheelJoint.prototype,\"m_indexB\",box2d.b2WheelJoint.prototype.m_indexB);box2d.b2WheelJoint.prototype.m_localCenterA=null;goog.exportProperty(box2d.b2WheelJoint.prototype,\"m_localCenterA\",box2d.b2WheelJoint.prototype.m_localCenterA);box2d.b2WheelJoint.prototype.m_localCenterB=null;goog.exportProperty(box2d.b2WheelJoint.prototype,\"m_localCenterB\",box2d.b2WheelJoint.prototype.m_localCenterB);box2d.b2WheelJoint.prototype.m_invMassA=0;\ngoog.exportProperty(box2d.b2WheelJoint.prototype,\"m_invMassA\",box2d.b2WheelJoint.prototype.m_invMassA);box2d.b2WheelJoint.prototype.m_invMassB=0;goog.exportProperty(box2d.b2WheelJoint.prototype,\"m_invMassB\",box2d.b2WheelJoint.prototype.m_invMassB);box2d.b2WheelJoint.prototype.m_invIA=0;goog.exportProperty(box2d.b2WheelJoint.prototype,\"m_invIA\",box2d.b2WheelJoint.prototype.m_invIA);box2d.b2WheelJoint.prototype.m_invIB=0;goog.exportProperty(box2d.b2WheelJoint.prototype,\"m_invIB\",box2d.b2WheelJoint.prototype.m_invIB);\nbox2d.b2WheelJoint.prototype.m_ax=null;goog.exportProperty(box2d.b2WheelJoint.prototype,\"m_ax\",box2d.b2WheelJoint.prototype.m_ax);box2d.b2WheelJoint.prototype.m_ay=null;goog.exportProperty(box2d.b2WheelJoint.prototype,\"m_ay\",box2d.b2WheelJoint.prototype.m_ay);box2d.b2WheelJoint.prototype.m_sAx=0;goog.exportProperty(box2d.b2WheelJoint.prototype,\"m_sAx\",box2d.b2WheelJoint.prototype.m_sAx);box2d.b2WheelJoint.prototype.m_sBx=0;goog.exportProperty(box2d.b2WheelJoint.prototype,\"m_sBx\",box2d.b2WheelJoint.prototype.m_sBx);\nbox2d.b2WheelJoint.prototype.m_sAy=0;goog.exportProperty(box2d.b2WheelJoint.prototype,\"m_sAy\",box2d.b2WheelJoint.prototype.m_sAy);box2d.b2WheelJoint.prototype.m_sBy=0;goog.exportProperty(box2d.b2WheelJoint.prototype,\"m_sBy\",box2d.b2WheelJoint.prototype.m_sBy);box2d.b2WheelJoint.prototype.m_mass=0;goog.exportProperty(box2d.b2WheelJoint.prototype,\"m_mass\",box2d.b2WheelJoint.prototype.m_mass);box2d.b2WheelJoint.prototype.m_motorMass=0;goog.exportProperty(box2d.b2WheelJoint.prototype,\"m_motorMass\",box2d.b2WheelJoint.prototype.m_motorMass);\nbox2d.b2WheelJoint.prototype.m_springMass=0;goog.exportProperty(box2d.b2WheelJoint.prototype,\"m_springMass\",box2d.b2WheelJoint.prototype.m_springMass);box2d.b2WheelJoint.prototype.m_bias=0;goog.exportProperty(box2d.b2WheelJoint.prototype,\"m_bias\",box2d.b2WheelJoint.prototype.m_bias);box2d.b2WheelJoint.prototype.m_gamma=0;goog.exportProperty(box2d.b2WheelJoint.prototype,\"m_gamma\",box2d.b2WheelJoint.prototype.m_gamma);box2d.b2WheelJoint.prototype.m_qA=null;\ngoog.exportProperty(box2d.b2WheelJoint.prototype,\"m_qA\",box2d.b2WheelJoint.prototype.m_qA);box2d.b2WheelJoint.prototype.m_qB=null;goog.exportProperty(box2d.b2WheelJoint.prototype,\"m_qB\",box2d.b2WheelJoint.prototype.m_qB);box2d.b2WheelJoint.prototype.m_lalcA=null;goog.exportProperty(box2d.b2WheelJoint.prototype,\"m_lalcA\",box2d.b2WheelJoint.prototype.m_lalcA);box2d.b2WheelJoint.prototype.m_lalcB=null;goog.exportProperty(box2d.b2WheelJoint.prototype,\"m_lalcB\",box2d.b2WheelJoint.prototype.m_lalcB);\nbox2d.b2WheelJoint.prototype.m_rA=null;goog.exportProperty(box2d.b2WheelJoint.prototype,\"m_rA\",box2d.b2WheelJoint.prototype.m_rA);box2d.b2WheelJoint.prototype.m_rB=null;goog.exportProperty(box2d.b2WheelJoint.prototype,\"m_rB\",box2d.b2WheelJoint.prototype.m_rB);box2d.b2WheelJoint.prototype.GetMotorSpeed=function(){return this.m_motorSpeed};goog.exportProperty(box2d.b2WheelJoint.prototype,\"GetMotorSpeed\",box2d.b2WheelJoint.prototype.GetMotorSpeed);box2d.b2WheelJoint.prototype.GetMaxMotorTorque=function(){return this.m_maxMotorTorque};\ngoog.exportProperty(box2d.b2WheelJoint.prototype,\"GetMaxMotorTorque\",box2d.b2WheelJoint.prototype.GetMaxMotorTorque);box2d.b2WheelJoint.prototype.SetSpringFrequencyHz=function(a){this.m_frequencyHz=a};goog.exportProperty(box2d.b2WheelJoint.prototype,\"SetSpringFrequencyHz\",box2d.b2WheelJoint.prototype.SetSpringFrequencyHz);box2d.b2WheelJoint.prototype.GetSpringFrequencyHz=function(){return this.m_frequencyHz};goog.exportProperty(box2d.b2WheelJoint.prototype,\"GetSpringFrequencyHz\",box2d.b2WheelJoint.prototype.GetSpringFrequencyHz);\nbox2d.b2WheelJoint.prototype.SetSpringDampingRatio=function(a){this.m_dampingRatio=a};goog.exportProperty(box2d.b2WheelJoint.prototype,\"SetSpringDampingRatio\",box2d.b2WheelJoint.prototype.SetSpringDampingRatio);box2d.b2WheelJoint.prototype.GetSpringDampingRatio=function(){return this.m_dampingRatio};goog.exportProperty(box2d.b2WheelJoint.prototype,\"GetSpringDampingRatio\",box2d.b2WheelJoint.prototype.GetSpringDampingRatio);\nbox2d.b2WheelJoint.prototype.InitVelocityConstraints=function(a){this.m_indexA=this.m_bodyA.m_islandIndex;this.m_indexB=this.m_bodyB.m_islandIndex;this.m_localCenterA.Copy(this.m_bodyA.m_sweep.localCenter);this.m_localCenterB.Copy(this.m_bodyB.m_sweep.localCenter);this.m_invMassA=this.m_bodyA.m_invMass;this.m_invMassB=this.m_bodyB.m_invMass;this.m_invIA=this.m_bodyA.m_invI;this.m_invIB=this.m_bodyB.m_invI;var b=this.m_invMassA,c=this.m_invMassB,e=this.m_invIA,d=this.m_invIB,f=a.positions[this.m_indexA].c,\ng=a.velocities[this.m_indexA].v,h=a.velocities[this.m_indexA].w,l=a.positions[this.m_indexB].c,k=a.positions[this.m_indexB].a,m=a.velocities[this.m_indexB].v,n=a.velocities[this.m_indexB].w,p=this.m_qA.SetAngleRadians(a.positions[this.m_indexA].a),q=this.m_qB.SetAngleRadians(k);box2d.b2SubVV(this.m_localAnchorA,this.m_localCenterA,this.m_lalcA);k=box2d.b2MulRV(p,this.m_lalcA,this.m_rA);box2d.b2SubVV(this.m_localAnchorB,this.m_localCenterB,this.m_lalcB);q=box2d.b2MulRV(q,this.m_lalcB,this.m_rB);f=\nbox2d.b2SubVV(box2d.b2AddVV(l,q,box2d.b2Vec2.s_t0),box2d.b2AddVV(f,k,box2d.b2Vec2.s_t1),box2d.b2WheelJoint.prototype.InitVelocityConstraints.s_d);box2d.b2MulRV(p,this.m_localYAxisA,this.m_ay);this.m_sAy=box2d.b2CrossVV(box2d.b2AddVV(f,k,box2d.b2Vec2.s_t0),this.m_ay);this.m_sBy=box2d.b2CrossVV(q,this.m_ay);this.m_mass=b+c+e*this.m_sAy*this.m_sAy+d*this.m_sBy*this.m_sBy;0<this.m_mass&&(this.m_mass=1/this.m_mass);this.m_gamma=this.m_bias=this.m_springMass=0;0<this.m_frequencyHz?(box2d.b2MulRV(p,this.m_localXAxisA,\nthis.m_ax),this.m_sAx=box2d.b2CrossVV(box2d.b2AddVV(f,k,box2d.b2Vec2.s_t0),this.m_ax),this.m_sBx=box2d.b2CrossVV(q,this.m_ax),b=b+c+e*this.m_sAx*this.m_sAx+d*this.m_sBx*this.m_sBx,0<b&&(this.m_springMass=1/b,c=box2d.b2DotVV(f,this.m_ax),p=2*box2d.b2_pi*this.m_frequencyHz,f=this.m_springMass*p*p,l=a.step.dt,this.m_gamma=l*(2*this.m_springMass*this.m_dampingRatio*p+l*f),0<this.m_gamma&&(this.m_gamma=1/this.m_gamma),this.m_bias=c*l*f*this.m_gamma,this.m_springMass=b+this.m_gamma,0<this.m_springMass&&\n(this.m_springMass=1/this.m_springMass))):this.m_springImpulse=0;this.m_enableMotor?(this.m_motorMass=e+d,0<this.m_motorMass&&(this.m_motorMass=1/this.m_motorMass)):this.m_motorImpulse=this.m_motorMass=0;a.step.warmStarting?(this.m_impulse*=a.step.dtRatio,this.m_springImpulse*=a.step.dtRatio,this.m_motorImpulse*=a.step.dtRatio,e=box2d.b2AddVV(box2d.b2MulSV(this.m_impulse,this.m_ay,box2d.b2Vec2.s_t0),box2d.b2MulSV(this.m_springImpulse,this.m_ax,box2d.b2Vec2.s_t1),box2d.b2WheelJoint.prototype.InitVelocityConstraints.s_P),\nd=this.m_impulse*this.m_sAy+this.m_springImpulse*this.m_sAx+this.m_motorImpulse,b=this.m_impulse*this.m_sBy+this.m_springImpulse*this.m_sBx+this.m_motorImpulse,g.SelfMulSub(this.m_invMassA,e),h-=this.m_invIA*d,m.SelfMulAdd(this.m_invMassB,e),n+=this.m_invIB*b):this.m_motorImpulse=this.m_springImpulse=this.m_impulse=0;a.velocities[this.m_indexA].w=h;a.velocities[this.m_indexB].w=n};goog.exportProperty(box2d.b2WheelJoint.prototype,\"InitVelocityConstraints\",box2d.b2WheelJoint.prototype.InitVelocityConstraints);\nbox2d.b2WheelJoint.prototype.InitVelocityConstraints.s_d=new box2d.b2Vec2;box2d.b2WheelJoint.prototype.InitVelocityConstraints.s_P=new box2d.b2Vec2;\nbox2d.b2WheelJoint.prototype.SolveVelocityConstraints=function(a){var b=this.m_invMassA,c=this.m_invMassB,e=this.m_invIA,d=this.m_invIB,f=a.velocities[this.m_indexA].v,g=a.velocities[this.m_indexA].w,h=a.velocities[this.m_indexB].v,l=a.velocities[this.m_indexB].w,k=box2d.b2DotVV(this.m_ax,box2d.b2SubVV(h,f,box2d.b2Vec2.s_t0))+this.m_sBx*l-this.m_sAx*g,k=-this.m_springMass*(k+this.m_bias+this.m_gamma*this.m_springImpulse);this.m_springImpulse+=k;var m=box2d.b2MulSV(k,this.m_ax,box2d.b2WheelJoint.prototype.SolveVelocityConstraints.s_P),\nn=k*this.m_sAx,k=k*this.m_sBx;f.SelfMulSub(b,m);g-=e*n;h.SelfMulAdd(c,m);l+=d*k;k=l-g-this.m_motorSpeed;k*=-this.m_motorMass;m=this.m_motorImpulse;n=a.step.dt*this.m_maxMotorTorque;this.m_motorImpulse=box2d.b2Clamp(this.m_motorImpulse+k,-n,n);k=this.m_motorImpulse-m;g-=e*k;l+=d*k;k=box2d.b2DotVV(this.m_ay,box2d.b2SubVV(h,f,box2d.b2Vec2.s_t0))+this.m_sBy*l-this.m_sAy*g;k*=-this.m_mass;this.m_impulse+=k;m=box2d.b2MulSV(k,this.m_ay,box2d.b2WheelJoint.prototype.SolveVelocityConstraints.s_P);n=k*this.m_sAy;\nk*=this.m_sBy;f.SelfMulSub(b,m);g-=e*n;h.SelfMulAdd(c,m);a.velocities[this.m_indexA].w=g;a.velocities[this.m_indexB].w=l+d*k};goog.exportProperty(box2d.b2WheelJoint.prototype,\"SolveVelocityConstraints\",box2d.b2WheelJoint.prototype.SolveVelocityConstraints);box2d.b2WheelJoint.prototype.SolveVelocityConstraints.s_P=new box2d.b2Vec2;\nbox2d.b2WheelJoint.prototype.SolvePositionConstraints=function(a){var b=a.positions[this.m_indexA].c,c=a.positions[this.m_indexA].a,e=a.positions[this.m_indexB].c,d=a.positions[this.m_indexB].a,f=this.m_qA.SetAngleRadians(c),g=this.m_qB.SetAngleRadians(d);box2d.b2SubVV(this.m_localAnchorA,this.m_localCenterA,this.m_lalcA);var h=box2d.b2MulRV(f,this.m_lalcA,this.m_rA);box2d.b2SubVV(this.m_localAnchorB,this.m_localCenterB,this.m_lalcB);var g=box2d.b2MulRV(g,this.m_lalcB,this.m_rB),l=box2d.b2AddVV(box2d.b2SubVV(e,\nb,box2d.b2Vec2.s_t0),box2d.b2SubVV(g,h,box2d.b2Vec2.s_t1),box2d.b2WheelJoint.prototype.SolvePositionConstraints.s_d),f=box2d.b2MulRV(f,this.m_localYAxisA,this.m_ay),h=box2d.b2CrossVV(box2d.b2AddVV(l,h,box2d.b2Vec2.s_t0),f),g=box2d.b2CrossVV(g,f),l=box2d.b2DotVV(l,this.m_ay),k=this.m_invMassA+this.m_invMassB+this.m_invIA*this.m_sAy*this.m_sAy+this.m_invIB*this.m_sBy*this.m_sBy,k=0!==k?-l/k:0,f=box2d.b2MulSV(k,f,box2d.b2WheelJoint.prototype.SolvePositionConstraints.s_P),h=k*h,g=k*g;b.SelfMulSub(this.m_invMassA,\nf);c-=this.m_invIA*h;e.SelfMulAdd(this.m_invMassB,f);d+=this.m_invIB*g;a.positions[this.m_indexA].a=c;a.positions[this.m_indexB].a=d;return box2d.b2Abs(l)<=box2d.b2_linearSlop};goog.exportProperty(box2d.b2WheelJoint.prototype,\"SolvePositionConstraints\",box2d.b2WheelJoint.prototype.SolvePositionConstraints);box2d.b2WheelJoint.prototype.SolvePositionConstraints.s_d=new box2d.b2Vec2;box2d.b2WheelJoint.prototype.SolvePositionConstraints.s_P=new box2d.b2Vec2;\nbox2d.b2WheelJoint.prototype.GetDefinition=function(a){box2d.ENABLE_ASSERTS&&box2d.b2Assert(!1);return a};goog.exportProperty(box2d.b2WheelJoint.prototype,\"GetDefinition\",box2d.b2WheelJoint.prototype.GetDefinition);box2d.b2WheelJoint.prototype.GetAnchorA=function(a){return this.m_bodyA.GetWorldPoint(this.m_localAnchorA,a)};goog.exportProperty(box2d.b2WheelJoint.prototype,\"GetAnchorA\",box2d.b2WheelJoint.prototype.GetAnchorA);\nbox2d.b2WheelJoint.prototype.GetAnchorB=function(a){return this.m_bodyB.GetWorldPoint(this.m_localAnchorB,a)};goog.exportProperty(box2d.b2WheelJoint.prototype,\"GetAnchorB\",box2d.b2WheelJoint.prototype.GetAnchorB);box2d.b2WheelJoint.prototype.GetReactionForce=function(a,b){b.x=a*(this.m_impulse*this.m_ay.x+this.m_springImpulse*this.m_ax.x);b.y=a*(this.m_impulse*this.m_ay.y+this.m_springImpulse*this.m_ax.y);return b};goog.exportProperty(box2d.b2WheelJoint.prototype,\"GetReactionForce\",box2d.b2WheelJoint.prototype.GetReactionForce);\nbox2d.b2WheelJoint.prototype.GetReactionTorque=function(a){return a*this.m_motorImpulse};goog.exportProperty(box2d.b2WheelJoint.prototype,\"GetReactionTorque\",box2d.b2WheelJoint.prototype.GetReactionTorque);box2d.b2WheelJoint.prototype.GetLocalAnchorA=function(a){return a.Copy(this.m_localAnchorA)};goog.exportProperty(box2d.b2WheelJoint.prototype,\"GetLocalAnchorA\",box2d.b2WheelJoint.prototype.GetLocalAnchorA);box2d.b2WheelJoint.prototype.GetLocalAnchorB=function(a){return a.Copy(this.m_localAnchorB)};\ngoog.exportProperty(box2d.b2WheelJoint.prototype,\"GetLocalAnchorB\",box2d.b2WheelJoint.prototype.GetLocalAnchorB);box2d.b2WheelJoint.prototype.GetLocalAxisA=function(a){return a.Copy(this.m_localXAxisA)};goog.exportProperty(box2d.b2WheelJoint.prototype,\"GetLocalAxisA\",box2d.b2WheelJoint.prototype.GetLocalAxisA);\nbox2d.b2WheelJoint.prototype.GetJointTranslation=function(){var a=this.m_bodyA,b=this.m_bodyB,c=a.GetWorldPoint(this.m_localAnchorA,new box2d.b2Vec2),b=b.GetWorldPoint(this.m_localAnchorB,new box2d.b2Vec2),c=box2d.b2SubVV(b,c,new box2d.b2Vec2),a=a.GetWorldVector(this.m_localXAxisA,new box2d.b2Vec2);return box2d.b2DotVV(c,a)};goog.exportProperty(box2d.b2WheelJoint.prototype,\"GetJointTranslation\",box2d.b2WheelJoint.prototype.GetJointTranslation);\nbox2d.b2WheelJoint.prototype.GetJointSpeed=function(){return this.m_bodyB.m_angularVelocity-this.m_bodyA.m_angularVelocity};goog.exportProperty(box2d.b2WheelJoint.prototype,\"GetJointSpeed\",box2d.b2WheelJoint.prototype.GetJointSpeed);box2d.b2WheelJoint.prototype.IsMotorEnabled=function(){return this.m_enableMotor};goog.exportProperty(box2d.b2WheelJoint.prototype,\"IsMotorEnabled\",box2d.b2WheelJoint.prototype.IsMotorEnabled);\nbox2d.b2WheelJoint.prototype.EnableMotor=function(a){this.m_bodyA.SetAwake(!0);this.m_bodyB.SetAwake(!0);this.m_enableMotor=a};goog.exportProperty(box2d.b2WheelJoint.prototype,\"EnableMotor\",box2d.b2WheelJoint.prototype.EnableMotor);box2d.b2WheelJoint.prototype.SetMotorSpeed=function(a){this.m_bodyA.SetAwake(!0);this.m_bodyB.SetAwake(!0);this.m_motorSpeed=a};goog.exportProperty(box2d.b2WheelJoint.prototype,\"SetMotorSpeed\",box2d.b2WheelJoint.prototype.SetMotorSpeed);\nbox2d.b2WheelJoint.prototype.SetMaxMotorTorque=function(a){this.m_bodyA.SetAwake(!0);this.m_bodyB.SetAwake(!0);this.m_maxMotorTorque=a};goog.exportProperty(box2d.b2WheelJoint.prototype,\"SetMaxMotorTorque\",box2d.b2WheelJoint.prototype.SetMaxMotorTorque);box2d.b2WheelJoint.prototype.GetMotorTorque=function(a){return a*this.m_motorImpulse};goog.exportProperty(box2d.b2WheelJoint.prototype,\"GetMotorTorque\",box2d.b2WheelJoint.prototype.GetMotorTorque);\nbox2d.b2WheelJoint.prototype.Dump=function(){if(box2d.DEBUG){var a=this.m_bodyA.m_islandIndex,b=this.m_bodyB.m_islandIndex;box2d.b2Log(\"  /*box2d.b2WheelJointDef*/ var jd = new box2d.b2WheelJointDef();\\n\");box2d.b2Log(\"  jd.bodyA = bodies[%d];\\n\",a);box2d.b2Log(\"  jd.bodyB = bodies[%d];\\n\",b);box2d.b2Log(\"  jd.collideConnected = %s;\\n\",this.m_collideConnected?\"true\":\"false\");box2d.b2Log(\"  jd.localAnchorA.SetXY(%.15f, %.15f);\\n\",this.m_localAnchorA.x,this.m_localAnchorA.y);box2d.b2Log(\"  jd.localAnchorB.SetXY(%.15f, %.15f);\\n\",\nthis.m_localAnchorB.x,this.m_localAnchorB.y);box2d.b2Log(\"  jd.localAxisA.Set(%.15f, %.15f);\\n\",this.m_localXAxisA.x,this.m_localXAxisA.y);box2d.b2Log(\"  jd.enableMotor = %s;\\n\",this.m_enableMotor?\"true\":\"false\");box2d.b2Log(\"  jd.motorSpeed = %.15f;\\n\",this.m_motorSpeed);box2d.b2Log(\"  jd.maxMotorTorque = %.15f;\\n\",this.m_maxMotorTorque);box2d.b2Log(\"  jd.frequencyHz = %.15f;\\n\",this.m_frequencyHz);box2d.b2Log(\"  jd.dampingRatio = %.15f;\\n\",this.m_dampingRatio);box2d.b2Log(\"  joints[%d] = this.m_world.CreateJoint(jd);\\n\",\nthis.m_index)}};goog.exportProperty(box2d.b2WheelJoint.prototype,\"Dump\",box2d.b2WheelJoint.prototype.Dump);box2d.b2MotorJointDef=function(){box2d.b2JointDef.call(this,box2d.b2JointType.e_motorJoint);this.linearOffset=new box2d.b2Vec2(0,0)};goog.inherits(box2d.b2MotorJointDef,box2d.b2JointDef);goog.exportSymbol(\"box2d.b2MotorJointDef\",box2d.b2MotorJointDef);box2d.b2MotorJointDef.prototype.linearOffset=null;goog.exportProperty(box2d.b2MotorJointDef.prototype,\"linearOffset\",box2d.b2MotorJointDef.prototype.linearOffset);box2d.b2MotorJointDef.prototype.angularOffset=0;\ngoog.exportProperty(box2d.b2MotorJointDef.prototype,\"angularOffset\",box2d.b2MotorJointDef.prototype.angularOffset);box2d.b2MotorJointDef.prototype.maxForce=1;goog.exportProperty(box2d.b2MotorJointDef.prototype,\"maxForce\",box2d.b2MotorJointDef.prototype.maxForce);box2d.b2MotorJointDef.prototype.maxTorque=1;goog.exportProperty(box2d.b2MotorJointDef.prototype,\"maxTorque\",box2d.b2MotorJointDef.prototype.maxTorque);box2d.b2MotorJointDef.prototype.correctionFactor=0.3;\ngoog.exportProperty(box2d.b2MotorJointDef.prototype,\"correctionFactor\",box2d.b2MotorJointDef.prototype.correctionFactor);box2d.b2MotorJointDef.prototype.Initialize=function(a,b){this.bodyA=a;this.bodyB=b;this.bodyA.GetLocalPoint(this.bodyB.GetPosition(),this.linearOffset);var c=this.bodyA.GetAngleRadians();this.angularOffset=this.bodyB.GetAngleRadians()-c};goog.exportProperty(box2d.b2MotorJointDef.prototype,\"Initialize\",box2d.b2MotorJointDef.prototype.Initialize);\nbox2d.b2MotorJoint=function(a){box2d.b2Joint.call(this,a);this.m_linearOffset=a.linearOffset.Clone();this.m_linearImpulse=new box2d.b2Vec2(0,0);this.m_maxForce=a.maxForce;this.m_maxTorque=a.maxTorque;this.m_correctionFactor=a.correctionFactor;this.m_rA=new box2d.b2Vec2(0,0);this.m_rB=new box2d.b2Vec2(0,0);this.m_localCenterA=new box2d.b2Vec2(0,0);this.m_localCenterB=new box2d.b2Vec2(0,0);this.m_linearError=new box2d.b2Vec2(0,0);this.m_linearMass=new box2d.b2Mat22;this.m_qA=new box2d.b2Rot;this.m_qB=\nnew box2d.b2Rot;this.m_K=new box2d.b2Mat22};goog.inherits(box2d.b2MotorJoint,box2d.b2Joint);goog.exportSymbol(\"box2d.b2MotorJoint\",box2d.b2MotorJoint);box2d.b2MotorJoint.prototype.m_linearOffset=null;goog.exportProperty(box2d.b2MotorJoint.prototype,\"m_linearOffset\",box2d.b2MotorJoint.prototype.m_linearOffset);box2d.b2MotorJoint.prototype.m_angularOffset=0;goog.exportProperty(box2d.b2MotorJoint.prototype,\"m_angularOffset\",box2d.b2MotorJoint.prototype.m_angularOffset);\nbox2d.b2MotorJoint.prototype.m_linearImpulse=null;goog.exportProperty(box2d.b2MotorJoint.prototype,\"m_linearImpulse\",box2d.b2MotorJoint.prototype.m_linearImpulse);box2d.b2MotorJoint.prototype.m_angularImpulse=0;goog.exportProperty(box2d.b2MotorJoint.prototype,\"m_angularImpulse\",box2d.b2MotorJoint.prototype.m_angularImpulse);box2d.b2MotorJoint.prototype.m_maxForce=0;goog.exportProperty(box2d.b2MotorJoint.prototype,\"m_maxForce\",box2d.b2MotorJoint.prototype.m_maxForce);\nbox2d.b2MotorJoint.prototype.m_maxTorque=0;goog.exportProperty(box2d.b2MotorJoint.prototype,\"m_maxTorque\",box2d.b2MotorJoint.prototype.m_maxTorque);box2d.b2MotorJoint.prototype.m_correctionFactor=0.3;goog.exportProperty(box2d.b2MotorJoint.prototype,\"m_correctionFactor\",box2d.b2MotorJoint.prototype.m_correctionFactor);box2d.b2MotorJoint.prototype.m_indexA=0;goog.exportProperty(box2d.b2MotorJoint.prototype,\"m_indexA\",box2d.b2MotorJoint.prototype.m_indexA);box2d.b2MotorJoint.prototype.m_indexB=0;\ngoog.exportProperty(box2d.b2MotorJoint.prototype,\"m_indexB\",box2d.b2MotorJoint.prototype.m_indexB);box2d.b2MotorJoint.prototype.m_rA=null;goog.exportProperty(box2d.b2MotorJoint.prototype,\"m_rA\",box2d.b2MotorJoint.prototype.m_rA);box2d.b2MotorJoint.prototype.m_rB=null;goog.exportProperty(box2d.b2MotorJoint.prototype,\"m_rB\",box2d.b2MotorJoint.prototype.m_rB);box2d.b2MotorJoint.prototype.m_localCenterA=null;goog.exportProperty(box2d.b2MotorJoint.prototype,\"m_localCenterA\",box2d.b2MotorJoint.prototype.m_localCenterA);\nbox2d.b2MotorJoint.prototype.m_localCenterB=null;goog.exportProperty(box2d.b2MotorJoint.prototype,\"m_localCenterB\",box2d.b2MotorJoint.prototype.m_localCenterB);box2d.b2MotorJoint.prototype.m_linearError=null;goog.exportProperty(box2d.b2MotorJoint.prototype,\"m_linearError\",box2d.b2MotorJoint.prototype.m_linearError);box2d.b2MotorJoint.prototype.m_angularError=0;goog.exportProperty(box2d.b2MotorJoint.prototype,\"m_angularError\",box2d.b2MotorJoint.prototype.m_angularError);\nbox2d.b2MotorJoint.prototype.m_invMassA=0;goog.exportProperty(box2d.b2MotorJoint.prototype,\"m_invMassA\",box2d.b2MotorJoint.prototype.m_invMassA);box2d.b2MotorJoint.prototype.m_invMassB=0;goog.exportProperty(box2d.b2MotorJoint.prototype,\"m_invMassB\",box2d.b2MotorJoint.prototype.m_invMassB);box2d.b2MotorJoint.prototype.m_invIA=0;goog.exportProperty(box2d.b2MotorJoint.prototype,\"m_invIA\",box2d.b2MotorJoint.prototype.m_invIA);box2d.b2MotorJoint.prototype.m_invIB=0;\ngoog.exportProperty(box2d.b2MotorJoint.prototype,\"m_invIB\",box2d.b2MotorJoint.prototype.m_invIB);box2d.b2MotorJoint.prototype.m_linearMass=null;goog.exportProperty(box2d.b2MotorJoint.prototype,\"m_linearMass\",box2d.b2MotorJoint.prototype.m_linearMass);box2d.b2MotorJoint.prototype.m_angularMass=0;goog.exportProperty(box2d.b2MotorJoint.prototype,\"m_angularMass\",box2d.b2MotorJoint.prototype.m_angularMass);box2d.b2MotorJoint.prototype.m_qA=null;goog.exportProperty(box2d.b2MotorJoint.prototype,\"m_qA\",box2d.b2MotorJoint.prototype.m_qA);\nbox2d.b2MotorJoint.prototype.m_qB=null;goog.exportProperty(box2d.b2MotorJoint.prototype,\"m_qB\",box2d.b2MotorJoint.prototype.m_qB);box2d.b2MotorJoint.prototype.m_K=null;goog.exportProperty(box2d.b2MotorJoint.prototype,\"m_K\",box2d.b2MotorJoint.prototype.m_K);box2d.b2MotorJoint.prototype.GetAnchorA=function(a){return this.m_bodyA.GetPosition(a)};goog.exportProperty(box2d.b2MotorJoint.prototype,\"GetAnchorA\",box2d.b2MotorJoint.prototype.GetAnchorA);box2d.b2MotorJoint.prototype.GetAnchorB=function(a){return this.m_bodyB.GetPosition(a)};\ngoog.exportProperty(box2d.b2MotorJoint.prototype,\"GetAnchorB\",box2d.b2MotorJoint.prototype.GetAnchorB);box2d.b2MotorJoint.prototype.GetReactionForce=function(a,b){return box2d.b2MulSV(a,this.m_linearImpulse,b)};goog.exportProperty(box2d.b2MotorJoint.prototype,\"GetReactionForce\",box2d.b2MotorJoint.prototype.GetReactionForce);box2d.b2MotorJoint.prototype.GetReactionTorque=function(a){return a*this.m_angularImpulse};goog.exportProperty(box2d.b2MotorJoint.prototype,\"GetReactionTorque\",box2d.b2MotorJoint.prototype.GetReactionTorque);\nbox2d.b2MotorJoint.prototype.SetCorrectionFactor=function(a){box2d.ENABLE_ASSERTS&&box2d.b2Assert(box2d.b2IsValid(a)&&0<=a&&1>=a);this._correctionFactor=a};box2d.b2MotorJoint.prototype.GetCorrectionFactor=function(){return this.m_correctionFactor};box2d.b2MotorJoint.prototype.SetLinearOffset=function(a){box2d.b2IsEqualToV(a,this.m_linearOffset)||(this.m_bodyA.SetAwake(!0),this.m_bodyB.SetAwake(!0),this.m_linearOffset.Copy(a))};goog.exportProperty(box2d.b2MotorJoint.prototype,\"SetLinearOffset\",box2d.b2MotorJoint.prototype.SetLinearOffset);\nbox2d.b2MotorJoint.prototype.GetLinearOffset=function(a){return a.Copy(this.m_linearOffset)};goog.exportProperty(box2d.b2MotorJoint.prototype,\"GetLinearOffset\",box2d.b2MotorJoint.prototype.GetLinearOffset);box2d.b2MotorJoint.prototype.SetAngularOffset=function(a){a!==this.m_angularOffset&&(this.m_bodyA.SetAwake(!0),this.m_bodyB.SetAwake(!0),this.m_angularOffset=a)};goog.exportProperty(box2d.b2MotorJoint.prototype,\"SetAngularOffset\",box2d.b2MotorJoint.prototype.SetAngularOffset);\nbox2d.b2MotorJoint.prototype.GetAngularOffset=function(){return this.m_angularOffset};goog.exportProperty(box2d.b2MotorJoint.prototype,\"GetAngularOffset\",box2d.b2MotorJoint.prototype.GetAngularOffset);box2d.b2MotorJoint.prototype.SetMaxForce=function(a){box2d.ENABLE_ASSERTS&&box2d.b2Assert(box2d.b2IsValid(a)&&0<=a);this.m_maxForce=a};goog.exportProperty(box2d.b2MotorJoint.prototype,\"SetMaxForce\",box2d.b2MotorJoint.prototype.SetMaxForce);box2d.b2MotorJoint.prototype.GetMaxForce=function(){return this.m_maxForce};\ngoog.exportProperty(box2d.b2MotorJoint.prototype,\"GetMaxForce\",box2d.b2MotorJoint.prototype.GetMaxForce);box2d.b2MotorJoint.prototype.SetMaxTorque=function(a){box2d.ENABLE_ASSERTS&&box2d.b2Assert(box2d.b2IsValid(a)&&0<=a);this.m_maxTorque=a};goog.exportProperty(box2d.b2MotorJoint.prototype,\"SetMaxTorque\",box2d.b2MotorJoint.prototype.SetMaxTorque);box2d.b2MotorJoint.prototype.GetMaxTorque=function(){return this.m_maxTorque};goog.exportProperty(box2d.b2MotorJoint.prototype,\"GetMaxTorque\",box2d.b2MotorJoint.prototype.GetMaxTorque);\nbox2d.b2MotorJoint.prototype.InitVelocityConstraints=function(a){this.m_indexA=this.m_bodyA.m_islandIndex;this.m_indexB=this.m_bodyB.m_islandIndex;this.m_localCenterA.Copy(this.m_bodyA.m_sweep.localCenter);this.m_localCenterB.Copy(this.m_bodyB.m_sweep.localCenter);this.m_invMassA=this.m_bodyA.m_invMass;this.m_invMassB=this.m_bodyB.m_invMass;this.m_invIA=this.m_bodyA.m_invI;this.m_invIB=this.m_bodyB.m_invI;var b=a.positions[this.m_indexA].c,c=a.positions[this.m_indexA].a,e=a.velocities[this.m_indexA].v,\nd=a.velocities[this.m_indexA].w,f=a.positions[this.m_indexB].c,g=a.positions[this.m_indexB].a,h=a.velocities[this.m_indexB].v,l=a.velocities[this.m_indexB].w,k=this.m_qA.SetAngleRadians(c),m=this.m_qB.SetAngleRadians(g),n=box2d.b2MulRV(k,box2d.b2NegV(this.m_localCenterA,box2d.b2Vec2.s_t0),this.m_rA),m=box2d.b2MulRV(m,box2d.b2NegV(this.m_localCenterB,box2d.b2Vec2.s_t0),this.m_rB),p=this.m_invMassA,q=this.m_invMassB,r=this.m_invIA,t=this.m_invIB,s=this.m_K;s.ex.x=p+q+r*n.y*n.y+t*m.y*m.y;s.ex.y=-r*n.x*\nn.y-t*m.x*m.y;s.ey.x=s.ex.y;s.ey.y=p+q+r*n.x*n.x+t*m.x*m.x;s.GetInverse(this.m_linearMass);this.m_angularMass=r+t;0<this.m_angularMass&&(this.m_angularMass=1/this.m_angularMass);box2d.b2SubVV(box2d.b2SubVV(box2d.b2AddVV(f,m,box2d.b2Vec2.s_t0),box2d.b2AddVV(b,n,box2d.b2Vec2.s_t1),box2d.b2Vec2.s_t2),box2d.b2MulRV(k,this.m_linearOffset,box2d.b2Vec2.s_t3),this.m_linearError);this.m_angularError=g-c-this.m_angularOffset;a.step.warmStarting?(this.m_linearImpulse.SelfMul(a.step.dtRatio),this.m_angularImpulse*=\na.step.dtRatio,b=this.m_linearImpulse,e.SelfMulSub(p,b),d-=r*(box2d.b2CrossVV(n,b)+this.m_angularImpulse),h.SelfMulAdd(q,b),l+=t*(box2d.b2CrossVV(m,b)+this.m_angularImpulse)):(this.m_linearImpulse.SetZero(),this.m_angularImpulse=0);a.velocities[this.m_indexA].w=d;a.velocities[this.m_indexB].w=l};goog.exportProperty(box2d.b2MotorJoint.prototype,\"InitVelocityConstraints\",box2d.b2MotorJoint.prototype.InitVelocityConstraints);\nbox2d.b2MotorJoint.prototype.SolveVelocityConstraints=function(a){var b=a.velocities[this.m_indexA].v,c=a.velocities[this.m_indexA].w,e=a.velocities[this.m_indexB].v,d=a.velocities[this.m_indexB].w,f=this.m_invMassA,g=this.m_invMassB,h=this.m_invIA,l=this.m_invIB,k=a.step.dt,m=a.step.inv_dt,n=d-c+m*this.m_correctionFactor*this.m_angularError,n=-this.m_angularMass*n,p=this.m_angularImpulse,q=k*this.m_maxTorque;this.m_angularImpulse=box2d.b2Clamp(this.m_angularImpulse+n,-q,q);var n=this.m_angularImpulse-\np,c=c-h*n,d=d+l*n,r=this.m_rA,t=this.m_rB,n=box2d.b2AddVV(box2d.b2SubVV(box2d.b2AddVV(e,box2d.b2CrossSV(d,t,box2d.b2Vec2.s_t0),box2d.b2Vec2.s_t0),box2d.b2AddVV(b,box2d.b2CrossSV(c,r,box2d.b2Vec2.s_t1),box2d.b2Vec2.s_t1),box2d.b2Vec2.s_t2),box2d.b2MulSV(m*this.m_correctionFactor,this.m_linearError,box2d.b2Vec2.s_t3),box2d.b2MotorJoint.prototype.SolveVelocityConstraints.s_Cdot),n=box2d.b2MulMV(this.m_linearMass,n,box2d.b2MotorJoint.prototype.SolveVelocityConstraints.s_impulse).SelfNeg(),p=box2d.b2MotorJoint.prototype.SolveVelocityConstraints.s_oldImpulse.Copy(this.m_linearImpulse);\nthis.m_linearImpulse.SelfAdd(n);q=k*this.m_maxForce;this.m_linearImpulse.GetLengthSquared()>q*q&&(this.m_linearImpulse.Normalize(),this.m_linearImpulse.SelfMul(q));box2d.b2SubVV(this.m_linearImpulse,p,n);b.SelfMulSub(f,n);c-=h*box2d.b2CrossVV(r,n);e.SelfMulAdd(g,n);d+=l*box2d.b2CrossVV(t,n);a.velocities[this.m_indexA].w=c;a.velocities[this.m_indexB].w=d};goog.exportProperty(box2d.b2MotorJoint.prototype,\"SolveVelocityConstraints\",box2d.b2MotorJoint.prototype.SolveVelocityConstraints);\nbox2d.b2MotorJoint.prototype.SolveVelocityConstraints.s_Cdot=new box2d.b2Vec2;box2d.b2MotorJoint.prototype.SolveVelocityConstraints.s_impulse=new box2d.b2Vec2;box2d.b2MotorJoint.prototype.SolveVelocityConstraints.s_oldImpulse=new box2d.b2Vec2;box2d.b2MotorJoint.prototype.SolvePositionConstraints=function(a){return!0};goog.exportProperty(box2d.b2MotorJoint.prototype,\"SolvePositionConstraints\",box2d.b2MotorJoint.prototype.SolvePositionConstraints);\nbox2d.b2MotorJoint.prototype.Dump=function(){if(box2d.DEBUG){var a=this.m_bodyA.m_islandIndex,b=this.m_bodyB.m_islandIndex;box2d.b2Log(\"  /*box2d.b2MotorJointDef*/ var jd = new box2d.b2MotorJointDef();\\n\");box2d.b2Log(\"  jd.bodyA = bodies[%d];\\n\",a);box2d.b2Log(\"  jd.bodyB = bodies[%d];\\n\",b);box2d.b2Log(\"  jd.collideConnected = %s;\\n\",this.m_collideConnected?\"true\":\"false\");box2d.b2Log(\"  jd.linearOffset.SetXY(%.15f, %.15f);\\n\",this.m_linearOffset.x,this.m_linearOffset.y);box2d.b2Log(\"  jd.angularOffset = %.15f;\\n\",\nthis.m_angularOffset);box2d.b2Log(\"  jd.maxForce = %.15f;\\n\",this.m_maxForce);box2d.b2Log(\"  jd.maxTorque = %.15f;\\n\",this.m_maxTorque);box2d.b2Log(\"  jd.correctionFactor = %.15f;\\n\",this.m_correctionFactor);box2d.b2Log(\"  joints[%d] = this.m_world.CreateJoint(jd);\\n\",this.m_index)}};goog.exportProperty(box2d.b2MotorJoint.prototype,\"Dump\",box2d.b2MotorJoint.prototype.Dump);\n"
  },
  {
    "path": "lib/convnetjs/convnet-min.js",
    "content": "var convnetjs=convnetjs||{REVISION:\"ALPHA\"};(function(d){var k=false;var e=0;var l=function(){if(k){k=false;return e}var q=2*Math.random()-1;var p=2*Math.random()-1;var s=q*q+p*p;if(s==0||s>1){return l()}var t=Math.sqrt(-2*Math.log(s)/s);e=p*t;k=true;return q*t};var i=function(q,p){return Math.random()*(p-q)+q};var g=function(q,p){return Math.floor(Math.random()*(p-q)+q)};var c=function(q,p){return q+l()*p};var f=function(r){if(typeof(r)===\"undefined\"||isNaN(r)){return[]}if(typeof ArrayBuffer===\"undefined\"){var p=new Array(r);for(var q=0;q<r;q++){p[q]=0}return p}else{return new Float64Array(r)}};var n=function(p,q){for(var r=0,s=p.length;r<s;r++){if(p[r]===q){return true}}return false};var o=function(q){var p=[];for(var r=0,s=q.length;r<s;r++){if(!n(p,q[r])){p.push(q[r])}}return p};var b=function(q){if(q.length===0){return{}}var p=q[0];var s=q[0];var r=0;var u=0;var v=q.length;for(var t=1;t<v;t++){if(q[t]>p){p=q[t];r=t}if(q[t]<s){s=q[t];u=t}}return{maxi:r,maxv:p,mini:u,minv:s,dv:p-s}};var j=function(v){var s=v,r=0,p;var u=[];for(var t=0;t<v;t++){u[t]=t}while(s--){r=Math.floor(Math.random()*(s+1));p=u[s];u[s]=u[r];u[r]=p}return u};var h=function(q,v){var t=i(0,1);var s=0;for(var r=0,u=q.length;r<u;r++){s+=v[r];if(t<s){return q[r]}}};var m=function(s,t,p){if(typeof t===\"string\"){return(typeof s[t]!==\"undefined\")?s[t]:p}else{var q=p;for(var r=0;r<t.length;r++){var u=t[r];if(typeof s[u]!==\"undefined\"){q=s[u]}}return q}};function a(q,p){if(!q){p=p||\"Assertion failed\";if(typeof Error!==\"undefined\"){throw new Error(p)}throw p}}d.randf=i;d.randi=g;d.randn=c;d.zeros=f;d.maxmin=b;d.randperm=j;d.weightedSample=h;d.arrUnique=o;d.arrContains=n;d.getopt=m;d.assert=a})(convnetjs);(function(b){var a=function(k,g,f,j){if(Object.prototype.toString.call(k)===\"[object Array]\"){this.sx=1;this.sy=1;this.depth=k.length;this.w=b.zeros(this.depth);this.dw=b.zeros(this.depth);for(var d=0;d<this.depth;d++){this.w[d]=k[d]}}else{this.sx=k;this.sy=g;this.depth=f;var h=k*g*f;this.w=b.zeros(h);this.dw=b.zeros(h);if(typeof j===\"undefined\"){var e=Math.sqrt(1/(k*g*f));for(var d=0;d<h;d++){this.w[d]=b.randn(0,e)}}else{for(var d=0;d<h;d++){this.w[d]=j}}}};a.prototype={get:function(c,g,f){var e=((this.sx*g)+c)*this.depth+f;return this.w[e]},set:function(c,h,g,f){var e=((this.sx*h)+c)*this.depth+g;this.w[e]=f},add:function(c,h,g,f){var e=((this.sx*h)+c)*this.depth+g;this.w[e]+=f},get_grad:function(c,g,f){var e=((this.sx*g)+c)*this.depth+f;return this.dw[e]},set_grad:function(c,h,g,f){var e=((this.sx*h)+c)*this.depth+g;this.dw[e]=f},add_grad:function(c,h,g,f){var e=((this.sx*h)+c)*this.depth+g;this.dw[e]+=f},cloneAndZero:function(){return new a(this.sx,this.sy,this.depth,0)},clone:function(){var c=new a(this.sx,this.sy,this.depth,0);var e=this.w.length;for(var d=0;d<e;d++){c.w[d]=this.w[d]}return c},addFrom:function(c){for(var d=0;d<this.w.length;d++){this.w[d]+=c.w[d]}},addFromScaled:function(d,c){for(var e=0;e<this.w.length;e++){this.w[e]+=c*d.w[e]}},setConst:function(c){for(var d=0;d<this.w.length;d++){this.w[d]=c}},toJSON:function(){var c={};c.sx=this.sx;c.sy=this.sy;c.depth=this.depth;c.w=this.w;return c},fromJSON:function(d){this.sx=d.sx;this.sy=d.sy;this.depth=d.depth;var e=this.sx*this.sy*this.depth;this.w=b.zeros(e);this.dw=b.zeros(e);for(var c=0;c<e;c++){this.w[c]=d.w[c]}}};b.Vol=a})(convnetjs);(function(c){var a=c.Vol;var b=function(f,h,n,m,g){if(typeof(g)===\"undefined\"){var g=false}if(typeof(n)===\"undefined\"){var n=c.randi(0,f.sx-h)}if(typeof(m)===\"undefined\"){var m=c.randi(0,f.sy-h)}var e;if(h!==f.sx||n!==0||m!==0){e=new a(h,h,f.depth,0);for(var l=0;l<h;l++){for(var k=0;k<h;k++){if(l+n<0||l+n>=f.sx||k+m<0||k+m>=f.sy){continue}for(var j=0;j<f.depth;j++){e.set(l,k,j,f.get(l+n,k+m,j))}}}}else{e=f}if(g){var i=e.cloneAndZero();for(var l=0;l<e.sx;l++){for(var k=0;k<e.sy;k++){for(var j=0;j<e.depth;j++){i.set(l,k,j,e.get(e.sx-l-1,k,j))}}}e=i}return e};var d=function(o,n){if(typeof(n)===\"undefined\"){var n=false}var h=document.createElement(\"canvas\");h.width=o.width;h.height=o.height;var u=h.getContext(\"2d\");try{u.drawImage(o,0,0)}catch(q){if(q.name===\"NS_ERROR_NOT_AVAILABLE\"){return false}else{throw q}}try{var v=u.getImageData(0,0,h.width,h.height)}catch(q){if(q.name===\"IndexSizeError\"){return false}else{throw q}}var g=v.data;var k=o.width;var s=o.height;var t=[];for(var m=0;m<g.length;m++){t.push(g[m]/255-0.5)}var r=new a(k,s,4,0);r.w=t;if(n){var f=new a(k,s,1,0);for(var m=0;m<k;m++){for(var l=0;l<s;l++){f.set(m,l,0,r.get(m,l,0))}}r=f}return r};c.augment=b;c.img_to_vol=d})(convnetjs);(function(c){var a=c.Vol;var d=function(g){var g=g||{};this.out_depth=g.filters;this.sx=g.sx;this.in_depth=g.in_depth;this.in_sx=g.in_sx;this.in_sy=g.in_sy;this.sy=typeof g.sy!==\"undefined\"?g.sy:this.sx;this.stride=typeof g.stride!==\"undefined\"?g.stride:1;this.pad=typeof g.pad!==\"undefined\"?g.pad:0;this.l1_decay_mul=typeof g.l1_decay_mul!==\"undefined\"?g.l1_decay_mul:0;this.l2_decay_mul=typeof g.l2_decay_mul!==\"undefined\"?g.l2_decay_mul:1;this.out_sx=Math.floor((this.in_sx+this.pad*2-this.sx)/this.stride+1);this.out_sy=Math.floor((this.in_sy+this.pad*2-this.sy)/this.stride+1);this.layer_type=\"conv\";var e=typeof g.bias_pref!==\"undefined\"?g.bias_pref:0;this.filters=[];for(var f=0;f<this.out_depth;f++){this.filters.push(new a(this.sx,this.sy,this.in_depth))}this.biases=new a(1,1,this.out_depth,e)};d.prototype={forward:function(h,k){this.in_act=h;var q=new a(this.out_sx|0,this.out_sy|0,this.out_depth|0,0);var w=h.sx|0;var u=h.sy|0;var r=this.stride|0;for(var t=0;t<this.out_depth;t++){var s=this.filters[t];var n=-this.pad|0;var l=-this.pad|0;for(var m=0;m<this.out_sy;l+=r,m++){n=-this.pad|0;for(var o=0;o<this.out_sx;n+=r,o++){var v=0;for(var e=0;e<s.sy;e++){var i=l+e;for(var g=0;g<s.sx;g++){var j=n+g;if(i>=0&&i<u&&j>=0&&j<w){for(var p=0;p<s.depth;p++){v+=s.w[((s.sx*e)+g)*s.depth+p]*h.w[((w*i)+j)*h.depth+p]}}}}v+=this.biases.w[t];q.set(o,m,t,v)}}}this.out_act=q;return this.out_act},backward:function(){var i=this.in_act;i.dw=c.zeros(i.w.length);var w=i.sx|0;var v=i.sy|0;var q=this.stride|0;for(var t=0;t<this.out_depth;t++){var r=this.filters[t];var n=-this.pad|0;var l=-this.pad|0;for(var m=0;m<this.out_sy;l+=q,m++){n=-this.pad|0;for(var o=0;o<this.out_sx;n+=q,o++){var e=this.out_act.get_grad(o,m,t);for(var g=0;g<r.sy;g++){var j=l+g;for(var h=0;h<r.sx;h++){var k=n+h;if(j>=0&&j<v&&k>=0&&k<w){for(var p=0;p<r.depth;p++){var u=((w*j)+k)*i.depth+p;var s=((r.sx*g)+h)*r.depth+p;r.dw[s]+=i.w[u]*e;i.dw[u]+=r.w[s]*e}}}}this.biases.dw[t]+=e}}}},getParamsAndGrads:function(){var e=[];for(var f=0;f<this.out_depth;f++){e.push({params:this.filters[f].w,grads:this.filters[f].dw,l2_decay_mul:this.l2_decay_mul,l1_decay_mul:this.l1_decay_mul})}e.push({params:this.biases.w,grads:this.biases.dw,l1_decay_mul:0,l2_decay_mul:0});return e},toJSON:function(){var f={};f.sx=this.sx;f.sy=this.sy;f.stride=this.stride;f.in_depth=this.in_depth;f.out_depth=this.out_depth;f.out_sx=this.out_sx;f.out_sy=this.out_sy;f.layer_type=this.layer_type;f.l1_decay_mul=this.l1_decay_mul;f.l2_decay_mul=this.l2_decay_mul;f.pad=this.pad;f.filters=[];for(var e=0;e<this.filters.length;e++){f.filters.push(this.filters[e].toJSON())}f.biases=this.biases.toJSON();return f},fromJSON:function(g){this.out_depth=g.out_depth;this.out_sx=g.out_sx;this.out_sy=g.out_sy;this.layer_type=g.layer_type;this.sx=g.sx;this.sy=g.sy;this.stride=g.stride;this.in_depth=g.in_depth;this.filters=[];this.l1_decay_mul=typeof g.l1_decay_mul!==\"undefined\"?g.l1_decay_mul:1;this.l2_decay_mul=typeof g.l2_decay_mul!==\"undefined\"?g.l2_decay_mul:1;this.pad=typeof g.pad!==\"undefined\"?g.pad:0;for(var f=0;f<g.filters.length;f++){var e=new a(0,0,0,0);e.fromJSON(g.filters[f]);this.filters.push(e)}this.biases=new a(0,0,0,0);this.biases.fromJSON(g.biases)}};var b=function(g){var g=g||{};this.out_depth=typeof g.num_neurons!==\"undefined\"?g.num_neurons:g.filters;this.l1_decay_mul=typeof g.l1_decay_mul!==\"undefined\"?g.l1_decay_mul:0;this.l2_decay_mul=typeof g.l2_decay_mul!==\"undefined\"?g.l2_decay_mul:1;this.num_inputs=g.in_sx*g.in_sy*g.in_depth;this.out_sx=1;this.out_sy=1;this.layer_type=\"fc\";var e=typeof g.bias_pref!==\"undefined\"?g.bias_pref:0;this.filters=[];for(var f=0;f<this.out_depth;f++){this.filters.push(new a(1,1,this.num_inputs))}this.biases=new a(1,1,this.out_depth,e)};b.prototype={forward:function(h,l){this.in_act=h;var f=new a(1,1,this.out_depth,0);var k=h.w;for(var j=0;j<this.out_depth;j++){var g=0;var e=this.filters[j].w;for(var m=0;m<this.num_inputs;m++){g+=k[m]*e[m]}g+=this.biases.w[j];f.w[j]=g}this.out_act=f;return this.out_act},backward:function(){var e=this.in_act;e.dw=c.zeros(e.w.length);for(var f=0;f<this.out_depth;f++){var h=this.filters[f];var g=this.out_act.dw[f];for(var j=0;j<this.num_inputs;j++){e.dw[j]+=h.w[j]*g;h.dw[j]+=e.w[j]*g}this.biases.dw[f]+=g}},getParamsAndGrads:function(){var e=[];for(var f=0;f<this.out_depth;f++){e.push({params:this.filters[f].w,grads:this.filters[f].dw,l1_decay_mul:this.l1_decay_mul,l2_decay_mul:this.l2_decay_mul})}e.push({params:this.biases.w,grads:this.biases.dw,l1_decay_mul:0,l2_decay_mul:0});return e},toJSON:function(){var f={};f.out_depth=this.out_depth;f.out_sx=this.out_sx;f.out_sy=this.out_sy;f.layer_type=this.layer_type;f.num_inputs=this.num_inputs;f.l1_decay_mul=this.l1_decay_mul;f.l2_decay_mul=this.l2_decay_mul;f.filters=[];for(var e=0;e<this.filters.length;e++){f.filters.push(this.filters[e].toJSON())}f.biases=this.biases.toJSON();return f},fromJSON:function(g){this.out_depth=g.out_depth;this.out_sx=g.out_sx;this.out_sy=g.out_sy;this.layer_type=g.layer_type;this.num_inputs=g.num_inputs;this.l1_decay_mul=typeof g.l1_decay_mul!==\"undefined\"?g.l1_decay_mul:1;this.l2_decay_mul=typeof g.l2_decay_mul!==\"undefined\"?g.l2_decay_mul:1;this.filters=[];for(var f=0;f<g.filters.length;f++){var e=new a(0,0,0,0);e.fromJSON(g.filters[f]);this.filters.push(e)}this.biases=new a(0,0,0,0);this.biases.fromJSON(g.biases)}};c.ConvLayer=d;c.FullyConnLayer=b})(convnetjs);(function(c){var a=c.Vol;var b=function(d){var d=d||{};this.sx=d.sx;this.in_depth=d.in_depth;this.in_sx=d.in_sx;this.in_sy=d.in_sy;this.sy=typeof d.sy!==\"undefined\"?d.sy:this.sx;this.stride=typeof d.stride!==\"undefined\"?d.stride:2;this.pad=typeof d.pad!==\"undefined\"?d.pad:0;this.out_depth=this.in_depth;this.out_sx=Math.floor((this.in_sx+this.pad*2-this.sx)/this.stride+1);this.out_sy=Math.floor((this.in_sy+this.pad*2-this.sy)/this.stride+1);this.layer_type=\"pool\";this.switchx=c.zeros(this.out_sx*this.out_sy*this.out_depth);this.switchy=c.zeros(this.out_sx*this.out_sy*this.out_depth)};b.prototype={forward:function(l,u){this.in_act=l;var h=new a(this.out_sx,this.out_sy,this.out_depth,0);var i=0;for(var p=0;p<this.out_depth;p++){var s=-this.pad;var q=-this.pad;for(var e=0;e<this.out_sx;s+=this.stride,e++){q=-this.pad;for(var w=0;w<this.out_sy;q+=this.stride,w++){var r=-99999;var o=-1,k=-1;for(var m=0;m<this.sx;m++){for(var j=0;j<this.sy;j++){var f=q+j;var g=s+m;if(f>=0&&f<l.sy&&g>=0&&g<l.sx){var t=l.get(g,f,p);if(t>r){r=t;o=g;k=f}}}}this.switchx[i]=o;this.switchy[i]=k;i++;h.set(e,w,p,r)}}}this.out_act=h;return this.out_act},backward:function(){var h=this.in_act;h.dw=c.zeros(h.w.length);var f=this.out_act;var g=0;for(var j=0;j<this.out_depth;j++){var l=-this.pad;var k=-this.pad;for(var e=0;e<this.out_sx;l+=this.stride,e++){k=-this.pad;for(var m=0;m<this.out_sy;k+=this.stride,m++){var i=this.out_act.get_grad(e,m,j);h.add_grad(this.switchx[g],this.switchy[g],j,i);g++}}}},getParamsAndGrads:function(){return[]},toJSON:function(){var d={};d.sx=this.sx;d.sy=this.sy;d.stride=this.stride;d.in_depth=this.in_depth;d.out_depth=this.out_depth;d.out_sx=this.out_sx;d.out_sy=this.out_sy;d.layer_type=this.layer_type;d.pad=this.pad;return d},fromJSON:function(d){this.out_depth=d.out_depth;this.out_sx=d.out_sx;this.out_sy=d.out_sy;this.layer_type=d.layer_type;this.sx=d.sx;this.sy=d.sy;this.stride=d.stride;this.in_depth=d.in_depth;this.pad=typeof d.pad!==\"undefined\"?d.pad:0;this.switchx=c.zeros(this.out_sx*this.out_sy*this.out_depth);this.switchy=c.zeros(this.out_sx*this.out_sy*this.out_depth)}};c.PoolLayer=b})(convnetjs);(function(c){var a=c.Vol;var d=c.getopt;var b=function(e){var e=e||{};this.out_depth=d(e,[\"out_depth\",\"depth\"],0);this.out_sx=d(e,[\"out_sx\",\"sx\",\"width\"],1);this.out_sy=d(e,[\"out_sy\",\"sy\",\"height\"],1);this.layer_type=\"input\"};b.prototype={forward:function(e,f){this.in_act=e;this.out_act=e;return this.out_act},backward:function(){},getParamsAndGrads:function(){return[]},toJSON:function(){var e={};e.out_depth=this.out_depth;e.out_sx=this.out_sx;e.out_sy=this.out_sy;e.layer_type=this.layer_type;return e},fromJSON:function(e){this.out_depth=e.out_depth;this.out_sx=e.out_sx;this.out_sy=e.out_sy;this.layer_type=e.layer_type}};c.InputLayer=b})(convnetjs);(function(e){var a=e.Vol;var c=function(f){var f=f||{};this.num_inputs=f.in_sx*f.in_sy*f.in_depth;this.out_depth=this.num_inputs;this.out_sx=1;this.out_sy=1;this.layer_type=\"softmax\"};c.prototype={forward:function(h,o){this.in_act=h;var f=new a(1,1,this.out_depth,0);var j=h.w;var k=h.w[0];for(var l=1;l<this.out_depth;l++){if(j[l]>k){k=j[l]}}var n=e.zeros(this.out_depth);var g=0;for(var l=0;l<this.out_depth;l++){var m=Math.exp(j[l]-k);g+=m;n[l]=m}for(var l=0;l<this.out_depth;l++){n[l]/=g;f.w[l]=n[l]}this.es=n;this.out_act=f;return this.out_act},backward:function(k){var f=this.in_act;f.dw=e.zeros(f.w.length);for(var h=0;h<this.out_depth;h++){var g=h===k?1:0;var j=-(g-this.es[h]);f.dw[h]=j}return -Math.log(this.es[k])},getParamsAndGrads:function(){return[]},toJSON:function(){var f={};f.out_depth=this.out_depth;f.out_sx=this.out_sx;f.out_sy=this.out_sy;f.layer_type=this.layer_type;f.num_inputs=this.num_inputs;return f},fromJSON:function(f){this.out_depth=f.out_depth;this.out_sx=f.out_sx;this.out_sy=f.out_sy;this.layer_type=f.layer_type;this.num_inputs=f.num_inputs}};var d=function(f){var f=f||{};this.num_inputs=f.in_sx*f.in_sy*f.in_depth;this.out_depth=this.num_inputs;this.out_sx=1;this.out_sy=1;this.layer_type=\"regression\"};d.prototype={forward:function(f,g){this.in_act=f;this.out_act=f;return f},backward:function(l){var f=this.in_act;f.dw=e.zeros(f.w.length);var k=0;if(l instanceof Array||l instanceof Float64Array){for(var j=0;j<this.out_depth;j++){var g=f.w[j]-l[j];f.dw[j]=g;k+=0.5*g*g}}else{if(typeof l===\"number\"){var g=f.w[0]-l;f.dw[0]=g;k+=0.5*g*g}else{var j=l.dim;var h=l.val;var g=f.w[j]-h;f.dw[j]=g;k+=0.5*g*g}}return k},getParamsAndGrads:function(){return[]},toJSON:function(){var f={};f.out_depth=this.out_depth;f.out_sx=this.out_sx;f.out_sy=this.out_sy;f.layer_type=this.layer_type;f.num_inputs=this.num_inputs;return f},fromJSON:function(f){this.out_depth=f.out_depth;this.out_sx=f.out_sx;this.out_sy=f.out_sy;this.layer_type=f.layer_type;this.num_inputs=f.num_inputs}};var b=function(f){var f=f||{};this.num_inputs=f.in_sx*f.in_sy*f.in_depth;this.out_depth=this.num_inputs;this.out_sx=1;this.out_sy=1;this.layer_type=\"svm\"};b.prototype={forward:function(f,g){this.in_act=f;this.out_act=f;return f},backward:function(m){var g=this.in_act;g.dw=e.zeros(g.w.length);var f=g.w[m];var k=1;var j=0;for(var h=0;h<this.out_depth;h++){if(m===h){continue}var l=-f+g.w[h]+k;if(l>0){g.dw[h]+=1;g.dw[m]-=1;j+=l}}return j},getParamsAndGrads:function(){return[]},toJSON:function(){var f={};f.out_depth=this.out_depth;f.out_sx=this.out_sx;f.out_sy=this.out_sy;f.layer_type=this.layer_type;f.num_inputs=this.num_inputs;return f},fromJSON:function(f){this.out_depth=f.out_depth;this.out_sx=f.out_sx;this.out_sy=f.out_sy;this.layer_type=f.layer_type;this.num_inputs=f.num_inputs}};e.RegressionLayer=d;e.SoftmaxLayer=c;e.SVMLayer=b})(convnetjs);(function(d){var a=d.Vol;var e=function(h){var h=h||{};this.out_sx=h.in_sx;this.out_sy=h.in_sy;this.out_depth=h.in_depth;this.layer_type=\"relu\"};e.prototype={forward:function(j,l){this.in_act=j;var h=j.clone();var m=j.w.length;var n=h.w;for(var k=0;k<m;k++){if(n[k]<0){n[k]=0}}this.out_act=h;return this.out_act},backward:function(){var j=this.in_act;var h=this.out_act;var l=j.w.length;j.dw=d.zeros(l);for(var k=0;k<l;k++){if(h.w[k]<=0){j.dw[k]=0}else{j.dw[k]=h.dw[k]}}},getParamsAndGrads:function(){return[]},toJSON:function(){var h={};h.out_depth=this.out_depth;h.out_sx=this.out_sx;h.out_sy=this.out_sy;h.layer_type=this.layer_type;return h},fromJSON:function(h){this.out_depth=h.out_depth;this.out_sx=h.out_sx;this.out_sy=h.out_sy;this.layer_type=h.layer_type}};var g=function(h){var h=h||{};this.out_sx=h.in_sx;this.out_sy=h.in_sy;this.out_depth=h.in_depth;this.layer_type=\"sigmoid\"};g.prototype={forward:function(j,m){this.in_act=j;var h=j.cloneAndZero();var n=j.w.length;var o=h.w;var l=j.w;for(var k=0;k<n;k++){o[k]=1/(1+Math.exp(-l[k]))}this.out_act=h;return this.out_act},backward:function(){var j=this.in_act;var h=this.out_act;var m=j.w.length;j.dw=d.zeros(m);for(var k=0;k<m;k++){var l=h.w[k];j.dw[k]=l*(1-l)*h.dw[k]}},getParamsAndGrads:function(){return[]},toJSON:function(){var h={};h.out_depth=this.out_depth;h.out_sx=this.out_sx;h.out_sy=this.out_sy;h.layer_type=this.layer_type;return h},fromJSON:function(h){this.out_depth=h.out_depth;this.out_sx=h.out_sx;this.out_sy=h.out_sy;this.layer_type=h.layer_type}};var f=function(h){var h=h||{};this.group_size=typeof h.group_size!==\"undefined\"?h.group_size:2;this.out_sx=h.in_sx;this.out_sy=h.in_sy;this.out_depth=Math.floor(h.in_depth/this.group_size);this.layer_type=\"maxout\";this.switches=d.zeros(this.out_sx*this.out_sy*this.out_depth)};f.prototype={forward:function(l,w){this.in_act=l;var q=this.out_depth;var v=new a(this.out_sx,this.out_sy,this.out_depth,0);if(this.out_sx===1&&this.out_sy===1){for(var p=0;p<q;p++){var m=p*this.group_size;var u=l.w[m];var r=0;for(var o=1;o<this.group_size;o++){var h=l.w[m+o];if(h>u){u=h;r=o}}v.w[p]=u;this.switches[p]=m+r}}else{var k=0;for(var t=0;t<l.sx;t++){for(var s=0;s<l.sy;s++){for(var p=0;p<q;p++){var m=p*this.group_size;var u=l.get(t,s,m);var r=0;for(var o=1;o<this.group_size;o++){var h=l.get(t,s,m+o);if(h>u){u=h;r=o}}v.set(t,s,p,u);this.switches[k]=m+r;k++}}}}this.out_act=v;return this.out_act},backward:function(){var k=this.in_act;var j=this.out_act;var o=this.out_depth;k.dw=d.zeros(k.w.length);if(this.out_sx===1&&this.out_sy===1){for(var l=0;l<o;l++){var m=j.dw[l];k.dw[this.switches[l]]=m}}else{var q=0;for(var h=0;h<j.sx;h++){for(var p=0;p<j.sy;p++){for(var l=0;l<o;l++){var m=j.get_grad(h,p,l);k.set_grad(h,p,this.switches[q],m);q++}}}}},getParamsAndGrads:function(){return[]},toJSON:function(){var h={};h.out_depth=this.out_depth;h.out_sx=this.out_sx;h.out_sy=this.out_sy;h.layer_type=this.layer_type;h.group_size=this.group_size;return h},fromJSON:function(h){this.out_depth=h.out_depth;this.out_sx=h.out_sx;this.out_sy=h.out_sy;this.layer_type=h.layer_type;this.group_size=h.group_size;this.switches=d.zeros(this.group_size)}};function c(h){var i=Math.exp(2*h);return(i-1)/(i+1)}var b=function(h){var h=h||{};this.out_sx=h.in_sx;this.out_sy=h.in_sy;this.out_depth=h.in_depth;this.layer_type=\"tanh\"};b.prototype={forward:function(j,l){this.in_act=j;var h=j.cloneAndZero();var m=j.w.length;for(var k=0;k<m;k++){h.w[k]=c(j.w[k])}this.out_act=h;return this.out_act},backward:function(){var j=this.in_act;var h=this.out_act;var m=j.w.length;j.dw=d.zeros(m);for(var k=0;k<m;k++){var l=h.w[k];j.dw[k]=(1-l*l)*h.dw[k]}},getParamsAndGrads:function(){return[]},toJSON:function(){var h={};h.out_depth=this.out_depth;h.out_sx=this.out_sx;h.out_sy=this.out_sy;h.layer_type=this.layer_type;return h},fromJSON:function(h){this.out_depth=h.out_depth;this.out_sx=h.out_sx;this.out_sy=h.out_sy;this.layer_type=h.layer_type}};d.TanhLayer=b;d.MaxoutLayer=f;d.ReluLayer=e;d.SigmoidLayer=g})(convnetjs);(function(c){var a=c.Vol;var b=function(d){var d=d||{};this.out_sx=d.in_sx;this.out_sy=d.in_sy;this.out_depth=d.in_depth;this.layer_type=\"dropout\";this.drop_prob=typeof d.drop_prob!==\"undefined\"?d.drop_prob:0.5;this.dropped=c.zeros(this.out_sx*this.out_sy*this.out_depth)};b.prototype={forward:function(e,g){this.in_act=e;if(typeof(g)===\"undefined\"){g=false}var d=e.clone();var h=e.w.length;if(g){for(var f=0;f<h;f++){if(Math.random()<this.drop_prob){d.w[f]=0;this.dropped[f]=true}else{this.dropped[f]=false}}}else{for(var f=0;f<h;f++){d.w[f]*=this.drop_prob}}this.out_act=d;return this.out_act},backward:function(){var d=this.in_act;var f=this.out_act;var g=d.w.length;d.dw=c.zeros(g);for(var e=0;e<g;e++){if(!(this.dropped[e])){d.dw[e]=f.dw[e]}}},getParamsAndGrads:function(){return[]},toJSON:function(){var d={};d.out_depth=this.out_depth;d.out_sx=this.out_sx;d.out_sy=this.out_sy;d.layer_type=this.layer_type;d.drop_prob=this.drop_prob;return d},fromJSON:function(d){this.out_depth=d.out_depth;this.out_sx=d.out_sx;this.out_sy=d.out_sy;this.layer_type=d.layer_type;this.drop_prob=d.drop_prob}};c.DropoutLayer=b})(convnetjs);(function(c){var a=c.Vol;var b=function(d){var d=d||{};this.k=d.k;this.n=d.n;this.alpha=d.alpha;this.beta=d.beta;this.out_sx=d.in_sx;this.out_sy=d.in_sy;this.out_depth=d.in_depth;this.layer_type=\"lrn\";if(this.n%2===0){console.log(\"WARNING n should be odd for LRN layer\")}};b.prototype={forward:function(f,p){this.in_act=f;var e=f.cloneAndZero();this.S_cache_=f.cloneAndZero();var k=Math.floor(this.n/2);for(var n=0;n<f.sx;n++){for(var m=0;m<f.sy;m++){for(var h=0;h<f.depth;h++){var l=f.get(n,m,h);var o=0;for(var g=Math.max(0,h-k);g<=Math.min(h+k,f.depth-1);g++){var d=f.get(n,m,g);o+=d*d}o*=this.alpha/this.n;o+=this.k;this.S_cache_.set(n,m,h,o);o=Math.pow(o,this.beta);e.set(n,m,h,l/o)}}}this.out_act=e;return this.out_act},backward:function(){var f=this.in_act;f.dw=c.zeros(f.w.length);var d=this.out_act;var n=Math.floor(this.n/2);for(var r=0;r<f.sx;r++){for(var q=0;q<f.sy;q++){for(var l=0;l<f.depth;l++){var p=this.out_act.get_grad(r,q,l);var k=this.S_cache_.get(r,q,l);var e=Math.pow(k,this.beta);var s=e*e;for(var h=Math.max(0,l-n);h<=Math.min(l+n,f.depth-1);h++){var o=f.get(r,q,h);var m=-o*this.beta*Math.pow(k,this.beta-1)*this.alpha/this.n*2*o;if(h===l){m+=e}m/=s;m*=p;f.add_grad(r,q,h,m)}}}}},getParamsAndGrads:function(){return[]},toJSON:function(){var d={};d.k=this.k;d.n=this.n;d.alpha=this.alpha;d.beta=this.beta;d.out_sx=this.out_sx;d.out_sy=this.out_sy;d.out_depth=this.out_depth;d.layer_type=this.layer_type;return d},fromJSON:function(d){this.k=d.k;this.n=d.n;this.alpha=d.alpha;this.beta=d.beta;this.out_sx=d.out_sx;this.out_sy=d.out_sy;this.out_depth=d.out_depth;this.layer_type=d.layer_type}};c.LocalResponseNormalizationLayer=b})(convnetjs);(function(d){var a=d.Vol;var b=d.assert;var c=function(e){this.layers=[]};c.prototype={makeLayers:function(e){b(e.length>=2,\"Error! At least one input layer and one loss layer are required.\");b(e[0].type===\"input\",\"Error! First layer must be the input layer, to declare size of inputs\");var f=function(){var m=[];for(var l=0;l<e.length;l++){var n=e[l];if(n.type===\"softmax\"||n.type===\"svm\"){m.push({type:\"fc\",num_neurons:n.num_classes})}if(n.type===\"regression\"){m.push({type:\"fc\",num_neurons:n.num_neurons})}if((n.type===\"fc\"||n.type===\"conv\")&&typeof(n.bias_pref)===\"undefined\"){n.bias_pref=0;if(typeof n.activation!==\"undefined\"&&n.activation===\"relu\"){n.bias_pref=0.1}}m.push(n);if(typeof n.activation!==\"undefined\"){if(n.activation===\"relu\"){m.push({type:\"relu\"})}else{if(n.activation===\"sigmoid\"){m.push({type:\"sigmoid\"})}else{if(n.activation===\"tanh\"){m.push({type:\"tanh\"})}else{if(n.activation===\"maxout\"){var k=n.group_size!==\"undefined\"?n.group_size:2;m.push({type:\"maxout\",group_size:k})}else{console.log(\"ERROR unsupported activation \"+n.activation)}}}}}if(typeof n.drop_prob!==\"undefined\"&&n.type!==\"dropout\"){m.push({type:\"dropout\",drop_prob:n.drop_prob})}}return m};e=f(e);this.layers=[];for(var g=0;g<e.length;g++){var j=e[g];if(g>0){var h=this.layers[g-1];j.in_sx=h.out_sx;j.in_sy=h.out_sy;j.in_depth=h.out_depth}switch(j.type){case\"fc\":this.layers.push(new d.FullyConnLayer(j));break;case\"lrn\":this.layers.push(new d.LocalResponseNormalizationLayer(j));break;case\"dropout\":this.layers.push(new d.DropoutLayer(j));break;case\"input\":this.layers.push(new d.InputLayer(j));break;case\"softmax\":this.layers.push(new d.SoftmaxLayer(j));break;case\"regression\":this.layers.push(new d.RegressionLayer(j));break;case\"conv\":this.layers.push(new d.ConvLayer(j));break;case\"pool\":this.layers.push(new d.PoolLayer(j));break;case\"relu\":this.layers.push(new d.ReluLayer(j));break;case\"sigmoid\":this.layers.push(new d.SigmoidLayer(j));break;case\"tanh\":this.layers.push(new d.TanhLayer(j));break;case\"maxout\":this.layers.push(new d.MaxoutLayer(j));break;case\"svm\":this.layers.push(new d.SVMLayer(j));break;default:console.log(\"ERROR: UNRECOGNIZED LAYER TYPE: \"+j.type)}}},forward:function(f,h){if(typeof(h)===\"undefined\"){h=false}var e=this.layers[0].forward(f,h);for(var g=1;g<this.layers.length;g++){e=this.layers[g].forward(e,h)}return e},getCostLoss:function(e,h){this.forward(e,false);var g=this.layers.length;var f=this.layers[g-1].backward(h);return f},backward:function(h){var g=this.layers.length;var f=this.layers[g-1].backward(h);for(var e=g-2;e>=0;e--){this.layers[e].backward()}return f},getParamsAndGrads:function(){var e=[];for(var g=0;g<this.layers.length;g++){var h=this.layers[g].getParamsAndGrads();for(var f=0;f<h.length;f++){e.push(h[f])}}return e},getPrediction:function(){var h=this.layers[this.layers.length-1];b(h.layer_type===\"softmax\",\"getPrediction function assumes softmax as last layer of the net!\");var j=h.out_act.w;var e=j[0];var f=0;for(var g=1;g<j.length;g++){if(j[g]>e){e=j[g];f=g}}return f},toJSON:function(){var f={};f.layers=[];for(var e=0;e<this.layers.length;e++){f.layers.push(this.layers[e].toJSON())}return f},fromJSON:function(j){this.layers=[];for(var h=0;h<j.layers.length;h++){var f=j.layers[h];var g=f.layer_type;var e;if(g===\"input\"){e=new d.InputLayer()}if(g===\"relu\"){e=new d.ReluLayer()}if(g===\"sigmoid\"){e=new d.SigmoidLayer()}if(g===\"tanh\"){e=new d.TanhLayer()}if(g===\"dropout\"){e=new d.DropoutLayer()}if(g===\"conv\"){e=new d.ConvLayer()}if(g===\"pool\"){e=new d.PoolLayer()}if(g===\"lrn\"){e=new d.LocalResponseNormalizationLayer()}if(g===\"softmax\"){e=new d.SoftmaxLayer()}if(g===\"regression\"){e=new d.RegressionLayer()}if(g===\"fc\"){e=new d.FullyConnLayer()}if(g===\"maxout\"){e=new d.MaxoutLayer()}if(g===\"svm\"){e=new d.SVMLayer()}e.fromJSON(f);this.layers.push(e)}}};d.Net=c})(convnetjs);(function(b){var a=b.Vol;var c=function(e,d){this.net=e;var d=d||{};this.learning_rate=typeof d.learning_rate!==\"undefined\"?d.learning_rate:0.01;this.l1_decay=typeof d.l1_decay!==\"undefined\"?d.l1_decay:0;this.l2_decay=typeof d.l2_decay!==\"undefined\"?d.l2_decay:0;this.batch_size=typeof d.batch_size!==\"undefined\"?d.batch_size:1;this.method=typeof d.method!==\"undefined\"?d.method:\"sgd\";this.momentum=typeof d.momentum!==\"undefined\"?d.momentum:0.9;this.ro=typeof d.ro!==\"undefined\"?d.ro:0.95;this.eps=typeof d.eps!==\"undefined\"?d.eps:0.000001;this.k=0;this.gsum=[];this.xsum=[]};c.prototype={train:function(s,r){var h=new Date().getTime();this.net.forward(s,true);var f=new Date().getTime();var q=f-h;var h=new Date().getTime();var A=this.net.backward(r);var k=0;var d=0;var f=new Date().getTime();var G=f-h;this.k++;if(this.k%this.batch_size===0){var e=this.net.getParamsAndGrads();if(this.gsum.length===0&&(this.method!==\"sgd\"||this.momentum>0)){for(var E=0;E<e.length;E++){this.gsum.push(b.zeros(e[E].params.length));if(this.method===\"adadelta\"){this.xsum.push(b.zeros(e[E].params.length))}else{this.xsum.push([])}}}for(var E=0;E<e.length;E++){var H=e[E];var w=H.params;var F=H.grads;var z=typeof H.l2_decay_mul!==\"undefined\"?H.l2_decay_mul:1;var I=typeof H.l1_decay_mul!==\"undefined\"?H.l1_decay_mul:1;var l=this.l2_decay*z;var n=this.l1_decay*I;var u=w.length;for(var B=0;B<u;B++){k+=l*w[B]*w[B]/2;d+=n*Math.abs(w[B]);var D=n*(w[B]>0?1:-1);var o=l*(w[B]);var t=(o+D+F[B])/this.batch_size;var m=this.gsum[E];var C=this.xsum[E];if(this.method===\"adagrad\"){m[B]=m[B]+t*t;var v=-this.learning_rate/Math.sqrt(m[B]+this.eps)*t;w[B]+=v}else{if(this.method===\"windowgrad\"){m[B]=this.ro*m[B]+(1-this.ro)*t*t;var v=-this.learning_rate/Math.sqrt(m[B]+this.eps)*t;w[B]+=v}else{if(this.method===\"adadelta\"){m[B]=this.ro*m[B]+(1-this.ro)*t*t;var v=-Math.sqrt((C[B]+this.eps)/(m[B]+this.eps))*t;C[B]=this.ro*C[B]+(1-this.ro)*v*v;w[B]+=v}else{if(this.method===\"nesterov\"){var v=m[B];m[B]=m[B]*this.momentum+this.learning_rate*t;v=this.momentum*v-(1+this.momentum)*m[B];w[B]+=v}else{if(this.momentum>0){var v=this.momentum*m[B]-this.learning_rate*t;m[B]=v;w[B]+=v}else{w[B]+=-this.learning_rate*t}}}}}F[B]=0}}}return{fwd_time:q,bwd_time:G,l2_decay_loss:k,l1_decay_loss:d,cost_loss:A,softmax_loss:A,loss:A+d+k}}};b.Trainer=c;b.SGDTrainer=c})(convnetjs);(function(c){var e=c.randf;var d=c.randi;var j=c.Net;var g=c.Trainer;var b=c.maxmin;var h=c.randperm;var f=c.weightedSample;var i=c.getopt;var k=c.arrUnique;var a=function(m,n,l){var l=l||{};if(typeof m===\"undefined\"){m=[]}if(typeof n===\"undefined\"){n=[]}this.data=m;this.labels=n;this.train_ratio=i(l,\"train_ratio\",0.7);this.num_folds=i(l,\"num_folds\",10);this.num_candidates=i(l,\"num_candidates\",50);this.num_epochs=i(l,\"num_epochs\",50);this.ensemble_size=i(l,\"ensemble_size\",10);this.batch_size_min=i(l,\"batch_size_min\",10);this.batch_size_max=i(l,\"batch_size_max\",300);this.l2_decay_min=i(l,\"l2_decay_min\",-4);this.l2_decay_max=i(l,\"l2_decay_max\",2);this.learning_rate_min=i(l,\"learning_rate_min\",-4);this.learning_rate_max=i(l,\"learning_rate_max\",0);this.momentum_min=i(l,\"momentum_min\",0.9);this.momentum_max=i(l,\"momentum_max\",0.9);this.neurons_min=i(l,\"neurons_min\",5);this.neurons_max=i(l,\"neurons_max\",30);this.folds=[];this.candidates=[];this.evaluated_candidates=[];this.unique_labels=k(n);this.iter=0;this.foldix=0;this.finish_fold_callback=null;this.finish_batch_callback=null;if(this.data.length>0){this.sampleFolds();this.sampleCandidates()}};a.prototype={sampleFolds:function(){var o=this.data.length;var m=Math.floor(this.train_ratio*o);this.folds=[];for(var l=0;l<this.num_folds;l++){var n=h(o);this.folds.push({train_ix:n.slice(0,m),test_ix:n.slice(m,o)})}},sampleCandidate:function(){var A=this.data[0].w.length;var z=this.unique_labels.length;var s=[];s.push({type:\"input\",out_sx:1,out_sy:1,out_depth:A});var l=f([0,1,2,3],[0.2,0.3,0.3,0.2]);for(var m=0;m<l;m++){var n=d(this.neurons_min,this.neurons_max);var v=[\"tanh\",\"maxout\",\"relu\"][d(0,3)];if(e(0,1)<0.5){var r=Math.random();s.push({type:\"fc\",num_neurons:n,activation:v,drop_prob:r})}else{s.push({type:\"fc\",num_neurons:n,activation:v})}}s.push({type:\"softmax\",num_classes:z});var x=new j();x.makeLayers(s);var C=d(this.batch_size_min,this.batch_size_max);var o=Math.pow(10,e(this.l2_decay_min,this.l2_decay_max));var t=Math.pow(10,e(this.learning_rate_min,this.learning_rate_max));var p=e(this.momentum_min,this.momentum_max);var y=e(0,1);var u;if(y<0.33){u={method:\"adadelta\",batch_size:C,l2_decay:o}}else{if(y<0.66){u={method:\"adagrad\",learning_rate:t,batch_size:C,l2_decay:o}}else{u={method:\"sgd\",learning_rate:t,momentum:p,batch_size:C,l2_decay:o}}}var B=new g(x,u);var w={};w.acc=[];w.accv=0;w.layer_defs=s;w.trainer_def=u;w.net=x;w.trainer=B;return w},sampleCandidates:function(){this.candidates=[];for(var l=0;l<this.num_candidates;l++){var m=this.sampleCandidate();this.candidates.push(m)}},step:function(){this.iter++;var r=this.folds[this.foldix];var p=r.train_ix[d(0,r.train_ix.length)];for(var q=0;q<this.candidates.length;q++){var u=this.data[p];var o=this.labels[p];this.candidates[q].trainer.train(u,o)}var n=this.num_epochs*r.train_ix.length;if(this.iter>=n){var m=this.evalValErrors();for(var q=0;q<this.candidates.length;q++){var s=this.candidates[q];s.acc.push(m[q]);s.accv+=m[q]}this.iter=0;this.foldix++;if(this.finish_fold_callback!==null){this.finish_fold_callback()}if(this.foldix>=this.folds.length){for(var q=0;q<this.candidates.length;q++){this.evaluated_candidates.push(this.candidates[q])}this.evaluated_candidates.sort(function(w,l){return(w.accv/w.acc.length)>(l.accv/l.acc.length)?-1:1});if(this.evaluated_candidates.length>3*this.ensemble_size){this.evaluated_candidates=this.evaluated_candidates.slice(0,3*this.ensemble_size)}if(this.finish_batch_callback!==null){this.finish_batch_callback()}this.sampleCandidates();this.foldix=0}else{for(var q=0;q<this.candidates.length;q++){var s=this.candidates[q];var t=new j();t.makeLayers(s.layer_defs);var v=new g(t,s.trainer_def);s.net=t;s.trainer=v}}}},evalValErrors:function(){var t=[];var r=this.folds[this.foldix];for(var p=0;p<this.candidates.length;p++){var s=this.candidates[p].net;var w=0;for(var m=0;m<r.test_ix.length;m++){var u=this.data[r.test_ix[m]];var o=this.labels[r.test_ix[m]];s.forward(u);var n=s.getPrediction();w+=(n===o?1:0)}w/=r.test_ix.length;t.push(w)}return t},predict_soft:function(q){var o=[];var r=0;if(this.evaluated_candidates.length===0){r=this.candidates.length;o=this.candidates}else{r=Math.min(this.ensemble_size,this.evaluated_candidates.length);o=this.evaluated_candidates}var l,m;for(var p=0;p<r;p++){var t=o[p].net;var u=t.forward(q);if(p===0){l=u;m=u.w.length}else{for(var s=0;s<m;s++){l.w[s]+=u.w[s]}}}for(var s=0;s<m;s++){l.w[s]/=r}return l},predict:function(n){var m=this.predict_soft(n);if(m.w.length!==0){var l=b(m.w);var o=l.maxi}else{var o=-1}return o},toJSON:function(){var l=Math.min(this.ensemble_size,this.evaluated_candidates.length);var n={};n.nets=[];for(var m=0;m<l;m++){n.nets.push(this.evaluated_candidates[m].net.toJSON())}return n},fromJSON:function(m){this.ensemble_size=m.nets.length;this.evaluated_candidates=[];for(var l=0;l<this.ensemble_size;l++){var n=new j();n.fromJSON(m.nets[l]);var o={};o.net=n;this.evaluated_candidates.push(o)}},onFinishFold:function(l){this.finish_fold_callback=l},onFinishBatch:function(l){this.finish_batch_callback=l}};c.MagicNet=a})(convnetjs);(function(a){if(typeof module===\"undefined\"||typeof module.exports===\"undefined\"){window.jsfeat=a}else{module.exports=a}})(convnetjs);"
  },
  {
    "path": "lib/convnetjs/convnet.js",
    "content": "var convnetjs = convnetjs || { REVISION: 'ALPHA' };\n(function(global) {\n  \"use strict\";\n\n  // Random number utilities\n  var return_v = false;\n  var v_val = 0.0;\n  var gaussRandom = function() {\n    if(return_v) { \n      return_v = false;\n      return v_val; \n    }\n    var u = 2*Math.random()-1;\n    var v = 2*Math.random()-1;\n    var r = u*u + v*v;\n    if(r == 0 || r > 1) return gaussRandom();\n    var c = Math.sqrt(-2*Math.log(r)/r);\n    v_val = v*c; // cache this\n    return_v = true;\n    return u*c;\n  }\n  var randf = function(a, b) { return Math.random()*(b-a)+a; }\n  var randi = function(a, b) { return Math.floor(Math.random()*(b-a)+a); }\n  var randn = function(mu, std){ return mu+gaussRandom()*std; }\n\n  // Array utilities\n  var zeros = function(n) {\n    if(typeof(n)==='undefined' || isNaN(n)) { return []; }\n    if(typeof ArrayBuffer === 'undefined') {\n      // lacking browser support\n      var arr = new Array(n);\n      for(var i=0;i<n;i++) { arr[i]= 0; }\n      return arr;\n    } else {\n      return new Float64Array(n);\n    }\n  }\n\n  var arrContains = function(arr, elt) {\n    for(var i=0,n=arr.length;i<n;i++) {\n      if(arr[i]===elt) return true;\n    }\n    return false;\n  }\n\n  var arrUnique = function(arr) {\n    var b = [];\n    for(var i=0,n=arr.length;i<n;i++) {\n      if(!arrContains(b, arr[i])) {\n        b.push(arr[i]);\n      }\n    }\n    return b;\n  }\n\n  // return max and min of a given non-empty array.\n  var maxmin = function(w) {\n    if(w.length === 0) { return {}; } // ... ;s\n    var maxv = w[0];\n    var minv = w[0];\n    var maxi = 0;\n    var mini = 0;\n    var n = w.length;\n    for(var i=1;i<n;i++) {\n      if(w[i] > maxv) { maxv = w[i]; maxi = i; } \n      if(w[i] < minv) { minv = w[i]; mini = i; } \n    }\n    return {maxi: maxi, maxv: maxv, mini: mini, minv: minv, dv:maxv-minv};\n  }\n\n  // create random permutation of numbers, in range [0...n-1]\n  var randperm = function(n) {\n    var i = n,\n        j = 0,\n        temp;\n    var array = [];\n    for(var q=0;q<n;q++)array[q]=q;\n    while (i--) {\n        j = Math.floor(Math.random() * (i+1));\n        temp = array[i];\n        array[i] = array[j];\n        array[j] = temp;\n    }\n    return array;\n  }\n\n  // sample from list lst according to probabilities in list probs\n  // the two lists are of same size, and probs adds up to 1\n  var weightedSample = function(lst, probs) {\n    var p = randf(0, 1.0);\n    var cumprob = 0.0;\n    for(var k=0,n=lst.length;k<n;k++) {\n      cumprob += probs[k];\n      if(p < cumprob) { return lst[k]; }\n    }\n  }\n\n  // syntactic sugar function for getting default parameter values\n  var getopt = function(opt, field_name, default_value) {\n    return typeof opt[field_name] !== 'undefined' ? opt[field_name] : default_value;\n  }\n\n  global.randf = randf;\n  global.randi = randi;\n  global.randn = randn;\n  global.zeros = zeros;\n  global.maxmin = maxmin;\n  global.randperm = randperm;\n  global.weightedSample = weightedSample;\n  global.arrUnique = arrUnique;\n  global.arrContains = arrContains;\n  global.getopt = getopt;\n  \n})(convnetjs);\n(function(global) {\n  \"use strict\";\n\n  // Vol is the basic building block of all data in a net.\n  // it is essentially just a 3D volume of numbers, with a\n  // width (sx), height (sy), and depth (depth).\n  // it is used to hold data for all filters, all volumes,\n  // all weights, and also stores all gradients w.r.t. \n  // the data. c is optionally a value to initialize the volume\n  // with. If c is missing, fills the Vol with random numbers.\n  var Vol = function(sx, sy, depth, c) {\n    // this is how you check if a variable is an array. Oh, Javascript :)\n    if(Object.prototype.toString.call(sx) === '[object Array]') {\n      // we were given a list in sx, assume 1D volume and fill it up\n      this.sx = 1;\n      this.sy = 1;\n      this.depth = sx.length;\n      // we have to do the following copy because we want to use\n      // fast typed arrays, not an ordinary javascript array\n      this.w = global.zeros(this.depth);\n      this.dw = global.zeros(this.depth);\n      for(var i=0;i<this.depth;i++) {\n        this.w[i] = sx[i];\n      }\n    } else {\n      // we were given dimensions of the vol\n      this.sx = sx;\n      this.sy = sy;\n      this.depth = depth;\n      var n = sx*sy*depth;\n      this.w = global.zeros(n);\n      this.dw = global.zeros(n);\n      if(typeof c === 'undefined') {\n        // weight normalization is done to equalize the output\n        // variance of every neuron, otherwise neurons with a lot\n        // of incoming connections have outputs of larger variance\n        var scale = Math.sqrt(1.0/(sx*sy*depth));\n        for(var i=0;i<n;i++) { \n          this.w[i] = global.randn(0.0, scale);\n        }\n      } else {\n        for(var i=0;i<n;i++) { \n          this.w[i] = c;\n        }\n      }\n    }\n  }\n\n  Vol.prototype = {\n    get: function(x, y, d) { \n      var ix=((this.sx * y)+x)*this.depth+d;\n      return this.w[ix];\n    },\n    set: function(x, y, d, v) { \n      var ix=((this.sx * y)+x)*this.depth+d;\n      this.w[ix] = v; \n    },\n    add: function(x, y, d, v) { \n      var ix=((this.sx * y)+x)*this.depth+d;\n      this.w[ix] += v; \n    },\n    get_grad: function(x, y, d) { \n      var ix = ((this.sx * y)+x)*this.depth+d;\n      return this.dw[ix]; \n    },\n    set_grad: function(x, y, d, v) { \n      var ix = ((this.sx * y)+x)*this.depth+d;\n      this.dw[ix] = v; \n    },\n    add_grad: function(x, y, d, v) { \n      var ix = ((this.sx * y)+x)*this.depth+d;\n      this.dw[ix] += v; \n    },\n    cloneAndZero: function() { return new Vol(this.sx, this.sy, this.depth, 0.0)},\n    clone: function() {\n      var V = new Vol(this.sx, this.sy, this.depth, 0.0);\n      var n = this.w.length;\n      for(var i=0;i<n;i++) { V.w[i] = this.w[i]; }\n      return V;\n    },\n    addFrom: function(V) { for(var k=0;k<this.w.length;k++) { this.w[k] += V.w[k]; }},\n    addFromScaled: function(V, a) { for(var k=0;k<this.w.length;k++) { this.w[k] += a*V.w[k]; }},\n    setConst: function(a) { for(var k=0;k<this.w.length;k++) { this.w[k] = a; }},\n\n    toJSON: function() {\n      // todo: we may want to only save d most significant digits to save space\n      var json = {}\n      json.sx = this.sx; \n      json.sy = this.sy;\n      json.depth = this.depth;\n      json.w = this.w;\n      return json;\n      // we wont back up gradients to save space\n    },\n    fromJSON: function(json) {\n      this.sx = json.sx;\n      this.sy = json.sy;\n      this.depth = json.depth;\n\n      var n = this.sx*this.sy*this.depth;\n      this.w = global.zeros(n);\n      this.dw = global.zeros(n);\n      // copy over the elements.\n      for(var i=0;i<n;i++) {\n        this.w[i] = json.w[i];\n      }\n    }\n  }\n\n  global.Vol = Vol;\n})(convnetjs);\n(function(global) {\n  \"use strict\";\n  var Vol = global.Vol; // convenience\n\n  // Volume utilities\n  // intended for use with data augmentation\n  // crop is the size of output\n  // dx,dy are offset wrt incoming volume, of the shift\n  // fliplr is boolean on whether we also want to flip left<->right\n  var augment = function(V, crop, dx, dy, fliplr) {\n    // note assumes square outputs of size crop x crop\n    if(typeof(fliplr)==='undefined') var fliplr = false;\n    if(typeof(dx)==='undefined') var dx = global.randi(0, V.sx - crop);\n    if(typeof(dy)==='undefined') var dy = global.randi(0, V.sy - crop);\n    \n    // randomly sample a crop in the input volume\n    var W;\n    if(crop !== V.sx || dx!==0 || dy!==0) {\n      W = new Vol(crop, crop, V.depth, 0.0);\n      for(var x=0;x<crop;x++) {\n        for(var y=0;y<crop;y++) {\n          if(x+dx<0 || x+dx>=V.sx || y+dy<0 || y+dy>=V.sy) continue; // oob\n          for(var d=0;d<V.depth;d++) {\n           W.set(x,y,d,V.get(x+dx,y+dy,d)); // copy data over\n          }\n        }\n      }\n    } else {\n      W = V;\n    }\n\n    if(fliplr) {\n      // flip volume horziontally\n      var W2 = W.cloneAndZero();\n      for(var x=0;x<W.sx;x++) {\n        for(var y=0;y<W.sy;y++) {\n          for(var d=0;d<W.depth;d++) {\n           W2.set(x,y,d,W.get(W.sx - x - 1,y,d)); // copy data over\n          }\n        }\n      }\n      W = W2; //swap\n    }\n    return W;\n  }\n\n  // img is a DOM element that contains a loaded image\n  // returns a Vol of size (W, H, 4). 4 is for RGBA\n  var img_to_vol = function(img, convert_grayscale) {\n\n    if(typeof(convert_grayscale)==='undefined') var convert_grayscale = false;\n\n    var canvas = document.createElement('canvas');\n    canvas.width = img.width;\n    canvas.height = img.height;\n    var ctx = canvas.getContext(\"2d\");\n\n    // due to a Firefox bug\n    try {\n      ctx.drawImage(img, 0, 0);\n    } catch (e) {\n      if (e.name === \"NS_ERROR_NOT_AVAILABLE\") {\n        // sometimes happens, lets just abort\n        return false;\n      } else {\n        throw e;\n      }\n    }\n\n    try {\n      var img_data = ctx.getImageData(0, 0, canvas.width, canvas.height);\n    } catch (e) {\n      if(e.name === 'IndexSizeError') {\n        return false; // not sure what causes this sometimes but okay abort\n      } else {\n        throw e;\n      }\n    }\n\n    // prepare the input: get pixels and normalize them\n    var p = img_data.data;\n    var W = img.width;\n    var H = img.height;\n    var pv = []\n    for(var i=0;i<p.length;i++) {\n      pv.push(p[i]/255.0-0.5); // normalize image pixels to [-0.5, 0.5]\n    }\n    var x = new Vol(W, H, 4, 0.0); //input volume (image)\n    x.w = pv;\n\n    if(convert_grayscale) {\n      // flatten into depth=1 array\n      var x1 = new Vol(W, H, 1, 0.0);\n      for(var i=0;i<W;i++) {\n        for(var j=0;j<H;j++) {\n          x1.set(i,j,0,x.get(i,j,0));\n        }\n      }\n      x = x1;\n    }\n\n    return x;\n  }\n  \n  global.augment = augment;\n  global.img_to_vol = img_to_vol;\n\n})(convnetjs);\n(function(global) {\n  \"use strict\";\n  var Vol = global.Vol; // convenience\n\n  // This file contains all layers that do dot products with input,\n  // but usually in a different connectivity pattern and weight sharing\n  // schemes: \n  // - FullyConn is fully connected dot products \n  // - ConvLayer does convolutions (so weight sharing spatially)\n  // putting them together in one file because they are very similar\n  var ConvLayer = function(opt) {\n    var opt = opt || {};\n\n    // required\n    this.out_depth = opt.filters;\n    this.sx = opt.sx; // filter size. Should be odd if possible, it's cleaner.\n    this.in_depth = opt.in_depth;\n    this.in_sx = opt.in_sx;\n    this.in_sy = opt.in_sy;\n    \n    // optional\n    this.sy = typeof opt.sy !== 'undefined' ? opt.sy : this.sx;\n    this.stride = typeof opt.stride !== 'undefined' ? opt.stride : 1; // stride at which we apply filters to input volume\n    this.pad = typeof opt.pad !== 'undefined' ? opt.pad : 0; // amount of 0 padding to add around borders of input volume\n    this.l1_decay_mul = typeof opt.l1_decay_mul !== 'undefined' ? opt.l1_decay_mul : 0.0;\n    this.l2_decay_mul = typeof opt.l2_decay_mul !== 'undefined' ? opt.l2_decay_mul : 1.0;\n\n    // computed\n    // note we are doing floor, so if the strided convolution of the filter doesnt fit into the input\n    // volume exactly, the output volume will be trimmed and not contain the (incomplete) computed\n    // final application.\n    this.out_sx = Math.floor((this.in_sx + this.pad * 2 - this.sx) / this.stride + 1);\n    this.out_sy = Math.floor((this.in_sy + this.pad * 2 - this.sy) / this.stride + 1);\n    this.layer_type = 'conv';\n\n    // initializations\n    var bias = typeof opt.bias_pref !== 'undefined' ? opt.bias_pref : 0.0;\n    this.filters = [];\n    for(var i=0;i<this.out_depth;i++) { this.filters.push(new Vol(this.sx, this.sy, this.in_depth)); }\n    this.biases = new Vol(1, 1, this.out_depth, bias);\n  }\n  ConvLayer.prototype = {\n    forward: function(V, is_training) {\n      this.in_act = V;\n\n      var A = new Vol(this.out_sx, this.out_sy, this.out_depth, 0.0);\n      for(var d=0;d<this.out_depth;d++) {\n        var f = this.filters[d];\n        var x = -this.pad;\n        var y = -this.pad;\n        for(var ax=0; ax<this.out_sx; x+=this.stride,ax++) {\n          y = -this.pad;\n          for(var ay=0; ay<this.out_sy; y+=this.stride,ay++) {\n\n            // convolve centered at this particular location\n            // could be bit more efficient, going for correctness first\n            var a = 0.0;\n            for(var fx=0;fx<f.sx;fx++) {\n              for(var fy=0;fy<f.sy;fy++) {\n                for(var fd=0;fd<f.depth;fd++) {\n                  var oy = y+fy; // coordinates in the original input array coordinates\n                  var ox = x+fx;\n                  if(oy>=0 && oy<V.sy && ox>=0 && ox<V.sx) {\n                    //a += f.get(fx, fy, fd) * V.get(ox, oy, fd);\n                    // avoid function call overhead for efficiency, compromise modularity :(\n                    a += f.w[((f.sx * fy)+fx)*f.depth+fd] * V.w[((V.sx * oy)+ox)*V.depth+fd];\n                  }\n                }\n              }\n            }\n            a += this.biases.w[d];\n            A.set(ax, ay, d, a);\n          }\n        }\n      }\n      this.out_act = A;\n      return this.out_act;\n    },\n    backward: function() { \n\n      // compute gradient wrt weights, biases and input data\n      var V = this.in_act;\n      V.dw = global.zeros(V.w.length); // zero out gradient wrt bottom data, we're about to fill it\n      for(var d=0;d<this.out_depth;d++) {\n        var f = this.filters[d];\n        var x = -this.pad;\n        var y = -this.pad;\n        for(var ax=0; ax<this.out_sx; x+=this.stride,ax++) {\n          y = -this.pad;\n          for(var ay=0; ay<this.out_sy; y+=this.stride,ay++) {\n            // convolve and add up the gradients. \n            // could be more efficient, going for correctness first\n            var chain_grad = this.out_act.get_grad(ax,ay,d); // gradient from above, from chain rule\n            for(var fx=0;fx<f.sx;fx++) {\n              for(var fy=0;fy<f.sy;fy++) {\n                for(var fd=0;fd<f.depth;fd++) {\n                  var oy = y+fy;\n                  var ox = x+fx;\n                  if(oy>=0 && oy<V.sy && ox>=0 && ox<V.sx) {\n                    // forward prop calculated: a += f.get(fx, fy, fd) * V.get(ox, oy, fd);\n                    //f.add_grad(fx, fy, fd, V.get(ox, oy, fd) * chain_grad);\n                    //V.add_grad(ox, oy, fd, f.get(fx, fy, fd) * chain_grad);\n\n                    // avoid function call overhead and use Vols directly for efficiency\n                    var ix1 = ((V.sx * oy)+ox)*V.depth+fd;\n                    var ix2 = ((f.sx * fy)+fx)*f.depth+fd;\n                    f.dw[ix2] += V.w[ix1]*chain_grad;\n                    V.dw[ix1] += f.w[ix2]*chain_grad;\n                  }\n                }\n              }\n            }\n            this.biases.dw[d] += chain_grad;\n          }\n        }\n      }\n    },\n    getParamsAndGrads: function() {\n      var response = [];\n      for(var i=0;i<this.out_depth;i++) {\n        response.push({params: this.filters[i].w, grads: this.filters[i].dw, l2_decay_mul: this.l2_decay_mul, l1_decay_mul: this.l1_decay_mul});\n      }\n      response.push({params: this.biases.w, grads: this.biases.dw, l1_decay_mul: 0.0, l2_decay_mul: 0.0});\n      return response;\n    },\n    toJSON: function() {\n      var json = {};\n      json.sx = this.sx; // filter size in x, y dims\n      json.sy = this.sy;\n      json.stride = this.stride;\n      json.in_depth = this.in_depth;\n      json.out_depth = this.out_depth;\n      json.out_sx = this.out_sx;\n      json.out_sy = this.out_sy;\n      json.layer_type = this.layer_type;\n      json.l1_decay_mul = this.l1_decay_mul;\n      json.l2_decay_mul = this.l2_decay_mul;\n      json.pad = this.pad;\n      json.filters = [];\n      for(var i=0;i<this.filters.length;i++) {\n        json.filters.push(this.filters[i].toJSON());\n      }\n      json.biases = this.biases.toJSON();\n      return json;\n    },\n    fromJSON: function(json) {\n      this.out_depth = json.out_depth;\n      this.out_sx = json.out_sx;\n      this.out_sy = json.out_sy;\n      this.layer_type = json.layer_type;\n      this.sx = json.sx; // filter size in x, y dims\n      this.sy = json.sy;\n      this.stride = json.stride;\n      this.in_depth = json.in_depth; // depth of input volume\n      this.filters = [];\n      this.l1_decay_mul = typeof json.l1_decay_mul !== 'undefined' ? json.l1_decay_mul : 1.0;\n      this.l2_decay_mul = typeof json.l2_decay_mul !== 'undefined' ? json.l2_decay_mul : 1.0;\n      this.pad = typeof json.pad !== 'undefined' ? json.pad : 0;\n      for(var i=0;i<json.filters.length;i++) {\n        var v = new Vol(0,0,0,0);\n        v.fromJSON(json.filters[i]);\n        this.filters.push(v);\n      }\n      this.biases = new Vol(0,0,0,0);\n      this.biases.fromJSON(json.biases);\n    }\n  }\n\n  var FullyConnLayer = function(opt) {\n    var opt = opt || {};\n\n    // required\n    // ok fine we will allow 'filters' as the word as well\n    this.out_depth = typeof opt.num_neurons !== 'undefined' ? opt.num_neurons : opt.filters;\n\n    // optional \n    this.l1_decay_mul = typeof opt.l1_decay_mul !== 'undefined' ? opt.l1_decay_mul : 0.0;\n    this.l2_decay_mul = typeof opt.l2_decay_mul !== 'undefined' ? opt.l2_decay_mul : 1.0;\n\n    // computed\n    this.num_inputs = opt.in_sx * opt.in_sy * opt.in_depth;\n    this.out_sx = 1;\n    this.out_sy = 1;\n    this.layer_type = 'fc';\n\n    // initializations\n    var bias = typeof opt.bias_pref !== 'undefined' ? opt.bias_pref : 0.0;\n    this.filters = [];\n    for(var i=0;i<this.out_depth ;i++) { this.filters.push(new Vol(1, 1, this.num_inputs)); }\n    this.biases = new Vol(1, 1, this.out_depth, bias);\n  }\n\n  FullyConnLayer.prototype = {\n    forward: function(V, is_training) {\n      this.in_act = V;\n      var A = new Vol(1, 1, this.out_depth, 0.0);\n      var Vw = V.w;\n      for(var i=0;i<this.out_depth;i++) {\n        var a = 0.0;\n        var wi = this.filters[i].w;\n        for(var d=0;d<this.num_inputs;d++) {\n          a += Vw[d] * wi[d]; // for efficiency use Vols directly for now\n        }\n        a += this.biases.w[i];\n        A.w[i] = a;\n      }\n      this.out_act = A;\n      return this.out_act;\n    },\n    backward: function() {\n      var V = this.in_act;\n      V.dw = global.zeros(V.w.length); // zero out the gradient in input Vol\n      \n      // compute gradient wrt weights and data\n      for(var i=0;i<this.out_depth;i++) {\n        var tfi = this.filters[i];\n        var chain_grad = this.out_act.dw[i];\n        for(var d=0;d<this.num_inputs;d++) {\n          V.dw[d] += tfi.w[d]*chain_grad; // grad wrt input data\n          tfi.dw[d] += V.w[d]*chain_grad; // grad wrt params\n        }\n        this.biases.dw[i] += chain_grad;\n      }\n    },\n    getParamsAndGrads: function() {\n      var response = [];\n      for(var i=0;i<this.out_depth;i++) {\n        response.push({params: this.filters[i].w, grads: this.filters[i].dw, l1_decay_mul: this.l1_decay_mul, l2_decay_mul: this.l2_decay_mul});\n      }\n      response.push({params: this.biases.w, grads: this.biases.dw, l1_decay_mul: 0.0, l2_decay_mul: 0.0});\n      return response;\n    },\n    toJSON: function() {\n      var json = {};\n      json.out_depth = this.out_depth;\n      json.out_sx = this.out_sx;\n      json.out_sy = this.out_sy;\n      json.layer_type = this.layer_type;\n      json.num_inputs = this.num_inputs;\n      json.l1_decay_mul = this.l1_decay_mul;\n      json.l2_decay_mul = this.l2_decay_mul;\n      json.filters = [];\n      for(var i=0;i<this.filters.length;i++) {\n        json.filters.push(this.filters[i].toJSON());\n      }\n      json.biases = this.biases.toJSON();\n      return json;\n    },\n    fromJSON: function(json) {\n      this.out_depth = json.out_depth;\n      this.out_sx = json.out_sx;\n      this.out_sy = json.out_sy;\n      this.layer_type = json.layer_type;\n      this.num_inputs = json.num_inputs;\n      this.l1_decay_mul = typeof json.l1_decay_mul !== 'undefined' ? json.l1_decay_mul : 1.0;\n      this.l2_decay_mul = typeof json.l2_decay_mul !== 'undefined' ? json.l2_decay_mul : 1.0;\n      this.filters = [];\n      for(var i=0;i<json.filters.length;i++) {\n        var v = new Vol(0,0,0,0);\n        v.fromJSON(json.filters[i]);\n        this.filters.push(v);\n      }\n      this.biases = new Vol(0,0,0,0);\n      this.biases.fromJSON(json.biases);\n    }\n  }\n\n  global.ConvLayer = ConvLayer;\n  global.FullyConnLayer = FullyConnLayer;\n  \n})(convnetjs);\n(function(global) {\n  \"use strict\";\n  var Vol = global.Vol; // convenience\n  \n  var PoolLayer = function(opt) {\n\n    var opt = opt || {};\n\n    // required\n    this.sx = opt.sx; // filter size\n    this.in_depth = opt.in_depth;\n    this.in_sx = opt.in_sx;\n    this.in_sy = opt.in_sy;\n\n    // optional\n    this.sy = typeof opt.sy !== 'undefined' ? opt.sy : this.sx;\n    this.stride = typeof opt.stride !== 'undefined' ? opt.stride : 2;\n    this.pad = typeof opt.pad !== 'undefined' ? opt.pad : 0; // amount of 0 padding to add around borders of input volume\n\n    // computed\n    this.out_depth = this.in_depth;\n    this.out_sx = Math.floor((this.in_sx + this.pad * 2 - this.sx) / this.stride + 1);\n    this.out_sy = Math.floor((this.in_sy + this.pad * 2 - this.sy) / this.stride + 1);\n    this.layer_type = 'pool';\n    // store switches for x,y coordinates for where the max comes from, for each output neuron\n    this.switchx = global.zeros(this.out_sx*this.out_sy*this.out_depth);\n    this.switchy = global.zeros(this.out_sx*this.out_sy*this.out_depth);\n  }\n\n  PoolLayer.prototype = {\n    forward: function(V, is_training) {\n      this.in_act = V;\n\n      var A = new Vol(this.out_sx, this.out_sy, this.out_depth, 0.0);\n      \n      var n=0; // a counter for switches\n      for(var d=0;d<this.out_depth;d++) {\n        var x = -this.pad;\n        var y = -this.pad;\n        for(var ax=0; ax<this.out_sx; x+=this.stride,ax++) {\n          y = -this.pad;\n          for(var ay=0; ay<this.out_sy; y+=this.stride,ay++) {\n\n            // convolve centered at this particular location\n            var a = -99999; // hopefully small enough ;\\\n            var winx=-1,winy=-1;\n            for(var fx=0;fx<this.sx;fx++) {\n              for(var fy=0;fy<this.sy;fy++) {\n                var oy = y+fy;\n                var ox = x+fx;\n                if(oy>=0 && oy<V.sy && ox>=0 && ox<V.sx) {\n                  var v = V.get(ox, oy, d);\n                  // perform max pooling and store pointers to where\n                  // the max came from. This will speed up backprop \n                  // and can help make nice visualizations in future\n                  if(v > a) { a = v; winx=ox; winy=oy;}\n                }\n              }\n            }\n            this.switchx[n] = winx;\n            this.switchy[n] = winy;\n            n++;\n            A.set(ax, ay, d, a);\n          }\n        }\n      }\n      this.out_act = A;\n      return this.out_act;\n    },\n    backward: function() { \n      // pooling layers have no parameters, so simply compute \n      // gradient wrt data here\n      var V = this.in_act;\n      V.dw = global.zeros(V.w.length); // zero out gradient wrt data\n      var A = this.out_act; // computed in forward pass \n\n      var n = 0;\n      for(var d=0;d<this.out_depth;d++) {\n        var x = -this.pad;\n        var y = -this.pad;\n        for(var ax=0; ax<this.out_sx; x+=this.stride,ax++) {\n          y = -this.pad;\n          for(var ay=0; ay<this.out_sy; y+=this.stride,ay++) {\n\n            var chain_grad = this.out_act.get_grad(ax,ay,d);\n            V.add_grad(this.switchx[n], this.switchy[n], d, chain_grad);\n            n++;\n\n          }\n        }\n      }\n    },\n    getParamsAndGrads: function() {\n      return [];\n    },\n    toJSON: function() {\n      var json = {};\n      json.sx = this.sx;\n      json.sy = this.sy;\n      json.stride = this.stride;\n      json.in_depth = this.in_depth;\n      json.out_depth = this.out_depth;\n      json.out_sx = this.out_sx;\n      json.out_sy = this.out_sy;\n      json.layer_type = this.layer_type;\n      json.pad = this.pad;\n      return json;\n    },\n    fromJSON: function(json) {\n      this.out_depth = json.out_depth;\n      this.out_sx = json.out_sx;\n      this.out_sy = json.out_sy;\n      this.layer_type = json.layer_type;\n      this.sx = json.sx;\n      this.sy = json.sy;\n      this.stride = json.stride;\n      this.in_depth = json.in_depth;\n      this.pad = typeof json.pad !== 'undefined' ? json.pad : 0; // backwards compatibility\n      this.switchx = global.zeros(this.out_sx*this.out_sy*this.out_depth); // need to re-init these appropriately\n      this.switchy = global.zeros(this.out_sx*this.out_sy*this.out_depth);\n    }\n  }\n\n  global.PoolLayer = PoolLayer;\n\n})(convnetjs);\n\n(function(global) {\n  \"use strict\";\n  var Vol = global.Vol; // convenience\n  \n  var InputLayer = function(opt) {\n    var opt = opt || {};\n\n    // this is a bit silly but lets allow people to specify either ins or outs\n    this.out_sx = typeof opt.out_sx !== 'undefined' ? opt.out_sx : opt.in_sx;\n    this.out_sy = typeof opt.out_sy !== 'undefined' ? opt.out_sy : opt.in_sy;\n    this.out_depth = typeof opt.out_depth !== 'undefined' ? opt.out_depth : opt.in_depth;\n    this.layer_type = 'input';\n  }\n  InputLayer.prototype = {\n    forward: function(V, is_training) {\n      this.in_act = V;\n      this.out_act = V;\n      return this.out_act; // dummy identity function for now\n    },\n    backward: function() { },\n    getParamsAndGrads: function() {\n      return [];\n    },\n    toJSON: function() {\n      var json = {};\n      json.out_depth = this.out_depth;\n      json.out_sx = this.out_sx;\n      json.out_sy = this.out_sy;\n      json.layer_type = this.layer_type;\n      return json;\n    },\n    fromJSON: function(json) {\n      this.out_depth = json.out_depth;\n      this.out_sx = json.out_sx;\n      this.out_sy = json.out_sy;\n      this.layer_type = json.layer_type; \n    }\n  }\n\n  global.InputLayer = InputLayer;\n})(convnetjs);\n(function(global) {\n  \"use strict\";\n  var Vol = global.Vol; // convenience\n  \n  // Layers that implement a loss. Currently these are the layers that \n  // can initiate a backward() pass. In future we probably want a more \n  // flexible system that can accomodate multiple losses to do multi-task\n  // learning, and stuff like that. But for now, one of the layers in this\n  // file must be the final layer in a Net.\n\n  // This is a classifier, with N discrete classes from 0 to N-1\n  // it gets a stream of N incoming numbers and computes the softmax\n  // function (exponentiate and normalize to sum to 1 as probabilities should)\n  var SoftmaxLayer = function(opt) {\n    var opt = opt || {};\n\n    // computed\n    this.num_inputs = opt.in_sx * opt.in_sy * opt.in_depth;\n    this.out_depth = this.num_inputs;\n    this.out_sx = 1;\n    this.out_sy = 1;\n    this.layer_type = 'softmax';\n  }\n\n  SoftmaxLayer.prototype = {\n    forward: function(V, is_training) {\n      this.in_act = V;\n\n      var A = new Vol(1, 1, this.out_depth, 0.0);\n\n      // compute max activation\n      var as = V.w;\n      var amax = V.w[0];\n      for(var i=1;i<this.out_depth;i++) {\n        if(as[i] > amax) amax = as[i];\n      }\n\n      // compute exponentials (carefully to not blow up)\n      var es = global.zeros(this.out_depth);\n      var esum = 0.0;\n      for(var i=0;i<this.out_depth;i++) {\n        var e = Math.exp(as[i] - amax);\n        esum += e;\n        es[i] = e;\n      }\n\n      // normalize and output to sum to one\n      for(var i=0;i<this.out_depth;i++) {\n        es[i] /= esum;\n        A.w[i] = es[i];\n      }\n\n      this.es = es; // save these for backprop\n      this.out_act = A;\n      return this.out_act;\n    },\n    backward: function(y) {\n\n      // compute and accumulate gradient wrt weights and bias of this layer\n      var x = this.in_act;\n      x.dw = global.zeros(x.w.length); // zero out the gradient of input Vol\n\n      for(var i=0;i<this.out_depth;i++) {\n        var indicator = i === y ? 1.0 : 0.0;\n        var mul = -(indicator - this.es[i]);\n        x.dw[i] = mul;\n      }\n\n      // loss is the class negative log likelihood\n      return -Math.log(this.es[y]);\n    },\n    getParamsAndGrads: function() { \n      return [];\n    },\n    toJSON: function() {\n      var json = {};\n      json.out_depth = this.out_depth;\n      json.out_sx = this.out_sx;\n      json.out_sy = this.out_sy;\n      json.layer_type = this.layer_type;\n      json.num_inputs = this.num_inputs;\n      return json;\n    },\n    fromJSON: function(json) {\n      this.out_depth = json.out_depth;\n      this.out_sx = json.out_sx;\n      this.out_sy = json.out_sy;\n      this.layer_type = json.layer_type;\n      this.num_inputs = json.num_inputs;\n    }\n  }\n\n  // implements an L2 regression cost layer,\n  // so penalizes \\sum_i(||x_i - y_i||^2), where x is its input\n  // and y is the user-provided array of \"correct\" values.\n  var RegressionLayer = function(opt) {\n    var opt = opt || {};\n\n    // computed\n    this.num_inputs = opt.in_sx * opt.in_sy * opt.in_depth;\n    this.out_depth = this.num_inputs;\n    this.out_sx = 1;\n    this.out_sy = 1;\n    this.layer_type = 'regression';\n  }\n\n  RegressionLayer.prototype = {\n    forward: function(V, is_training) {\n      this.in_act = V;\n      this.out_act = V;\n      return V; // identity function\n    },\n    // y is a list here of size num_inputs\n    backward: function(y) { \n\n      // compute and accumulate gradient wrt weights and bias of this layer\n      var x = this.in_act;\n      x.dw = global.zeros(x.w.length); // zero out the gradient of input Vol\n      var loss = 0.0;\n      if(y instanceof Array || y instanceof Float64Array) {\n        for(var i=0;i<this.out_depth;i++) {\n          var dy = x.w[i] - y[i];\n          x.dw[i] = dy;\n          loss += 2*dy*dy;\n        }\n      } else {\n        // assume it is a struct with entries .dim and .val\n        // and we pass gradient only along dimension dim to be equal to val\n        var i = y.dim;\n        var yi = y.val;\n        var dy = x.w[i] - yi;\n        x.dw[i] = dy;\n        loss += 2*dy*dy;\n      }\n      return loss;\n    },\n    getParamsAndGrads: function() { \n      return [];\n    },\n    toJSON: function() {\n      var json = {};\n      json.out_depth = this.out_depth;\n      json.out_sx = this.out_sx;\n      json.out_sy = this.out_sy;\n      json.layer_type = this.layer_type;\n      json.num_inputs = this.num_inputs;\n      return json;\n    },\n    fromJSON: function(json) {\n      this.out_depth = json.out_depth;\n      this.out_sx = json.out_sx;\n      this.out_sy = json.out_sy;\n      this.layer_type = json.layer_type;\n      this.num_inputs = json.num_inputs;\n    }\n  }\n\n  var SVMLayer = function(opt) {\n    var opt = opt || {};\n\n    // computed\n    this.num_inputs = opt.in_sx * opt.in_sy * opt.in_depth;\n    this.out_depth = this.num_inputs;\n    this.out_sx = 1;\n    this.out_sy = 1;\n    this.layer_type = 'svm';\n  }\n\n  SVMLayer.prototype = {\n    forward: function(V, is_training) {\n      this.in_act = V;\n      this.out_act = V; // nothing to do, output raw scores\n      return V;\n    },\n    backward: function(y) {\n\n      // compute and accumulate gradient wrt weights and bias of this layer\n      var x = this.in_act;\n      x.dw = global.zeros(x.w.length); // zero out the gradient of input Vol\n\n      var yscore = x.w[y]; // score of ground truth\n      var margin = 1.0;\n      var loss = 0.0;\n      for(var i=0;i<this.out_depth;i++) {\n        if(-yscore + x.w[i] + margin > 0) {\n          // violating example, apply loss\n          // I love hinge loss, by the way. Truly.\n          // Seriously, compare this SVM code with Softmax forward AND backprop code above\n          // it's clear which one is superior, not only in code, simplicity\n          // and beauty, but also in practice.\n          x.dw[i] += 1;\n          x.dw[y] -= 1;\n          loss += -yscore + x.w[i] + margin;\n        }\n      }\n\n      return loss;\n    },\n    getParamsAndGrads: function() { \n      return [];\n    },\n    toJSON: function() {\n      var json = {};\n      json.out_depth = this.out_depth;\n      json.out_sx = this.out_sx;\n      json.out_sy = this.out_sy;\n      json.layer_type = this.layer_type;\n      json.num_inputs = this.num_inputs;\n      return json;\n    },\n    fromJSON: function(json) {\n      this.out_depth = json.out_depth;\n      this.out_sx = json.out_sx;\n      this.out_sy = json.out_sy;\n      this.layer_type = json.layer_type;\n      this.num_inputs = json.num_inputs;\n    }\n  }\n  \n  global.RegressionLayer = RegressionLayer;\n  global.SoftmaxLayer = SoftmaxLayer;\n  global.SVMLayer = SVMLayer;\n\n})(convnetjs);\n\n(function(global) {\n  \"use strict\";\n  var Vol = global.Vol; // convenience\n  \n  // Implements ReLU nonlinearity elementwise\n  // x -> max(0, x)\n  // the output is in [0, inf)\n  var ReluLayer = function(opt) {\n    var opt = opt || {};\n\n    // computed\n    this.out_sx = opt.in_sx;\n    this.out_sy = opt.in_sy;\n    this.out_depth = opt.in_depth;\n    this.layer_type = 'relu';\n  }\n  ReluLayer.prototype = {\n    forward: function(V, is_training) {\n      this.in_act = V;\n      var V2 = V.clone();\n      var N = V.w.length;\n      var V2w = V2.w;\n      for(var i=0;i<N;i++) { \n        if(V2w[i] < 0) V2w[i] = 0; // threshold at 0\n      }\n      this.out_act = V2;\n      return this.out_act;\n    },\n    backward: function() {\n      var V = this.in_act; // we need to set dw of this\n      var V2 = this.out_act;\n      var N = V.w.length;\n      V.dw = global.zeros(N); // zero out gradient wrt data\n      for(var i=0;i<N;i++) {\n        if(V2.w[i] <= 0) V.dw[i] = 0; // threshold\n        else V.dw[i] = V2.dw[i];\n      }\n    },\n    getParamsAndGrads: function() {\n      return [];\n    },\n    toJSON: function() {\n      var json = {};\n      json.out_depth = this.out_depth;\n      json.out_sx = this.out_sx;\n      json.out_sy = this.out_sy;\n      json.layer_type = this.layer_type;\n      return json;\n    },\n    fromJSON: function(json) {\n      this.out_depth = json.out_depth;\n      this.out_sx = json.out_sx;\n      this.out_sy = json.out_sy;\n      this.layer_type = json.layer_type; \n    }\n  }\n\n  // Implements Sigmoid nnonlinearity elementwise\n  // x -> 1/(1+e^(-x))\n  // so the output is between 0 and 1.\n  var SigmoidLayer = function(opt) {\n    var opt = opt || {};\n\n    // computed\n    this.out_sx = opt.in_sx;\n    this.out_sy = opt.in_sy;\n    this.out_depth = opt.in_depth;\n    this.layer_type = 'sigmoid';\n  }\n  SigmoidLayer.prototype = {\n    forward: function(V, is_training) {\n      this.in_act = V;\n      var V2 = V.cloneAndZero();\n      var N = V.w.length;\n      var V2w = V2.w;\n      var Vw = V.w;\n      for(var i=0;i<N;i++) { \n        V2w[i] = 1.0/(1.0+Math.exp(-Vw[i]));\n      }\n      this.out_act = V2;\n      return this.out_act;\n    },\n    backward: function() {\n      var V = this.in_act; // we need to set dw of this\n      var V2 = this.out_act;\n      var N = V.w.length;\n      V.dw = global.zeros(N); // zero out gradient wrt data\n      for(var i=0;i<N;i++) {\n        var v2wi = V2.w[i];\n        V.dw[i] =  v2wi * (1.0 - v2wi) * V2.dw[i];\n      }\n    },\n    getParamsAndGrads: function() {\n      return [];\n    },\n    toJSON: function() {\n      var json = {};\n      json.out_depth = this.out_depth;\n      json.out_sx = this.out_sx;\n      json.out_sy = this.out_sy;\n      json.layer_type = this.layer_type;\n      return json;\n    },\n    fromJSON: function(json) {\n      this.out_depth = json.out_depth;\n      this.out_sx = json.out_sx;\n      this.out_sy = json.out_sy;\n      this.layer_type = json.layer_type; \n    }\n  }\n\n  // Implements Maxout nnonlinearity that computes\n  // x -> max(x)\n  // where x is a vector of size group_size. Ideally of course,\n  // the input size should be exactly divisible by group_size\n  var MaxoutLayer = function(opt) {\n    var opt = opt || {};\n\n    // required\n    this.group_size = typeof opt.group_size !== 'undefined' ? opt.group_size : 2;\n\n    // computed\n    this.out_sx = opt.in_sx;\n    this.out_sy = opt.in_sy;\n    this.out_depth = Math.floor(opt.in_depth / this.group_size);\n    this.layer_type = 'maxout';\n\n    this.switches = global.zeros(this.out_sx*this.out_sy*this.out_depth); // useful for backprop\n  }\n  MaxoutLayer.prototype = {\n    forward: function(V, is_training) {\n      this.in_act = V;\n      var N = this.out_depth; \n      var V2 = new Vol(this.out_sx, this.out_sy, this.out_depth, 0.0);\n\n      // optimization branch. If we're operating on 1D arrays we dont have\n      // to worry about keeping track of x,y,d coordinates inside\n      // input volumes. In convnets we do :(\n      if(this.out_sx === 1 && this.out_sy === 1) {\n        for(var i=0;i<N;i++) {\n          var ix = i * this.group_size; // base index offset\n          var a = V.w[ix];\n          var ai = 0;\n          for(var j=1;j<this.group_size;j++) {\n            var a2 = V.w[ix+j];\n            if(a2 > a) {\n              a = a2;\n              ai = j;\n            }\n          }\n          V2.w[i] = a;\n          this.switches[i] = ix + ai;\n        }\n      } else {\n        var n=0; // counter for switches\n        for(var x=0;x<V.sx;x++) {\n          for(var y=0;y<V.sy;y++) {\n            for(var i=0;i<N;i++) {\n              var ix = i * this.group_size;\n              var a = V.get(x, y, ix);\n              var ai = 0;\n              for(var j=1;j<this.group_size;j++) {\n                var a2 = V.get(x, y, ix+j);\n                if(a2 > a) {\n                  a = a2;\n                  ai = j;\n                }\n              }\n              V2.set(x,y,i,a);\n              this.switches[n] = ix + ai;\n              n++;\n            }\n          }\n        }\n\n      }\n      this.out_act = V2;\n      return this.out_act;\n    },\n    backward: function() {\n      var V = this.in_act; // we need to set dw of this\n      var V2 = this.out_act;\n      var N = this.out_depth;\n      V.dw = global.zeros(V.w.length); // zero out gradient wrt data\n\n      // pass the gradient through the appropriate switch\n      if(this.out_sx === 1 && this.out_sy === 1) {\n        for(var i=0;i<N;i++) {\n          var chain_grad = V2.dw[i];\n          V.dw[this.switches[i]] = chain_grad;\n        }\n      } else {\n        // bleh okay, lets do this the hard way\n        var n=0; // counter for switches\n        for(var x=0;x<V2.sx;x++) {\n          for(var y=0;y<V2.sy;y++) {\n            for(var i=0;i<N;i++) {\n              var chain_grad = V2.get_grad(x,y,i);\n              V.set_grad(x,y,this.switches[n],chain_grad);\n              n++;\n            }\n          }\n        }\n      }\n    },\n    getParamsAndGrads: function() {\n      return [];\n    },\n    toJSON: function() {\n      var json = {};\n      json.out_depth = this.out_depth;\n      json.out_sx = this.out_sx;\n      json.out_sy = this.out_sy;\n      json.layer_type = this.layer_type;\n      json.group_size = this.group_size;\n      return json;\n    },\n    fromJSON: function(json) {\n      this.out_depth = json.out_depth;\n      this.out_sx = json.out_sx;\n      this.out_sy = json.out_sy;\n      this.layer_type = json.layer_type; \n      this.group_size = json.group_size;\n      this.switches = global.zeros(this.group_size);\n    }\n  }\n\n  // a helper function, since tanh is not yet part of ECMAScript. Will be in v6.\n  function tanh(x) {\n    var y = Math.exp(2 * x);\n    return (y - 1) / (y + 1);\n  }\n  // Implements Tanh nnonlinearity elementwise\n  // x -> tanh(x) \n  // so the output is between -1 and 1.\n  var TanhLayer = function(opt) {\n    var opt = opt || {};\n\n    // computed\n    this.out_sx = opt.in_sx;\n    this.out_sy = opt.in_sy;\n    this.out_depth = opt.in_depth;\n    this.layer_type = 'tanh';\n  }\n  TanhLayer.prototype = {\n    forward: function(V, is_training) {\n      this.in_act = V;\n      var V2 = V.cloneAndZero();\n      var N = V.w.length;\n      for(var i=0;i<N;i++) { \n        V2.w[i] = tanh(V.w[i]);\n      }\n      this.out_act = V2;\n      return this.out_act;\n    },\n    backward: function() {\n      var V = this.in_act; // we need to set dw of this\n      var V2 = this.out_act;\n      var N = V.w.length;\n      V.dw = global.zeros(N); // zero out gradient wrt data\n      for(var i=0;i<N;i++) {\n        var v2wi = V2.w[i];\n        V.dw[i] = (1.0 - v2wi * v2wi) * V2.dw[i];\n      }\n    },\n    getParamsAndGrads: function() {\n      return [];\n    },\n    toJSON: function() {\n      var json = {};\n      json.out_depth = this.out_depth;\n      json.out_sx = this.out_sx;\n      json.out_sy = this.out_sy;\n      json.layer_type = this.layer_type;\n      return json;\n    },\n    fromJSON: function(json) {\n      this.out_depth = json.out_depth;\n      this.out_sx = json.out_sx;\n      this.out_sy = json.out_sy;\n      this.layer_type = json.layer_type; \n    }\n  }\n  \n  global.TanhLayer = TanhLayer;\n  global.MaxoutLayer = MaxoutLayer;\n  global.ReluLayer = ReluLayer;\n  global.SigmoidLayer = SigmoidLayer;\n\n})(convnetjs);\n\n(function(global) {\n  \"use strict\";\n  var Vol = global.Vol; // convenience\n\n  // An inefficient dropout layer\n  // Note this is not most efficient implementation since the layer before\n  // computed all these activations and now we're just going to drop them :(\n  // same goes for backward pass. Also, if we wanted to be efficient at test time\n  // we could equivalently be clever and upscale during train and copy pointers during test\n  // todo: make more efficient.\n  var DropoutLayer = function(opt) {\n    var opt = opt || {};\n\n    // computed\n    this.out_sx = opt.in_sx;\n    this.out_sy = opt.in_sy;\n    this.out_depth = opt.in_depth;\n    this.layer_type = 'dropout';\n    this.drop_prob = typeof opt.drop_prob !== 'undefined' ? opt.drop_prob : 0.5;\n    this.dropped = global.zeros(this.out_sx*this.out_sy*this.out_depth);\n  }\n  DropoutLayer.prototype = {\n    forward: function(V, is_training) {\n      this.in_act = V;\n      if(typeof(is_training)==='undefined') { is_training = false; } // default is prediction mode\n      var V2 = V.clone();\n      var N = V.w.length;\n      if(is_training) {\n        // do dropout\n        for(var i=0;i<N;i++) {\n          if(Math.random()<this.drop_prob) { V2.w[i]=0; this.dropped[i] = true; } // drop!\n          else {this.dropped[i] = false;}\n        }\n      } else {\n        // scale the activations during prediction\n        for(var i=0;i<N;i++) { V2.w[i]*=this.drop_prob; }\n      }\n      this.out_act = V2;\n      return this.out_act; // dummy identity function for now\n    },\n    backward: function() {\n      var V = this.in_act; // we need to set dw of this\n      var chain_grad = this.out_act;\n      var N = V.w.length;\n      V.dw = global.zeros(N); // zero out gradient wrt data\n      for(var i=0;i<N;i++) {\n        if(!(this.dropped[i])) { \n          V.dw[i] = chain_grad.dw[i]; // copy over the gradient\n        }\n      }\n    },\n    getParamsAndGrads: function() {\n      return [];\n    },\n    toJSON: function() {\n      var json = {};\n      json.out_depth = this.out_depth;\n      json.out_sx = this.out_sx;\n      json.out_sy = this.out_sy;\n      json.layer_type = this.layer_type;\n      json.drop_prob = this.drop_prob;\n      return json;\n    },\n    fromJSON: function(json) {\n      this.out_depth = json.out_depth;\n      this.out_sx = json.out_sx;\n      this.out_sy = json.out_sy;\n      this.layer_type = json.layer_type; \n      this.drop_prob = json.drop_prob;\n    }\n  }\n  \n\n  global.DropoutLayer = DropoutLayer;\n})(convnetjs);\n(function(global) {\n  \"use strict\";\n  var Vol = global.Vol; // convenience\n  \n  // a bit experimental layer for now. I think it works but I'm not 100%\n  // the gradient check is a bit funky. I'll look into this a bit later.\n  // Local Response Normalization in window, along depths of volumes\n  var LocalResponseNormalizationLayer = function(opt) {\n    var opt = opt || {};\n\n    // required\n    this.k = opt.k;\n    this.n = opt.n;\n    this.alpha = opt.alpha;\n    this.beta = opt.beta;\n\n    // computed\n    this.out_sx = opt.in_sx;\n    this.out_sy = opt.in_sy;\n    this.out_depth = opt.in_depth;\n    this.layer_type = 'lrn';\n\n    // checks\n    if(this.n%2 === 0) { console.log('WARNING n should be odd for LRN layer'); }\n  }\n  LocalResponseNormalizationLayer.prototype = {\n    forward: function(V, is_training) {\n      this.in_act = V;\n\n      var A = V.cloneAndZero();\n      this.S_cache_ = V.cloneAndZero();\n      var n2 = Math.floor(this.n/2);\n      for(var x=0;x<V.sx;x++) {\n        for(var y=0;y<V.sy;y++) {\n          for(var i=0;i<V.depth;i++) {\n\n            var ai = V.get(x,y,i);\n\n            // normalize in a window of size n\n            var den = 0.0;\n            for(var j=Math.max(0,i-n2);j<=Math.min(i+n2,V.depth-1);j++) {\n              var aa = V.get(x,y,j);\n              den += aa*aa;\n            }\n            den *= this.alpha / this.n;\n            den += this.k;\n            this.S_cache_.set(x,y,i,den); // will be useful for backprop\n            den = Math.pow(den, this.beta);\n            A.set(x,y,i,ai/den);\n          }\n        }\n      }\n\n      this.out_act = A;\n      return this.out_act; // dummy identity function for now\n    },\n    backward: function() { \n      // evaluate gradient wrt data\n      var V = this.in_act; // we need to set dw of this\n      V.dw = global.zeros(V.w.length); // zero out gradient wrt data\n      var A = this.out_act; // computed in forward pass \n\n      var n2 = Math.floor(this.n/2);\n      for(var x=0;x<V.sx;x++) {\n        for(var y=0;y<V.sy;y++) {\n          for(var i=0;i<V.depth;i++) {\n\n            var chain_grad = this.out_act.get_grad(x,y,i);\n            var S = this.S_cache_.get(x,y,i);\n            var SB = Math.pow(S, this.beta);\n            var SB2 = SB*SB;\n\n            // normalize in a window of size n\n            for(var j=Math.max(0,i-n2);j<=Math.min(i+n2,V.depth-1);j++) {              \n              var aj = V.get(x,y,j); \n              var g = -aj*this.beta*Math.pow(S,this.beta-1)*this.alpha/this.n*2*aj;\n              if(j===i) g+= SB;\n              g /= SB2;\n              g *= chain_grad;\n              V.add_grad(x,y,j,g);\n            }\n\n          }\n        }\n      }\n    },\n    getParamsAndGrads: function() { return []; },\n    toJSON: function() {\n      var json = {};\n      json.k = this.k;\n      json.n = this.n;\n      json.alpha = this.alpha; // normalize by size\n      json.beta = this.beta;\n      json.out_sx = this.out_sx; \n      json.out_sy = this.out_sy;\n      json.out_depth = this.out_depth;\n      json.layer_type = this.layer_type;\n      return json;\n    },\n    fromJSON: function(json) {\n      this.k = json.k;\n      this.n = json.n;\n      this.alpha = json.alpha; // normalize by size\n      this.beta = json.beta;\n      this.out_sx = json.out_sx; \n      this.out_sy = json.out_sy;\n      this.out_depth = json.out_depth;\n      this.layer_type = json.layer_type;\n    }\n  }\n  \n\n  global.LocalResponseNormalizationLayer = LocalResponseNormalizationLayer;\n})(convnetjs);\n(function(global) {\n  \"use strict\";\n  var Vol = global.Vol; // convenience\n\n  // transforms x-> [x, x_i*x_j forall i,j]\n  // so the fully connected layer afters will essentially be doing tensor multiplies\n  var QuadTransformLayer = function(opt) {\n    var opt = opt || {};\n\n    // computed\n    this.out_sx = opt.in_sx;\n    this.out_sy = opt.in_sy;\n    // linear terms, and then quadratic terms, of which there are 1/2*n*(n+1),\n    // (offdiagonals and the diagonal total) and arithmetic series.\n    // Actually never mind, lets not be fancy here yet and just include\n    // terms x_ix_j and x_jx_i twice. Half as efficient but much less\n    // headache.\n    this.out_depth = opt.in_depth + opt.in_depth * opt.in_depth;\n    this.layer_type = 'quadtransform';\n\n  }\n  QuadTransformLayer.prototype = {\n    forward: function(V, is_training) {\n      this.in_act = V;\n      var N = this.out_depth;\n      var Ni = V.depth;\n      var V2 = new Vol(this.out_sx, this.out_sy, this.out_depth, 0.0);\n      for(var x=0;x<V.sx;x++) {\n        for(var y=0;y<V.sy;y++) {\n          for(var i=0;i<N;i++) {\n            if(i<Ni) {\n              V2.set(x,y,i,V.get(x,y,i)); // copy these over (linear terms)\n            } else {\n              var i0 = Math.floor((i-Ni)/Ni);\n              var i1 = (i-Ni) - i0*Ni;\n              V2.set(x,y,i,V.get(x,y,i0) * V.get(x,y,i1)); // quadratic\n            }\n          }\n        }\n      }\n      this.out_act = V2;\n      return this.out_act; // dummy identity function for now\n    },\n    backward: function() {\n      var V = this.in_act;\n      V.dw = global.zeros(V.w.length); // zero out gradient wrt data\n      var V2 = this.out_act;\n      var N = this.out_depth;\n      var Ni = V.depth;\n      for(var x=0;x<V.sx;x++) {\n        for(var y=0;y<V.sy;y++) {\n          for(var i=0;i<N;i++) {\n            var chain_grad = V2.get_grad(x,y,i);\n            if(i<Ni) {\n              V.add_grad(x,y,i,chain_grad);\n            } else {\n              var i0 = Math.floor((i-Ni)/Ni);\n              var i1 = (i-Ni) - i0*Ni;\n              V.add_grad(x,y,i0,V.get(x,y,i1)*chain_grad);\n              V.add_grad(x,y,i1,V.get(x,y,i0)*chain_grad);\n            }\n          }\n        }\n      }\n    },\n    getParamsAndGrads: function() {\n      return [];\n    },\n    toJSON: function() {\n      var json = {};\n      json.out_depth = this.out_depth;\n      json.out_sx = this.out_sx;\n      json.out_sy = this.out_sy;\n      json.layer_type = this.layer_type;\n      return json;\n    },\n    fromJSON: function(json) {\n      this.out_depth = json.out_depth;\n      this.out_sx = json.out_sx;\n      this.out_sy = json.out_sy;\n      this.layer_type = json.layer_type; \n    }\n  }\n  \n\n  global.QuadTransformLayer = QuadTransformLayer;\n})(convnetjs);\n(function(global) {\n  \"use strict\";\n  var Vol = global.Vol; // convenience\n  \n  // Net manages a set of layers\n  // For now constraints: Simple linear order of layers, first layer input last layer a cost layer\n  var Net = function(options) {\n    this.layers = [];\n  }\n\n  Net.prototype = {\n    \n    // takes a list of layer definitions and creates the network layer objects\n    makeLayers: function(defs) {\n\n      // few checks for now\n      if(defs.length<2) {console.log('ERROR! For now at least have input and softmax layers.');}\n      if(defs[0].type !== 'input') {console.log('ERROR! For now first layer should be input.');}\n\n      // desugar syntactic for adding activations and dropouts\n      var desugar = function() {\n        var new_defs = [];\n        for(var i=0;i<defs.length;i++) {\n          var def = defs[i];\n          \n          if(def.type==='softmax' || def.type==='svm') {\n            // add an fc layer here, there is no reason the user should\n            // have to worry about this and we almost always want to\n            new_defs.push({type:'fc', num_neurons: def.num_classes});\n          }\n\n          if(def.type==='regression') {\n            // add an fc layer here, there is no reason the user should\n            // have to worry about this and we almost always want to\n            new_defs.push({type:'fc', num_neurons: def.num_neurons});\n          }\n\n          if((def.type==='fc' || def.type==='conv') \n              && typeof(def.bias_pref) === 'undefined'){\n            def.bias_pref = 0.0;\n            if(typeof def.activation !== 'undefined' && def.activation === 'relu') {\n              def.bias_pref = 0.1; // relus like a bit of positive bias to get gradients early\n              // otherwise it's technically possible that a relu unit will never turn on (by chance)\n              // and will never get any gradient and never contribute any computation. Dead relu.\n            }\n          }\n          \n          if(typeof def.tensor !== 'undefined') {\n            // apply quadratic transform so that the upcoming multiply will include\n            // quadratic terms, equivalent to doing a tensor product\n            if(def.tensor) {\n              new_defs.push({type: 'quadtransform'});\n            }\n          }\n\n          new_defs.push(def);\n\n          if(typeof def.activation !== 'undefined') {\n            if(def.activation==='relu') { new_defs.push({type:'relu'}); }\n            else if (def.activation==='sigmoid') { new_defs.push({type:'sigmoid'}); }\n            else if (def.activation==='tanh') { new_defs.push({type:'tanh'}); }\n            else if (def.activation==='maxout') {\n              // create maxout activation, and pass along group size, if provided\n              var gs = def.group_size !== 'undefined' ? def.group_size : 2;\n              new_defs.push({type:'maxout', group_size:gs});\n            }\n            else { console.log('ERROR unsupported activation ' + def.activation); }\n          }\n          if(typeof def.drop_prob !== 'undefined' && def.type !== 'dropout') {\n            new_defs.push({type:'dropout', drop_prob: def.drop_prob});\n          }\n\n        }\n        return new_defs;\n      }\n      defs = desugar(defs);\n\n      // create the layers\n      this.layers = [];\n      for(var i=0;i<defs.length;i++) {\n        var def = defs[i];\n        if(i>0) {\n          var prev = this.layers[i-1];\n          def.in_sx = prev.out_sx;\n          def.in_sy = prev.out_sy;\n          def.in_depth = prev.out_depth;\n        }\n\n        switch(def.type) {\n          case 'fc': this.layers.push(new global.FullyConnLayer(def)); break;\n          case 'lrn': this.layers.push(new global.LocalResponseNormalizationLayer(def)); break;\n          case 'dropout': this.layers.push(new global.DropoutLayer(def)); break;\n          case 'input': this.layers.push(new global.InputLayer(def)); break;\n          case 'softmax': this.layers.push(new global.SoftmaxLayer(def)); break;\n          case 'regression': this.layers.push(new global.RegressionLayer(def)); break;\n          case 'conv': this.layers.push(new global.ConvLayer(def)); break;\n          case 'pool': this.layers.push(new global.PoolLayer(def)); break;\n          case 'relu': this.layers.push(new global.ReluLayer(def)); break;\n          case 'sigmoid': this.layers.push(new global.SigmoidLayer(def)); break;\n          case 'tanh': this.layers.push(new global.TanhLayer(def)); break;\n          case 'maxout': this.layers.push(new global.MaxoutLayer(def)); break;\n          case 'quadtransform': this.layers.push(new global.QuadTransformLayer(def)); break;\n          case 'svm': this.layers.push(new global.SVMLayer(def)); break;\n          default: console.log('ERROR: UNRECOGNIZED LAYER TYPE!');\n        }\n      }\n    },\n\n    // forward prop the network. A trainer will pass in is_training = true\n    forward: function(V, is_training) {\n      if(typeof(is_training)==='undefined') is_training = false;\n      var act = this.layers[0].forward(V, is_training);\n      for(var i=1;i<this.layers.length;i++) {\n        act = this.layers[i].forward(act, is_training);\n      }\n      return act;\n    },\n\n    getCostLoss: function(V, y) {\n      this.forward(V, false);\n      var N = this.layers.length;\n      var loss = this.layers[N-1].backward(y);\n      return loss;\n    },\n    \n    // backprop: compute gradients wrt all parameters\n    backward: function(y) {\n      var N = this.layers.length;\n      var loss = this.layers[N-1].backward(y); // last layer assumed softmax\n      for(var i=N-2;i>=0;i--) { // first layer assumed input\n        this.layers[i].backward();\n      }\n      return loss;\n    },\n    getParamsAndGrads: function() {\n      // accumulate parameters and gradients for the entire network\n      var response = [];\n      for(var i=0;i<this.layers.length;i++) {\n        var layer_reponse = this.layers[i].getParamsAndGrads();\n        for(var j=0;j<layer_reponse.length;j++) {\n          response.push(layer_reponse[j]);\n        }\n      }\n      return response;\n    },\n    getPrediction: function() {\n      var S = this.layers[this.layers.length-1]; // softmax layer\n      var p = S.out_act.w;\n      var maxv = p[0];\n      var maxi = 0;\n      for(var i=1;i<p.length;i++) {\n        if(p[i] > maxv) { maxv = p[i]; maxi = i;}\n      }\n      return maxi;\n    },\n    toJSON: function() {\n      var json = {};\n      json.layers = [];\n      for(var i=0;i<this.layers.length;i++) {\n        json.layers.push(this.layers[i].toJSON());\n      }\n      return json;\n    },\n    fromJSON: function(json) {\n      this.layers = [];\n      for(var i=0;i<json.layers.length;i++) {\n        var Lj = json.layers[i]\n        var t = Lj.layer_type;\n        var L;\n        if(t==='input') { L = new global.InputLayer(); }\n        if(t==='relu') { L = new global.ReluLayer(); }\n        if(t==='sigmoid') { L = new global.SigmoidLayer(); }\n        if(t==='tanh') { L = new global.TanhLayer(); }\n        if(t==='dropout') { L = new global.DropoutLayer(); }\n        if(t==='conv') { L = new global.ConvLayer(); }\n        if(t==='pool') { L = new global.PoolLayer(); }\n        if(t==='lrn') { L = new global.LocalResponseNormalizationLayer(); }\n        if(t==='softmax') { L = new global.SoftmaxLayer(); }\n        if(t==='regression') { L = new global.RegressionLayer(); }\n        if(t==='fc') { L = new global.FullyConnLayer(); }\n        if(t==='maxout') { L = new global.MaxoutLayer(); }\n        if(t==='quadtransform') { L = new global.QuadTransformLayer(); }\n        if(t==='svm') { L = new global.SVMLayer(); }\n        L.fromJSON(Lj);\n        this.layers.push(L);\n      }\n    }\n  }\n  \n\n  global.Net = Net;\n})(convnetjs);\n(function(global) {\n  \"use strict\";\n  var Vol = global.Vol; // convenience\n\n  var Trainer = function(net, options) {\n\n    this.net = net;\n\n    var options = options || {};\n    this.learning_rate = typeof options.learning_rate !== 'undefined' ? options.learning_rate : 0.01;\n    this.l1_decay = typeof options.l1_decay !== 'undefined' ? options.l1_decay : 0.0;\n    this.l2_decay = typeof options.l2_decay !== 'undefined' ? options.l2_decay : 0.0;\n    this.batch_size = typeof options.batch_size !== 'undefined' ? options.batch_size : 1;\n    this.method = typeof options.method !== 'undefined' ? options.method : 'sgd'; // sgd/adagrad/adadelta/windowgrad\n\n    this.momentum = typeof options.momentum !== 'undefined' ? options.momentum : 0.9;\n    this.ro = typeof options.ro !== 'undefined' ? options.ro : 0.95; // used in adadelta\n    this.eps = typeof options.eps !== 'undefined' ? options.eps : 1e-6; // used in adadelta\n\n    this.k = 0; // iteration counter\n    this.gsum = []; // last iteration gradients (used for momentum calculations)\n    this.xsum = []; // used in adadelta\n  }\n\n  Trainer.prototype = {\n    train: function(x, y) {\n\n      var start = new Date().getTime();\n      this.net.forward(x, true); // also set the flag that lets the net know we're just training\n      var end = new Date().getTime();\n      var fwd_time = end - start;\n\n      var start = new Date().getTime();\n      var cost_loss = this.net.backward(y);\n      var l2_decay_loss = 0.0;\n      var l1_decay_loss = 0.0;\n      var end = new Date().getTime();\n      var bwd_time = end - start;\n      \n      this.k++;\n      if(this.k % this.batch_size === 0) {\n\n        var pglist = this.net.getParamsAndGrads();\n\n        // initialize lists for accumulators. Will only be done once on first iteration\n        if(this.gsum.length === 0 && (this.method !== 'sgd' || this.momentum > 0.0)) {\n          // only vanilla sgd doesnt need either lists\n          // momentum needs gsum\n          // adagrad needs gsum\n          // adadelta needs gsum and xsum\n          for(var i=0;i<pglist.length;i++) {\n            this.gsum.push(global.zeros(pglist[i].params.length));\n            if(this.method === 'adadelta') {\n              this.xsum.push(global.zeros(pglist[i].params.length));\n            } else {\n              this.xsum.push([]); // conserve memory\n            }\n          }\n        }\n\n        // perform an update for all sets of weights\n        for(var i=0;i<pglist.length;i++) {\n          var pg = pglist[i]; // param, gradient, other options in future (custom learning rate etc)\n          var p = pg.params;\n          var g = pg.grads;\n\n          // learning rate for some parameters.\n          var l2_decay_mul = typeof pg.l2_decay_mul !== 'undefined' ? pg.l2_decay_mul : 1.0;\n          var l1_decay_mul = typeof pg.l1_decay_mul !== 'undefined' ? pg.l1_decay_mul : 1.0;\n          var l2_decay = this.l2_decay * l2_decay_mul;\n          var l1_decay = this.l1_decay * l1_decay_mul;\n\n          var plen = p.length;\n          for(var j=0;j<plen;j++) {\n            l2_decay_loss += l2_decay*p[j]*p[j]/2; // accumulate weight decay loss\n            l1_decay_loss += l1_decay*Math.abs(p[j]);\n            var l1grad = l1_decay * (p[j] > 0 ? 1 : -1);\n            var l2grad = l2_decay * (p[j]);\n\n            var gij = (l2grad + l1grad + g[j]) / this.batch_size; // raw batch gradient\n\n            var gsumi = this.gsum[i];\n            var xsumi = this.xsum[i];\n            if(this.method === 'adagrad') {\n              // adagrad update\n              gsumi[j] = gsumi[j] + gij * gij;\n              var dx = - this.learning_rate / Math.sqrt(gsumi[j] + this.eps) * gij;\n              p[j] += dx;\n            } else if(this.method === 'windowgrad') {\n              // this is adagrad but with a moving window weighted average\n              // so the gradient is not accumulated over the entire history of the run. \n              // it's also referred to as Idea #1 in Zeiler paper on Adadelta. Seems reasonable to me!\n              gsumi[j] = this.ro * gsumi[j] + (1-this.ro) * gij * gij;\n              var dx = - this.learning_rate / Math.sqrt(gsumi[j] + this.eps) * gij; // eps added for better conditioning\n              p[j] += dx;\n            } else if(this.method === 'adadelta') {\n              // assume adadelta if not sgd or adagrad\n              gsumi[j] = this.ro * gsumi[j] + (1-this.ro) * gij * gij;\n              var dx = - Math.sqrt((xsumi[j] + this.eps)/(gsumi[j] + this.eps)) * gij;\n              xsumi[j] = this.ro * xsumi[j] + (1-this.ro) * dx * dx; // yes, xsum lags behind gsum by 1.\n              p[j] += dx;\n            } else {\n              // assume SGD\n              if(this.momentum > 0.0) {\n                // momentum update\n                var dx = this.momentum * gsumi[j] - this.learning_rate * gij; // step\n                gsumi[j] = dx; // back this up for next iteration of momentum\n                p[j] += dx; // apply corrected gradient\n              } else {\n                // vanilla sgd\n                p[j] +=  - this.learning_rate * gij;\n              }\n            }\n            g[j] = 0.0; // zero out gradient so that we can begin accumulating anew\n          }\n        }\n      }\n\n      // appending softmax_loss for backwards compatibility, but from now on we will always use cost_loss\n      // in future, TODO: have to completely redo the way loss is done around the network as currently \n      // loss is a bit of a hack. Ideally, user should specify arbitrary number of loss functions on any layer\n      // and it should all be computed correctly and automatically. \n      return {fwd_time: fwd_time, bwd_time: bwd_time, \n              l2_decay_loss: l2_decay_loss, l1_decay_loss: l1_decay_loss,\n              cost_loss: cost_loss, softmax_loss: cost_loss, \n              loss: cost_loss + l1_decay_loss + l2_decay_loss}\n    }\n  }\n  \n  global.Trainer = Trainer;\n  global.SGDTrainer = Trainer; // backwards compatibility\n})(convnetjs);\n\n(function(global) {\n  \"use strict\";\n\n  // used utilities, make explicit local references\n  var randf = global.randf;\n  var randi = global.randi;\n  var Net = global.Net;\n  var Trainer = global.Trainer;\n  var maxmin = global.maxmin;\n  var randperm = global.randperm;\n  var weightedSample = global.weightedSample;\n  var getopt = global.getopt;\n  var arrUnique = global.arrUnique;\n\n  /*\n  A MagicNet takes data: a list of convnetjs.Vol(), and labels\n  which for now are assumed to be class indeces 0..K. MagicNet then:\n  - creates data folds for cross-validation\n  - samples candidate networks\n  - evaluates candidate networks on all data folds\n  - produces predictions by model-averaging the best networks\n  */\n  var MagicNet = function(data, labels, opt) {\n    var opt = opt || {};\n    if(typeof data === 'undefined') { data = []; }\n    if(typeof labels === 'undefined') { labels = []; }\n\n    // required inputs\n    this.data = data; // store these pointers to data\n    this.labels = labels;\n\n    // optional inputs\n    this.train_ratio = getopt(opt, 'train_ratio', 0.7);\n    this.num_folds = getopt(opt, 'num_folds', 10);\n    this.num_candidates = getopt(opt, 'num_candidates', 50); // we evaluate several in parallel\n    // how many epochs of data to train every network? for every fold?\n    // higher values mean higher accuracy in final results, but more expensive\n    this.num_epochs = getopt(opt, 'num_epochs', 50); \n    // number of best models to average during prediction. Usually higher = better\n    this.ensemble_size = getopt(opt, 'ensemble_size', 10);\n\n    // candidate parameters\n    this.batch_size_min = getopt(opt, 'batch_size_min', 10);\n    this.batch_size_max = getopt(opt, 'batch_size_max', 300);\n    this.l2_decay_min = getopt(opt, 'l2_decay_min', -4);\n    this.l2_decay_max = getopt(opt, 'l2_decay_max', 2);\n    this.learning_rate_min = getopt(opt, 'learning_rate_min', -4);\n    this.learning_rate_max = getopt(opt, 'learning_rate_max', 0);\n    this.momentum_min = getopt(opt, 'momentum_min', 0.9);\n    this.momentum_max = getopt(opt, 'momentum_max', 0.9);\n    this.neurons_min = getopt(opt, 'neurons_min', 5);\n    this.neurons_max = getopt(opt, 'neurons_max', 30);\n\n    // computed\n    this.folds = []; // data fold indices, gets filled by sampleFolds()\n    this.candidates = []; // candidate networks that are being currently evaluated\n    this.evaluated_candidates = []; // history of all candidates that were fully evaluated on all folds\n    this.unique_labels = arrUnique(labels);\n    this.iter = 0; // iteration counter, goes from 0 -> num_epochs * num_training_data\n    this.foldix = 0; // index of active fold\n\n    // callbacks\n    this.finish_fold_callback = null;\n    this.finish_batch_callback = null;\n\n    // initializations\n    if(this.data.length > 0) {\n      this.sampleFolds();\n      this.sampleCandidates();\n    }\n  };\n\n  MagicNet.prototype = {\n\n    // sets this.folds to a sampling of this.num_folds folds\n    sampleFolds: function() {\n      var N = this.data.length;\n      var num_train = Math.floor(this.train_ratio * N);\n      this.folds = []; // flush folds, if any\n      for(var i=0;i<this.num_folds;i++) {\n        var p = randperm(N);\n        this.folds.push({train_ix: p.slice(0, num_train), test_ix: p.slice(num_train, N)});\n      }\n    },\n\n    // returns a random candidate network\n    sampleCandidate: function() {\n      var input_depth = this.data[0].w.length;\n      var num_classes = this.unique_labels.length;\n\n      // sample network topology and hyperparameters\n      var layer_defs = [];\n      layer_defs.push({type:'input', out_sx:1, out_sy:1, out_depth: input_depth});\n      var nl = weightedSample([0,1,2,3], [0.2, 0.3, 0.3, 0.2]); // prefer nets with 1,2 hidden layers\n      for(var q=0;q<nl;q++) {\n        var ni = randi(this.neurons_min, this.neurons_max);\n        var act = ['tanh','maxout','relu'][randi(0,3)];\n        if(randf(0,1)<0.5) {\n          var dp = Math.random();\n          layer_defs.push({type:'fc', num_neurons: ni, activation: act, drop_prob: dp});\n        } else {\n          layer_defs.push({type:'fc', num_neurons: ni, activation: act});\n        }\n      }\n      layer_defs.push({type:'softmax', num_classes: num_classes});\n      var net = new Net();\n      net.makeLayers(layer_defs);\n\n      // sample training hyperparameters\n      var bs = randi(this.batch_size_min, this.batch_size_max); // batch size\n      var l2 = Math.pow(10, randf(this.l2_decay_min, this.l2_decay_max)); // l2 weight decay\n      var lr = Math.pow(10, randf(this.learning_rate_min, this.learning_rate_max)); // learning rate\n      var mom = randf(this.momentum_min, this.momentum_max); // momentum. Lets just use 0.9, works okay usually ;p\n      var tp = randf(0,1); // trainer type\n      var trainer_def;\n      if(tp<0.33) {\n        trainer_def = {method:'adadelta', batch_size:bs, l2_decay:l2};\n      } else if(tp<0.66) {\n        trainer_def = {method:'adagrad', learning_rate: lr, batch_size:bs, l2_decay:l2};\n      } else {\n        trainer_def = {method:'sgd', learning_rate: lr, momentum: mom, batch_size:bs, l2_decay:l2};\n      }\n      \n      var trainer = new Trainer(net, trainer_def);\n\n      var cand = {};\n      cand.acc = [];\n      cand.accv = 0; // this will maintained as sum(acc) for convenience\n      cand.layer_defs = layer_defs;\n      cand.trainer_def = trainer_def;\n      cand.net = net;\n      cand.trainer = trainer;\n      return cand;\n    },\n\n    // sets this.candidates with this.num_candidates candidate nets\n    sampleCandidates: function() {\n      this.candidates = []; // flush, if any\n      for(var i=0;i<this.num_candidates;i++) {\n        var cand = this.sampleCandidate();\n        this.candidates.push(cand);\n      }\n    },\n\n    step: function() {\n      \n      // run an example through current candidate\n      this.iter++;\n\n      // step all candidates on a random data point\n      var fold = this.folds[this.foldix]; // active fold\n      var dataix = fold.train_ix[randi(0, fold.train_ix.length)];\n      for(var k=0;k<this.candidates.length;k++) {\n        var x = this.data[dataix];\n        var l = this.labels[dataix];\n        this.candidates[k].trainer.train(x, l);\n      }\n\n      // process consequences: sample new folds, or candidates\n      var lastiter = this.num_epochs * fold.train_ix.length;\n      if(this.iter >= lastiter) {\n        // finished evaluation of this fold. Get final validation\n        // accuracies, record them, and go on to next fold.\n        var val_acc = this.evalValErrors();\n        for(var k=0;k<this.candidates.length;k++) {\n          var c = this.candidates[k];\n          c.acc.push(val_acc[k]);\n          c.accv += val_acc[k];\n        }\n        this.iter = 0; // reset step number\n        this.foldix++; // increment fold\n\n        if(this.finish_fold_callback !== null) {\n          this.finish_fold_callback();\n        }\n\n        if(this.foldix >= this.folds.length) {\n          // we finished all folds as well! Record these candidates\n          // and sample new ones to evaluate.\n          for(var k=0;k<this.candidates.length;k++) {\n            this.evaluated_candidates.push(this.candidates[k]);\n          }\n          // sort evaluated candidates according to accuracy achieved\n          this.evaluated_candidates.sort(function(a, b) { \n            return (a.accv / a.acc.length) \n                 > (b.accv / b.acc.length) \n                 ? -1 : 1;\n          });\n          // and clip only to the top few ones (lets place limit at 3*ensemble_size)\n          // otherwise there are concerns with keeping these all in memory \n          // if MagicNet is being evaluated for a very long time\n          if(this.evaluated_candidates.length > 3 * this.ensemble_size) {\n            this.evaluated_candidates = this.evaluated_candidates.slice(0, 3 * this.ensemble_size);\n          }\n          if(this.finish_batch_callback !== null) {\n            this.finish_batch_callback();\n          }\n          this.sampleCandidates(); // begin with new candidates\n          this.foldix = 0; // reset this\n        } else {\n          // we will go on to another fold. reset all candidates nets\n          for(var k=0;k<this.candidates.length;k++) {\n            var c = this.candidates[k];\n            var net = new Net();\n            net.makeLayers(c.layer_defs);\n            var trainer = new Trainer(net, c.trainer_def);\n            c.net = net;\n            c.trainer = trainer;\n          }\n        }\n      }\n    },\n\n    evalValErrors: function() {\n      // evaluate candidates on validation data and return performance of current networks\n      // as simple list\n      var vals = [];\n      var fold = this.folds[this.foldix]; // active fold\n      for(var k=0;k<this.candidates.length;k++) {\n        var net = this.candidates[k].net;\n        var v = 0.0;\n        for(var q=0;q<fold.test_ix.length;q++) {\n          var x = this.data[fold.test_ix[q]];\n          var l = this.labels[fold.test_ix[q]];\n          net.forward(x);\n          var yhat = net.getPrediction();\n          v += (yhat === l ? 1.0 : 0.0); // 0 1 loss\n        }\n        v /= fold.test_ix.length; // normalize\n        vals.push(v);\n      }\n      return vals;\n    },\n\n    // returns prediction scores for given test data point, as Vol\n    // uses an averaged prediction from the best ensemble_size models\n    // x is a Vol.\n    predict_soft: function(data) {\n      // forward prop the best networks\n      // and accumulate probabilities at last layer into a an output Vol\n      var nv = Math.min(this.ensemble_size, this.evaluated_candidates.length);\n      if(nv === 0) { return new convnetjs.Vol(0,0,0); } // not sure what to do here? we're not ready yet\n      var xout, n;\n      for(var j=0;j<nv;j++) {\n        var net = this.evaluated_candidates[j].net;\n        var x = net.forward(data);\n        if(j===0) { \n          xout = x; \n          n = x.w.length; \n        } else {\n          // add it on\n          for(var d=0;d<n;d++) {\n            xout.w[d] += x.w[d];\n          }\n        }\n      }\n      // produce average\n      for(var d=0;d<n;d++) {\n        xout.w[d] /= n;\n      }\n      return xout;\n    },\n\n    predict: function(data) {\n      var xout = this.predict_soft(data);\n      if(xout.w.length !== 0) {\n        var stats = maxmin(xout.w);\n        var predicted_label = stats.maxi; \n      } else {\n        var predicted_label = -1; // error out\n      }\n      return predicted_label;\n\n    },\n\n    toJSON: function() {\n      // dump the top ensemble_size networks as a list\n      var nv = Math.min(this.ensemble_size, this.evaluated_candidates.length);\n      var json = {};\n      json.nets = [];\n      for(var i=0;i<nv;i++) {\n        json.nets.push(this.evaluated_candidates[i].net.toJSON());\n      }\n      return json;\n    },\n\n    fromJSON: function(json) {\n      this.ensemble_size = json.nets.length;\n      this.evaluated_candidates = [];\n      for(var i=0;i<this.ensemble_size;i++) {\n        var net = new Net();\n        net.fromJSON(json.nets[i]);\n        var dummy_candidate = {};\n        dummy_candidate.net = net;\n        this.evaluated_candidates.push(dummy_candidate);\n      }\n    },\n\n    // callback functions\n    // called when a fold is finished, while evaluating a batch\n    onFinishFold: function(f) { this.finish_fold_callback = f; },\n    // called when a batch of candidates has finished evaluating\n    onFinishBatch: function(f) { this.finish_batch_callback = f; }\n    \n  };\n\n  global.MagicNet = MagicNet;\n})(convnetjs);\n(function(lib) {\n  \"use strict\";\n  if (typeof module === \"undefined\" || typeof module.exports === \"undefined\") {\n    window.jsfeat = lib; // in ordinary browser attach library to window\n  } else {\n    module.exports = lib; // in nodejs\n  }\n})(convnetjs);\n"
  },
  {
    "path": "lib/convnetjs/deepqlearn.js",
    "content": "var deepqlearn = deepqlearn || { REVISION: 'ALPHA' };\r\n\r\n(function(global) {\r\n  \"use strict\";\r\n  \r\n  // An agent is in state0 and does action0\r\n  // environment then assigns reward0 and provides new state, state1\r\n  // Experience nodes store all this information, which is used in the\r\n  // Q-learning update step\r\n  var Experience = function(state0, action0, reward0, state1) {\r\n    this.state0 = state0;\r\n    this.action0 = action0;\r\n    this.reward0 = reward0;\r\n    this.state1 = state1;\r\n  }\r\n\r\n  // A Brain object does all the magic.\r\n  // over time it receives some inputs and some rewards\r\n  // and its job is to set the outputs to maximize the expected reward\r\n  var Brain = function(num_states, num_actions, opt) {\r\n    var opt = opt || {};\r\n    // in number of time steps, of temporal memory\r\n    // the ACTUAL input to the net will be (x,a) temporal_window times, and followed by current x\r\n    // so to have no information from previous time step going into value function, set to 0.\r\n    this.temporal_window = typeof opt.temporal_window !== 'undefined' ? opt.temporal_window : 1; \r\n    // size of experience replay memory\r\n    this.experience_size = typeof opt.experience_size !== 'undefined' ? opt.experience_size : 30000;\r\n    // number of examples in experience replay memory before we begin learning\r\n    this.start_learn_threshold = typeof opt.start_learn_threshold !== 'undefined'? opt.start_learn_threshold : Math.floor(Math.min(this.experience_size*0.1, 1000)); \r\n    // gamma is a crucial parameter that controls how much plan-ahead the agent does. In [0,1]\r\n    this.gamma = typeof opt.gamma !== 'undefined' ? opt.gamma : 0.8;\r\n    \r\n    // number of steps we will learn for\r\n    this.learning_steps_total = typeof opt.learning_steps_total !== 'undefined' ? opt.learning_steps_total : 100000;\r\n    // how many steps of the above to perform only random actions (in the beginning)?\r\n    this.learning_steps_burnin = typeof opt.learning_steps_burnin !== 'undefined' ? opt.learning_steps_burnin : 3000;\r\n    // what epsilon value do we bottom out on? 0.0 => purely deterministic policy at end\r\n    this.epsilon_min = typeof opt.epsilon_min !== 'undefined' ? opt.epsilon_min : 0.05;\r\n    // what epsilon to use at test time? (i.e. when learning is disabled)\r\n    this.epsilon_test_time = typeof opt.epsilon_test_time !== 'undefined' ? opt.epsilon_test_time : 0.01;\r\n    \r\n    // advanced feature. Sometimes a random action should be biased towards some values\r\n    // for example in flappy bird, we may want to choose to not flap more often\r\n    if(typeof opt.random_action_distribution !== 'undefined') {\r\n      // this better sum to 1 by the way, and be of length this.num_actions\r\n      this.random_action_distribution = opt.random_action_distribution;\r\n      if(this.random_action_distribution.length !== num_actions) {\r\n        console.log('TROUBLE. random_action_distribution should be same length as num_actions.');\r\n      }\r\n      var a = this.random_action_distribution;\r\n      var s = 0.0; for(var k=0;k<a.length;k++) { s+= a[k]; }\r\n      if(Math.abs(s-1.0)>0.0001) { console.log('TROUBLE. random_action_distribution should sum to 1!'); }\r\n    } else {\r\n      this.random_action_distribution = [];\r\n    }\r\n    \r\n    // states that go into neural net to predict optimal action look as\r\n    // x0,a0,x1,a1,x2,a2,...xt\r\n    // this variable controls the size of that temporal window. Actions are\r\n    // encoded as 1-of-k hot vectors\r\n    this.net_inputs = num_states * this.temporal_window + num_actions * this.temporal_window + num_states;\r\n    this.num_states = num_states;\r\n    this.num_actions = num_actions;\r\n    this.window_size = Math.max(this.temporal_window, 2); // must be at least 2, but if we want more context even more\r\n    this.state_window = new Array(this.window_size);\r\n    this.action_window = new Array(this.window_size);\r\n    this.reward_window = new Array(this.window_size);\r\n    this.net_window = new Array(this.window_size);\r\n    \r\n    // create [state -> value of all possible actions] modeling net for the value function\r\n    var layer_defs = [];\r\n    if(typeof opt.layer_defs !== 'undefined') {\r\n      // this is an advanced usage feature, because size of the input to the network, and number of\r\n      // actions must check out. This is not very pretty Object Oriented programming but I can't see\r\n      // a way out of it :(\r\n      layer_defs = opt.layer_defs;\r\n      if(layer_defs.length < 2) { console.log('TROUBLE! must have at least 2 layers'); }\r\n      if(layer_defs[0].type !== 'input') { console.log('TROUBLE! first layer must be input layer!'); }\r\n      if(layer_defs[layer_defs.length-1].type !== 'regression') { console.log('TROUBLE! last layer must be input regression!'); }\r\n      if(layer_defs[0].out_depth * layer_defs[0].out_sx * layer_defs[0].out_sy !== this.net_inputs) {\r\n        console.log('TROUBLE! Number of inputs must be num_states * temporal_window + num_actions * temporal_window + num_states!');\r\n      }\r\n      if(layer_defs[layer_defs.length-1].num_neurons !== this.num_actions) {\r\n        console.log('TROUBLE! Number of regression neurons should be num_actions!');\r\n      }\r\n    } else {\r\n      // create a very simple neural net by default\r\n      layer_defs.push({type:'input', out_sx:1, out_sy:1, out_depth:this.net_inputs});\r\n      if(typeof opt.hidden_layer_sizes !== 'undefined') {\r\n        // allow user to specify this via the option, for convenience\r\n        var hl = opt.hidden_layer_sizes;\r\n        for(var k=0;k<hl.length;k++) {\r\n          layer_defs.push({type:'fc', num_neurons:hl[k], activation:'relu'}); // relu by default\r\n        }\r\n      }\r\n      layer_defs.push({type:'regression', num_neurons:num_actions}); // value function output\r\n    }\r\n    this.value_net = new convnetjs.Net();\r\n    this.value_net.makeLayers(layer_defs);\r\n    \r\n    // and finally we need a Temporal Difference Learning trainer!\r\n    var tdtrainer_options = {learning_rate:0.01, momentum:0.0, batch_size:64, l2_decay:0.01};\r\n    if(typeof opt.tdtrainer_options !== 'undefined') {\r\n      tdtrainer_options = opt.tdtrainer_options; // allow user to overwrite this\r\n    }\r\n    this.tdtrainer = new convnetjs.SGDTrainer(this.value_net, tdtrainer_options);\r\n    \r\n    // experience replay\r\n    this.experience = [];\r\n    \r\n    // various housekeeping variables\r\n    this.age = 0; // incremented every backward()\r\n    this.forward_passes = 0; // incremented every forward()\r\n    this.epsilon = 1.0; // controls exploration exploitation tradeoff. Should be annealed over time\r\n    this.latest_reward = 0;\r\n    this.last_input_array = [];\r\n    this.average_reward_window = new cnnutil.Window(1000, 10);\r\n    this.average_loss_window = new cnnutil.Window(1000, 10);\r\n    this.learning = true;\r\n  }\r\n  Brain.prototype = {\r\n    random_action: function() {\r\n      // a bit of a helper function. It returns a random action\r\n      // we are abstracting this away because in future we may want to \r\n      // do more sophisticated things. For example some actions could be more\r\n      // or less likely at \"rest\"/default state.\r\n      if(this.random_action_distribution.length === 0) {\r\n        return convnetjs.randi(0, this.num_actions);\r\n      } else {\r\n        // okay, lets do some fancier sampling:\r\n        var p = convnetjs.randf(0, 1.0);\r\n        var cumprob = 0.0;\r\n        for(var k=0;k<this.num_actions;k++) {\r\n          cumprob += this.random_action_distribution[k];\r\n          if(p < cumprob) { return k; }\r\n        }\r\n      }\r\n    },\r\n    policy: function(s) {\r\n      // compute the value of doing any action in this state\r\n      // and return the argmax action and its value\r\n      var svol = new convnetjs.Vol(1, 1, this.net_inputs);\r\n      svol.w = s;\r\n      var action_values = this.value_net.forward(svol);\r\n      var maxk = 0; \r\n      var maxval = action_values.w[0];\r\n      for(var k=1;k<this.num_actions;k++) {\r\n        if(action_values.w[k] > maxval) { maxk = k; maxval = action_values.w[k]; }\r\n      }\r\n      return {action:maxk, value:maxval};\r\n    },\r\n    getNetInput: function(xt) {\r\n      // return s = (x,a,x,a,x,a,xt) state vector. \r\n      // It's a concatenation of last window_size (x,a) pairs and current state x\r\n      var w = [];\r\n      w = w.concat(xt); // start with current state\r\n      // and now go backwards and append states and actions from history temporal_window times\r\n      var n = this.window_size; \r\n      for(var k=0;k<this.temporal_window;k++) {\r\n        // state\r\n        w = w.concat(this.state_window[n-1-k]);\r\n        // action, encoded as 1-of-k indicator vector. We scale it up a bit because\r\n        // we dont want weight regularization to undervalue this information, as it only exists once\r\n        var action1ofk = new Array(this.num_actions);\r\n        for(var q=0;q<this.num_actions;q++) action1ofk[q] = 0.0;\r\n        action1ofk[this.action_window[n-1-k]] = 1.0*this.num_states;\r\n        w = w.concat(action1ofk);\r\n      }\r\n      return w;\r\n    },\r\n    forward: function(input_array) {\r\n      // compute forward (behavior) pass given the input neuron signals from body\r\n      this.forward_passes += 1;\r\n      this.last_input_array = input_array; // back this up\r\n      \r\n      // create network input\r\n      var action;\r\n      if(this.forward_passes > this.temporal_window) {\r\n        // we have enough to actually do something reasonable\r\n        var net_input = this.getNetInput(input_array);\r\n        if(this.learning) {\r\n          // compute epsilon for the epsilon-greedy policy\r\n          this.epsilon = Math.min(1.0, Math.max(this.epsilon_min, 1.0-(this.age - this.learning_steps_burnin)/(this.learning_steps_total - this.learning_steps_burnin))); \r\n        } else {\r\n          this.epsilon = this.epsilon_test_time; // use test-time value\r\n        }\r\n        var rf = convnetjs.randf(0,1);\r\n        if(rf < this.epsilon) {\r\n          // choose a random action with epsilon probability\r\n          action = this.random_action();\r\n        } else {\r\n          // otherwise use our policy to make decision\r\n          var maxact = this.policy(net_input);\r\n          action = maxact.action;\r\n       }\r\n      } else {\r\n        // pathological case that happens first few iterations \r\n        // before we accumulate window_size inputs\r\n        var net_input = [];\r\n        action = this.random_action();\r\n      }\r\n      \r\n      // remember the state and action we took for backward pass\r\n      this.net_window.shift();\r\n      this.net_window.push(net_input);\r\n      this.state_window.shift(); \r\n      this.state_window.push(input_array);\r\n      this.action_window.shift(); \r\n      this.action_window.push(action);\r\n      \r\n      return action;\r\n    },\r\n    backward: function(reward) {\r\n      this.latest_reward = reward;\r\n      this.average_reward_window.add(reward);\r\n      this.reward_window.shift();\r\n      this.reward_window.push(reward);\r\n      \r\n      if(!this.learning) { return; } \r\n      \r\n      // various book-keeping\r\n      this.age += 1;\r\n      \r\n      // it is time t+1 and we have to store (s_t, a_t, r_t, s_{t+1}) as new experience\r\n      // (given that an appropriate number of state measurements already exist, of course)\r\n      if(this.forward_passes > this.temporal_window + 1) {\r\n        var e = new Experience();\r\n        var n = this.window_size;\r\n        e.state0 = this.net_window[n-2];\r\n        e.action0 = this.action_window[n-2];\r\n        e.reward0 = this.reward_window[n-2];\r\n        e.state1 = this.net_window[n-1];\r\n        if(this.experience.length < this.experience_size) {\r\n          this.experience.push(e);\r\n        } else {\r\n          // replace. finite memory!\r\n          var ri = convnetjs.randi(0, this.experience_size);\r\n          this.experience[ri] = e;\r\n        }\r\n      }\r\n      \r\n      // learn based on experience, once we have some samples to go on\r\n      // this is where the magic happens...\r\n      if(this.experience.length > this.start_learn_threshold) {\r\n        var avcost = 0.0;\r\n        for(var k=0;k < this.tdtrainer.batch_size;k++) {\r\n          var re = convnetjs.randi(0, this.experience.length);\r\n          var e = this.experience[re];\r\n          var x = new convnetjs.Vol(1, 1, this.net_inputs);\r\n          x.w = e.state0;\r\n          var maxact = this.policy(e.state1);\r\n          var r = e.reward0 + this.gamma * maxact.value;\r\n          var ystruct = {dim: e.action0, val: r};\r\n          var loss = this.tdtrainer.train(x, ystruct);\r\n          avcost += loss.loss;\r\n        }\r\n        avcost = avcost/this.tdtrainer.batch_size;\r\n        this.average_loss_window.add(avcost);\r\n      }\r\n    },\r\n    visSelf: function(elt) {\r\n      elt.innerHTML = ''; // erase elt first\r\n      \r\n      // elt is a DOM element that this function fills with brain-related information\r\n      var brainvis = document.createElement('div');\r\n      \r\n      // basic information\r\n      var desc = document.createElement('div');\r\n      var t = '';\r\n      t += 'experience replay size: ' + this.experience.length + '<br>';\r\n      t += 'exploration epsilon: ' + this.epsilon + '<br>';\r\n      t += 'age: ' + this.age + '<br>';\r\n      t += 'average Q-learning loss: ' + this.average_loss_window.get_average() + '<br />';\r\n      t += 'smooth-ish reward: ' + Math.round(this.average_reward_window.get_average()*1000)/1000 + '<br />';\r\n      desc.innerHTML = t;\r\n      brainvis.appendChild(desc);\r\n      \r\n      elt.appendChild(brainvis);\r\n    }\r\n  }\r\n  \r\n  global.Brain = Brain;\r\n})(deepqlearn);\r\n\r\n(function(lib) {\r\n  \"use strict\";\r\n  if (typeof module === \"undefined\" || typeof module.exports === \"undefined\") {\r\n    window.deepqlearn = lib; // in ordinary browser attach library to window\r\n  } else {\r\n    module.exports = lib; // in nodejs\r\n  }\r\n})(deepqlearn);\r\n"
  },
  {
    "path": "lib/convnetjs/ga.js",
    "content": "\n/*    \n\nGA addon for convnet.js\n\n@licstart  The following is the entire license notice for the \nJavaScript code in this page.\n\nCopyright (C) 2015 david ha, otoro.net, otoro labs\n\nThe JavaScript code in this page is free software: you can\nredistribute it and/or modify it under the terms of the GNU\nGeneral Public License (GNU GPL) as published by the Free Software\nFoundation, either version 3 of the License, or (at your option)\nany later version.  The code is distributed WITHOUT ANY WARRANTY;\nwithout even the implied warranty of MERCHANTABILITY or FITNESS\nFOR A PARTICULAR PURPOSE.  See the GNU GPL for more details.\n\nAs additional permission under GNU GPL version 3 section 7, you\nmay distribute non-source (e.g., minimized or compacted) forms of\nthat code without the copy of the GNU GPL normally required by\nsection 4, provided you include this license notice and a URL\nthrough which recipients can access the Corresponding Source.   \n\n\n@licend  The above is the entire license notice\nfor the JavaScript code in this page.\n*/\n\n(function(global) {\n  \"use strict\";\n  var Vol = convnetjs.Vol; // convenience\n\n  // used utilities, make explicit local references\n  var randf = convnetjs.randf;\n  var randn = convnetjs.randn;\n  var randi = convnetjs.randi;\n  var zeros = convnetjs.zeros;\n  var Net = convnetjs.Net;\n  var maxmin = convnetjs.maxmin;\n  var randperm = convnetjs.randperm;\n  var weightedSample = convnetjs.weightedSample;\n  var getopt = convnetjs.getopt;\n  var arrUnique = convnetjs.arrUnique;\n\n  function assert(condition, message) {\n      if (!condition) {\n          message = message || \"Assertion failed\";\n          if (typeof Error !== \"undefined\") {\n              throw new Error(message);\n          }\n          throw message; // Fallback\n      }\n  }\n\n  // returns a random cauchy random variable with gamma (controls magnitude sort of like stdev in randn)\n  // http://en.wikipedia.org/wiki/Cauchy_distribution\n  var randc = function(m, gamma) {\n    return m + gamma * 0.01 * randn(0.0, 1.0) / randn(0.0, 1.0);\n  };\n\n  // chromosome implementation using an array of floats\n  var Chromosome = function(floatArray) {\n    this.fitness = 0; // default value\n    this.nTrial = 0; // number of trials subjected to so far.\n    this.gene = floatArray;\n  };\n\n  Chromosome.prototype = {\n    burst_mutate: function(burst_magnitude_) { // adds a normal random variable of stdev width, zero mean to each gene.\n      var burst_magnitude = burst_magnitude_ || 0.1;\n      var i, N;\n      N = this.gene.length;\n      for (i = 0; i < N; i++) {\n        this.gene[i] += randn(0.0, burst_magnitude);\n      }\n    },\n    randomize: function(burst_magnitude_) { // resets each gene to a random value with zero mean and stdev\n      var burst_magnitude = burst_magnitude_ || 0.1;\n      var i, N;\n      N = this.gene.length;\n      for (i = 0; i < N; i++) {\n        this.gene[i] = randn(0.0, burst_magnitude);\n      }\n    },\n    mutate: function(mutation_rate_, burst_magnitude_) { // adds random gaussian (0,stdev) to each gene with prob mutation_rate\n      var mutation_rate = mutation_rate_ || 0.1;\n      var burst_magnitude = burst_magnitude_ || 0.1;\n      var i, N;\n      N = this.gene.length;\n      for (i = 0; i < N; i++) {\n        if (randf(0,1) < mutation_rate) {\n          this.gene[i] += randn(0.0, burst_magnitude);\n        }\n      }\n    },\n    crossover: function(partner, kid1, kid2) { // performs one-point crossover with partner to produce 2 kids\n    //assumes all chromosomes are initialised with same array size. pls make sure of this before calling\n      var i, N;\n      N = this.gene.length;\n      var l = randi(0, N); // crossover point\n      for (i = 0; i < N; i++) {\n        if (i < l) {\n          kid1.gene[i] = this.gene[i];\n          kid2.gene[i] = partner.gene[i];\n        } else {\n          kid1.gene[i] = partner.gene[i];\n          kid2.gene[i] = this.gene[i];\n        }\n      }\n    },\n    copyFrom: function(c) { // copies c's gene into itself\n      var i, N;\n      this.copyFromGene(c.gene);\n    },\n    copyFromGene: function(gene) { // gene into itself\n      var i, N;\n      N = this.gene.length;\n      for (i = 0; i < N; i++) {\n        this.gene[i] = gene[i];\n      }\n    },\n    clone: function() { // returns an exact copy of itself (into new memory, doesn't return reference)\n      var newGene = zeros(this.gene.length);\n      var i;\n      for (i = 0; i < this.gene.length; i++) {\n        newGene[i] = Math.round(10000*this.gene[i])/10000;\n      }\n      var c = new Chromosome(newGene);\n      c.fitness = this.fitness;\n      return c;\n    },\n    pushToNetwork: function(net) { // pushes this chromosome to a specified network\n      pushGeneToNetwork(net, this.gene);\n    }\n  };\n\n  // counts the number of weights and biases in the network\n  function getNetworkSize(net) {\n    var layer = null;\n    var filter = null;\n    var bias = null;\n    var w = null;\n    var count = 0;\n    var i, j, k;\n    for ( i = 0; i < net.layers.length; i++) {\n      layer = net.layers[i];\n      filter = layer.filters;\n      if (filter) {\n        for ( j = 0; j < filter.length; j++) {\n          w = filter[j].w;\n          count += w.length;\n        }\n      }\n      bias = layer.biases;\n      if (bias) {\n        w = bias.w;\n        count += w.length;\n      }\n    }\n    return count;\n  }\n\n  function pushGeneToNetwork(net, gene) { // pushes the gene (floatArray) to fill up weights and biases in net\n    var count = 0;\n    var layer = null;\n    var filter = null;\n    var bias = null;\n    var w = null;\n    var i, j, k;\n    for ( i = 0; i < net.layers.length; i++) {\n      layer = net.layers[i];\n      filter = layer.filters;\n      if (filter) {\n        for ( j = 0; j < filter.length; j++) {\n          w = filter[j].w;\n          for ( k = 0; k < w.length; k++) {\n            w[k] = gene[count++];\n          }\n        }\n      }\n      bias = layer.biases;\n      if (bias) {\n        w = bias.w;\n        for ( k = 0; k < w.length; k++) {\n          w[k] = gene[count++];\n        }  \n      }\n    }\n  }\n\n  function getGeneFromNetwork(net) { // gets all the weight/biases from network in a floatArray\n    var gene = [];\n    var layer = null;\n    var filter = null;\n    var bias = null;\n    var w = null;\n    var i, j, k;\n    for ( i = 0; i < net.layers.length; i++) {\n      layer = net.layers[i];\n      filter = layer.filters;\n      if (filter) {\n        for ( j = 0; j < filter.length; j++) {\n          w = filter[j].w;\n          for ( k = 0; k < w.length; k++) {\n            gene.push(w[k]);\n          }\n        }\n      }\n      bias = layer.biases;\n      if (bias) {\n        w = bias.w;\n        for ( k = 0; k < w.length; k++) {\n          gene.push(w[k]);\n        }  \n      }\n    }\n    return gene;\n  }\n\n  function copyFloatArray(x) { // returns a FloatArray copy of real numbered array x.\n    var N = x.length;\n    var y = zeros(N);\n    for (var i = 0; i < N; i++) {\n      y[i] = x[i];\n    }\n    return y;\n  }\n\n  function copyFloatArrayIntoArray(x, y) { // copies a FloatArray copy of real numbered array x into y\n    var N = x.length;\n    for (var i = 0; i < N; i++) {\n      y[i] = x[i];\n    }\n  }\n\n  // randomize neural network with random weights and biases\n  var randomizeNetwork = function(net) {\n    var netSize = getNetworkSize(net);\n    var chromosome = new Chromosome(zeros(netSize));\n    chromosome.randomize(1.0);\n    pushGeneToNetwork(net, chromosome.gene);\n  };\n\n  // implementation of basic conventional neuroevolution algorithm (CNE)\n  //\n  // options:\n  // population_size : positive integer\n  // mutation_rate : [0, 1], when mutation happens, chance of each gene getting mutated\n  // elite_percentage : [0, 0.3], only this group mates and produces offsprings\n  // mutation_size : positive floating point.  stdev of gausian noise added for mutations\n  // target_fitness : after fitness achieved is greater than this float value, learning stops\n  // burst_generations : positive integer.  if best fitness doesn't improve after this number of generations\n  //                    then mutate everything!\n  // best_trial : default 1.  save best of best_trial's results for each chromosome.\n  // num_match : for use in arms race mode.  how many random matches we set for each chromosome when it is its turn.\n  //\n  // initGene:  init float array to initialize the chromosomes.  can be result obtained from pretrained sessions.\n  var GATrainer = function(net, options_, initGene) {\n\n    this.net = net;\n\n    var options = options_ || {};\n    this.population_size = typeof options.population_size !== 'undefined' ? options.population_size : 100;\n    this.population_size = Math.floor(this.population_size/2)*2; // make sure even number\n    this.mutation_rate = typeof options.mutation_rate !== 'undefined' ? options.mutation_rate : 0.01;\n    this.elite_percentage = typeof options.elite_percentage !== 'undefined' ? options.elite_percentage : 0.2;\n    this.mutation_size = typeof options.mutation_size !== 'undefined' ? options.mutation_size : 0.05;\n    this.target_fitness = typeof options.target_fitness !== 'undefined' ? options.target_fitness : 10000000000000000;\n    this.burst_generations = typeof options.burst_generations !== 'undefined' ? options.burst_generations : 10;\n    this.best_trial = typeof options.best_trial !== 'undefined' ? options.best_trial : 1;\n    this.num_match = typeof options.num_match !== 'undefined' ? options.num_match : 1;\n    this.chromosome_size = getNetworkSize(this.net);\n\n    var initChromosome = null;\n    if (initGene) {\n      initChromosome = new Chromosome(initGene);\n    }\n\n    this.chromosomes = []; // population\n    for (var i = 0; i < this.population_size; i++) {\n      var chromosome = new Chromosome(zeros(this.chromosome_size));\n      if (initChromosome) { // if initial gene supplied, burst mutate param.\n        chromosome.copyFrom(initChromosome);\n        // pushGeneToNetwork(this.net, initChromosome.gene); // this line may be redundant. (*1)\n        if (i > 0) { // don't mutate the first guy.\n          chromosome.burst_mutate(this.mutation_size);\n        }\n      } else {\n        chromosome.randomize(1.0);\n      }\n      this.chromosomes.push(chromosome);\n    }\n    pushGeneToNetwork(this.net, this.chromosomes[0].gene); // push first chromosome to neural network. (replaced *1 above)\n\n    this.bestFitness = -10000000000000000;\n    this.bestFitnessCount = 0;\n\n  };\n\n  GATrainer.prototype = {\n    train: function(fitFunc) { // has to pass in fitness function.  returns best fitness\n      var bestFitFunc = function(nTrial, net) {\n        var bestFitness = -10000000000000000;\n        var fitness;\n        for (var i = 0; i < nTrial; i++) {\n          fitness = fitFunc(net);\n          if (fitness > bestFitness) {\n            bestFitness = fitness;\n          }\n        }\n        return bestFitness;\n      };\n\n      var i, N;\n      var fitness;\n      var c = this.chromosomes;\n      N = this.population_size;\n\n      var bestFitness = -10000000000000000;\n\n      // process first net (the best one)\n      pushGeneToNetwork(this.net, c[0].gene);\n      fitness = bestFitFunc(this.best_trial, this.net);\n      c[0].fitness = fitness;\n      bestFitness = fitness;\n      if (bestFitness > this.target_fitness) {\n        return bestFitness;\n      }\n\n      for (i = 1; i < N; i++) {\n        pushGeneToNetwork(this.net, c[i].gene);\n        fitness = bestFitFunc(this.best_trial, this.net);\n        c[i].fitness = fitness;\n        if (fitness > bestFitness) {\n          bestFitness = fitness;\n        }\n      }\n\n      // sort the chromosomes by fitness\n      c = c.sort(function (a, b) {\n        if (a.fitness > b.fitness) { return -1; }\n        if (a.fitness < b.fitness) { return 1; }\n        return 0;\n      });\n\n      var Nelite = Math.floor(Math.floor(this.elite_percentage*N)/2)*2; // even number\n      for (i = Nelite; i < N; i+=2) {\n        var p1 = randi(0, Nelite);\n        var p2 = randi(0, Nelite);\n        c[p1].crossover(c[p2], c[i], c[i+1]);\n      }\n\n      for (i = 1; i < N; i++) { // keep best guy the same.  don't mutate the best one, so start from 1, not 0.\n        c[i].mutate(this.mutation_rate, this.mutation_size);\n      }\n\n      // push best one to network.\n      pushGeneToNetwork(this.net, c[0].gene);\n      if (bestFitness < this.bestFitness) { // didn't beat the record this time\n        this.bestFitnessCount++;\n        if (this.bestFitnessCount > this.burst_generations) { // stagnation, do burst mutate!\n          for (i = 1; i < N; i++) { \n            c[i].copyFrom(c[0]);\n            c[i].burst_mutate(this.mutation_size);\n          }\n          //c[0].burst_mutate(this.mutation_size); // don't mutate best solution.\n        }\n\n      } else {\n        this.bestFitnessCount = 0; // reset count for burst\n        this.bestFitness = bestFitness; // record the best fitness score\n      }\n\n      return bestFitness;\n    },\n    matchTrain: function(matchFunc) { // uses arms race to determine best chromosome by playing them against each other\n      // this algorithm loops through each chromosome, and for each chromosome, it will play num_match games\n      // against other chromosomes.  at the same time.  if it wins, the fitness is incremented by 1\n      // else it is subtracted by 1.  if the game is tied, the fitness doesn't change.\n      // at the end of the algorithm, each fitness is divided by the number of games the chromosome has played\n      // the algorithm will then sort the chromosomes by this average fitness\n\n      var i, j, N;\n      var opponent;\n      var fitness;\n      var c = this.chromosomes;\n      var result = 0;\n      N = this.population_size;\n\n      // zero out all fitness and \n      for (i = 0; i < N; i++) {\n        c[i].fitness = 0;\n        c[i].nTrial = 0;\n      }\n\n      // get these guys to fight against each other!\n      for (i = 0; i < N; i++) {\n        \n        for (j = 0; j < this.num_match; j++) {\n          opponent = randi(0, N);\n          if (opponent === i) continue;\n          result = matchFunc(c[i], c[opponent]);\n          c[i].nTrial += 1;\n          c[opponent].nTrial += 1;\n          c[i].fitness += (result+1);\n          c[opponent].fitness += ((-result)+1); // if result is -1, it means opponent has won.\n        }\n      }\n\n      // average out all fitness scores by the number of matches each chromosome has done.\n      \n      for (i = 0; i < N; i++) {\n        if (c[i].nTrial > 0) {\n          c[i].fitness /= c[i].nTrial;\n        }\n      }\n      \n\n      // sort the chromosomes by fitness\n      c = c.sort(function (a, b) {\n        if (a.fitness > b.fitness) { return -1; }\n        if (a.fitness < b.fitness) { return 1; }\n        return 0;\n      });\n\n      var Nelite = Math.floor(Math.floor(this.elite_percentage*N)/2)*2; // even number\n      for (i = Nelite; i < N; i+=2) {\n        var p1 = randi(0, Nelite);\n        var p2 = randi(0, Nelite);\n        c[p1].crossover(c[p2], c[i], c[i+1]);\n      }\n\n      for (i = 2; i < N; i++) { // keep two best guys the same.  don't mutate the best one, so start from 2, not 0.\n        c[i].mutate(this.mutation_rate, this.mutation_size);\n      }\n\n      // push best one to network.\n      pushGeneToNetwork(this.net, c[0].gene);\n\n      // return; // this funciton doesn't return anything.\n      // debug info, print out all fitness\n\n    }\n  };\n\n  // variant of ESP network implemented\n  // population of N sub neural nets, each to be co-evolved by ESPTrainer\n  // fully recurrent.  outputs of each sub nn is also the input of all other sub nn's and itself.\n  // inputs should be order of ~ -10 to +10, and expect output to be similar magnitude.\n  // user can grab outputs of the the N sub networks and use them to accomplish some task for training\n  //\n  // Nsp: Number of sub populations (ie, 4)\n  // Ninput: Number of real inputs to the system (ie, 2).  so actual number of input is Niput + Nsp\n  // Nhidden:  Number of hidden neurons in each sub population (ie, 16)\n  // genes: (optional) array of Nsp genes (floatArrays) to initialise the network (pretrained);\n  var ESPNet = function(Nsp, Ninput, Nhidden, genes) {\n    this.net = []; // an array of convnet.js feed forward nn's\n    this.Ninput = Ninput;\n    this.Nsp = Nsp;\n    this.Nhidden = Nhidden;\n    this.input = new convnetjs.Vol(1, 1, Nsp+Ninput); // hold most up to date input vector\n    this.output = zeros(Nsp);\n\n    // define the architecture of each sub nn:\n    var layer_defs = [];\n    layer_defs.push({\n      type: 'input',\n      out_sx: 1,\n      out_sy: 1,\n      out_depth: (Ninput+Nsp)\n    });\n    layer_defs.push({\n      type: 'fc',\n      num_neurons: Nhidden,\n      activation: 'sigmoid'\n    });\n    layer_defs.push({\n      type: 'regression',\n      num_neurons: 1 // one output for each sub nn, gets fed back into inputs.\n    });\n\n    var network;\n    for (var i = 0; i < Nsp; i++) {\n      network = new convnetjs.Net();\n      network.makeLayers(layer_defs);\n      this.net.push(network);\n    }\n\n    // if pretrained network is supplied:\n    if (genes) {\n      this.pushGenes(genes);\n    }\n  };\n\n  ESPNet.prototype = {\n    feedback: function() { // feeds output back to last bit of input vector\n      var i;\n      var Ninput = this.Ninput;\n      var Nsp = this.Nsp;\n      for (i = 0; i < Nsp; i++) {\n        this.input.w[i+Ninput] = this.output[i];\n      }\n    },\n    setInput: function(input) { // input is a vector of length this.Ninput of real numbers\n      // this function also grabs the previous most recent output and put it into the internal input vector\n      var i;\n      var Ninput = this.Ninput;\n      var Nsp = this.Nsp;\n      for (i = 0; i < Ninput; i++) {\n        this.input.w[i] = input[i];\n      }\n      this.feedback();\n    },\n    forward: function() { // returns array of output of each Nsp neurons after a forward pass.\n      var i, j;\n      var Ninput = this.Ninput;\n      var Nsp = this.Nsp;\n      var y = zeros(Nsp);\n      var a; // temp variable to old output of forward pass\n      for (i = Nsp-1; i >= 0; i--) {\n        if (i === 0) { // for the base network, forward with output of other support networks\n          this.feedback();\n        }\n        a = this.net[i].forward(this.input); // forward pass sub nn # i\n        y[i] = a.w[0]; // each sub nn only has one output.\n        this.output[i] = y[i]; // set internal output to track output\n      }\n      return y;\n    },\n    getNetworkSize: function() { // return total number of weights and biases in a single sub nn.\n      return getNetworkSize(this.net[0]); // each network has identical architecture.\n    },\n    getGenes: function() { // return an array of Nsp genes (floatArrays of length getNetworkSize())\n      var i;\n      var Nsp = this.Nsp;\n      var result = [];\n      for (i = 0; i < Nsp; i++) {\n        result.push(getGeneFromNetwork(this.net[i]));\n      }\n      return result;\n    },\n    pushGenes: function(genes) { // genes is an array of Nsp genes (floatArrays)\n      var i;\n      var Nsp = this.Nsp;\n      for (i = 0; i < Nsp; i++) {\n        pushGeneToNetwork(this.net[i], genes[i]);\n      }\n    }\n  };\n\n  // implementation of variation of Enforced Sub Population neuroevolution algorithm\n  //\n  // options:\n  // population_size : population size of each subnetwork inside espnet\n  // mutation_rate : [0, 1], when mutation happens, chance of each gene getting mutated\n  // elite_percentage : [0, 0.3], only this group mates and produces offsprings\n  // mutation_size : positive floating point.  stdev of gausian noise added for mutations\n  // target_fitness : after fitness achieved is greater than this float value, learning stops\n  // num_passes : number of times each neuron within a sub population is tested\n  //          on average, each neuron will be tested num_passes * esp.Nsp times.\n  // burst_generations : positive integer.  if best fitness doesn't improve after this number of generations\n  //                    then start killing neurons that don't contribute to the bottom line! (reinit them with randoms)\n  // best_mode : if true, this will assign each neuron to the best fitness trial it has experienced.\n  //             if false, this will use the average of all trials experienced.\n  // initGenes:  init Nsp array of floatarray to initialize the chromosomes.  can be result obtained from pretrained sessions.\n  var ESPTrainer = function(espnet, options_, initGenes) {\n\n    this.espnet = espnet;\n    this.Nsp = espnet.Nsp;\n    var Nsp = this.Nsp;\n\n    var options = options_ || {};\n    this.population_size = typeof options.population_size !== 'undefined' ? options.population_size : 50;\n    this.population_size = Math.floor(this.population_size/2)*2; // make sure even number\n    this.mutation_rate = typeof options.mutation_rate !== 'undefined' ? options.mutation_rate : 0.2;\n    this.elite_percentage = typeof options.elite_percentage !== 'undefined' ? options.elite_percentage : 0.2;\n    this.mutation_size = typeof options.mutation_size !== 'undefined' ? options.mutation_size : 0.02;\n    this.target_fitness = typeof options.target_fitness !== 'undefined' ? options.target_fitness : 10000000000000000;\n    this.num_passes = typeof options.num_passes !== 'undefined' ? options.num_passes : 2;\n    this.burst_generations = typeof options.burst_generations !== 'undefined' ? options.burst_generations : 10;\n    this.best_mode = typeof options.best_mode !== 'undefined' ? options.best_mode : false;\n    this.chromosome_size = this.espnet.getNetworkSize();\n\n    this.initialize(initGenes);\n  };\n\n  ESPTrainer.prototype = {\n    initialize: function(initGenes) {\n      var i, j;\n      var y;\n      var Nsp = this.Nsp;\n      this.sp = []; // sub populations\n      this.bestGenes = []; // array of Nsp number of genes, records the best combination of genes for the bestFitness achieved so far.\n      var chromosomes, chromosome;\n      for (i = 0; i < Nsp; i++) {\n        chromosomes = []; // empty list of chromosomes\n        for (j = 0; j < this.population_size; j++) {\n          chromosome = new Chromosome(zeros(this.chromosome_size));\n          if (initGenes) {\n            chromosome.copyFromGene(initGenes[i]);\n            if (j > 0) { // don't mutate first guy (pretrained)\n              chromosome.burst_mutate(this.mutation_size);\n            }\n          } else { // push random genes to this.bestGenes since it has not been initalized.\n            chromosome.randomize(1.0); // create random gene array if no pretrained one is supplied.\n          }\n          chromosomes.push(chromosome);\n        }\n        y = copyFloatArray(chromosomes[0].gene); // y should either be random init gene, or pretrained.\n        this.bestGenes.push(y);\n        this.sp.push(chromosomes); // push array of chromosomes into each population\n      }\n\n      assert(this.bestGenes.length === Nsp);\n      this.espnet.pushGenes(this.bestGenes); // initial\n\n      this.bestFitness = -10000000000000000;\n      this.bestFitnessCount = 0;\n    },\n    train: function(fitFunc) { // has to pass in fitness function.  returns best fitness\n\n      var i, j, k, m, N, Nsp;\n      var fitness;\n      var c = this.sp; // array of arrays that holds every single chromosomes (Nsp x N);\n      N = this.population_size; // number of chromosomes in each sub population\n      Nsp = this.Nsp; // number of sub populations\n\n      var bestFitness = -10000000000000000;\n      var bestSet, bestGenes;\n      var cSet;\n      var genes;\n\n      // helper function to return best fitness run nTrial times\n      var bestFitFunc = function(nTrial, net) {\n        var bestFitness = -10000000000000000;\n        var fitness;\n        for (var i = 0; i < nTrial; i++) {\n          fitness = fitFunc(net);\n          if (fitness > bestFitness) {\n            bestFitness = fitness;\n          }\n        }\n        return bestFitness;\n      };\n\n      // helper function to create a new array filled with genes from an array of chromosomes\n      // returns an array of Nsp floatArrays\n      function getGenesFromChromosomes(s) {\n        var g = [];\n        for (var i = 0; i < s.length; i++) {\n          g.push(copyFloatArray(s[i].gene));\n        }\n        return g;\n      }\n\n      // makes a copy of an array of gene, helper function\n      function makeCopyOfGenes(s) {\n        var g = [];\n        for (var i = 0; i < s.length; i++) {\n          g.push(copyFloatArray(s[i]));\n        }\n        return g;\n      }\n\n      // helper function, randomize all of nth sub population of entire chromosome set c\n      function randomizeSubPopulation(n, c) {\n        for (var i = 0; i < N; i++) {\n          c[n][i].randomize(1.0);\n        }\n      }\n\n      // helper function used to sort the list of chromosomes according to their fitness\n      function compareChromosomes(a, b) {\n        if ((a.fitness/a.nTrial) > (b.fitness/b.nTrial)) { return -1; }\n        if ((a.fitness/a.nTrial) < (b.fitness/b.nTrial)) { return 1; }\n        return 0;\n      }\n\n      // iterate over each gene in each sub population to initialise the nTrial to zero (will be incremented later)\n      for (i = 0; i < Nsp; i++) { // loop over every sub population\n        for (j = 0; j < N; j++) {\n          if (this.best_mode) { // best mode turned on, no averaging, but just recording best score.\n            c[i][j].nTrial = 1;\n            c[i][j].fitness = -10000000000000000;\n          } else {\n            c[i][j].nTrial = 0;\n            c[i][j].fitness = 0;\n          }\n        }\n      }\n\n      // see if the global best gene has met target.  if so, can end it now.\n      assert(this.bestGenes.length === Nsp);\n      this.espnet.pushGenes(this.bestGenes); // put the random set of networks into the espnet\n      fitness = fitFunc(this.espnet); // try out this set, and get the fitness\n      if (fitness > this.target_fitness) {\n        return fitness;\n      }\n      bestGenes = makeCopyOfGenes(this.bestGenes);\n      bestFitness = fitness;\n      //this.bestFitness = fitness;\n\n      // for each chromosome in a sub population, choose random chromosomes from all othet sub  populations to\n      // build a espnet.  perform fitFunc on that esp net to get the fitness of that combination.  add the fitness\n      // to this chromosome, and all participating chromosomes.  increment the nTrial of all participating\n      // chromosomes by one, so afterwards they can be sorted by average fitness\n      // repeat this process this.num_passes times\n      for (k = 0; k < this.num_passes; k++) {\n        for (i = 0; i < Nsp; i++) {\n          for (j = 0; j < N; j++) {\n            // build an array of chromosomes randomly\n            cSet = [];\n            for (m = 0; m < Nsp; m++) {\n              if (m === i) { // push current iterated neuron\n                cSet.push(c[m][j]);\n              } else { // push random neuron in sub population m\n                cSet.push(c[m][randi(0, N)]);\n              }\n            }\n            genes = getGenesFromChromosomes(cSet);\n            assert(genes.length === Nsp);\n            this.espnet.pushGenes(genes); // put the random set of networks into the espnet\n\n            fitness = fitFunc(this.espnet); // try out this set, and get the fitness\n\n            for (m = 0; m < Nsp; m++) { // tally the scores into each participating neuron\n              if (this.best_mode) {\n                if (fitness > cSet[m].fitness) { // record best fitness this neuron participated in.\n                  cSet[m].fitness = fitness;                \n                }\n              } else {\n                cSet[m].nTrial += 1; // increase participation count for each participating neuron\n                cSet[m].fitness += fitness;                \n              }\n            }\n            if (fitness > bestFitness) {\n              bestFitness = fitness;\n              bestSet = cSet;\n              bestGenes = genes;\n            }\n          }\n        }\n      }\n\n      // sort the chromosomes by average fitness\n      for (i = 0; i < Nsp; i++) {\n        c[i] = c[i].sort(compareChromosomes);\n      }\n\n      var Nelite = Math.floor(Math.floor(this.elite_percentage*N)/2)*2; // even number\n      for (i = 0; i < Nsp; i++) {\n        for (j = Nelite; j < N; j+=2) {\n          var p1 = randi(0, Nelite);\n          var p2 = randi(0, Nelite);\n          c[i][p1].crossover(c[i][p2], c[i][j], c[i][j+1]);\n        }\n      }\n\n      // mutate the population size after 2*Nelite (keep one set of crossovers unmutiliated!)\n      for (i = 0; i < Nsp; i++) {\n        for (j = 2*Nelite; j < N; j++) {\n          c[i][j].mutate(this.mutation_rate, this.mutation_size);\n        }\n      }\n\n      // put global and local bestgenes in the last element of each gene\n      for (i = 0; i < Nsp; i++) {\n        c[i][N-1].copyFromGene( this.bestGenes[i] );\n        c[i][N-2].copyFromGene( bestGenes[i] );\n      }\n\n      if (bestFitness < this.bestFitness) { // didn't beat the record this time\n        this.bestFitnessCount++;\n        if (this.bestFitnessCount > this.burst_generations) { // stagnation, do burst mutate!\n          // add code here when progress stagnates later.\n          console.log('stagnating. burst mutate based on best solution.');\n          var bestGenesCopy = makeCopyOfGenes(this.bestGenes);\n          var bestFitnessCopy = this.bestFitness;\n          this.initialize(bestGenesCopy);\n          \n          this.bestGenes = bestGenesCopy;\n          this.bestFitness = this.bestFitnessCopy;\n          \n        }\n\n      } else {\n        this.bestFitnessCount = 0; // reset count for burst\n        this.bestFitness = bestFitness; // record the best fitness score\n        this.bestGenes = bestGenes; // record the set of genes that generated the best fitness\n      }\n\n      // push best one (found so far from all of history, not just this time) to network.\n      assert(this.bestGenes.length === Nsp);\n      this.espnet.pushGenes(this.bestGenes);\n\n      return bestFitness;\n    }\n  };\n\n  convnetjs.ESPNet = ESPNet;\n  convnetjs.ESPTrainer = ESPTrainer;\n  convnetjs.GATrainer = GATrainer;\n  convnetjs.Chromosome = Chromosome;\n  convnetjs.randomizeNetwork = randomizeNetwork;\n})(convnetjs);\n\n"
  },
  {
    "path": "lib/convnetjs/util.js",
    "content": "\n// contains various utility functions \nvar cnnutil = (function(exports){\n\n  // a window stores _size_ number of values\n  // and returns averages. Useful for keeping running\n  // track of validation or training accuracy during SGD\n  var Window = function(size, minsize) {\n    this.v = [];\n    this.size = typeof(size)==='undefined' ? 100 : size;\n    this.minsize = typeof(minsize)==='undefined' ? 20 : minsize;\n    this.sum = 0;\n  }\n  Window.prototype = {\n    add: function(x) {\n      this.v.push(x);\n      this.sum += x;\n      if(this.v.length>this.size) {\n        var xold = this.v.shift();\n        this.sum -= xold;\n      }\n    },\n    get_average: function() {\n      if(this.v.length < this.minsize) return -1;\n      else return this.sum/this.v.length;\n    },\n    reset: function(x) {\n      this.v = [];\n      this.sum = 0;\n    }\n  }\n\n  // returns min, max and indeces of an array\n  var maxmin = function(w) {\n    if(w.length === 0) { return {}; } // ... ;s\n\n    var maxv = w[0];\n    var minv = w[0];\n    var maxi = 0;\n    var mini = 0;\n    for(var i=1;i<w.length;i++) {\n      if(w[i] > maxv) { maxv = w[i]; maxi = i; } \n      if(w[i] < minv) { minv = w[i]; mini = i; } \n    }\n    return {maxi: maxi, maxv: maxv, mini: mini, minv: minv, dv:maxv-minv};\n  }\n\n  // returns string representation of float\n  // but truncated to length of d digits\n  var f2t = function(x, d) {\n    if(typeof(d)==='undefined') { var d = 5; }\n    var dd = 1.0 * Math.pow(10, d);\n    return '' + Math.floor(x*dd)/dd;\n  }\n\n  exports = exports || {};\n  exports.Window = Window;\n  exports.maxmin = maxmin;\n  exports.f2t = f2t;\n  return exports;\n\n})(typeof module != 'undefined' && module.exports);  // add exports to module.exports if in node.js\n\n\n"
  },
  {
    "path": "lib/convnetjs/vis.js",
    "content": "\n// contains various utility functions \nvar cnnvis = (function(exports){\n\n  // can be used to graph loss, or accuract over time\n  var Graph = function(options) {\n    var options = options || {};\n    this.step_horizon = options.step_horizon || 1000;\n    \n    this.pts = [];\n    \n    this.maxy = -9999;\n    this.miny = 9999;\n  }\n\n  Graph.prototype = {\n    // canv is the canvas we wish to update with this new datapoint\n    add: function(step, y) {\n      var time = new Date().getTime(); // in ms\n      if(y>this.maxy*0.99) this.maxy = y*1.05;\n      if(y<this.miny*1.01) this.miny = y*0.95;\n\n      this.pts.push({step: step, time: time, y: y});\n      if(step > this.step_horizon) this.step_horizon *= 2;\n    },\n    // elt is a canvas we wish to draw into\n    drawSelf: function(canv) {\n      \n      var pad = 25;\n      var H = canv.height;\n      var W = canv.width;\n      var ctx = canv.getContext('2d');\n\n      ctx.clearRect(0, 0, W, H);\n      ctx.font=\"10px Georgia\";\n\n      var f2t = function(x) {\n        var dd = 1.0 * Math.pow(10, 2);\n        return '' + Math.floor(x*dd)/dd;\n      }\n\n      // draw guidelines and values\n      ctx.strokeStyle = \"#999\";\n      ctx.beginPath();\n      var ng = 10;\n      for(var i=0;i<=ng;i++) {\n        var xpos = i/ng*(W-2*pad)+pad;\n        ctx.moveTo(xpos, pad);\n        ctx.lineTo(xpos, H-pad);\n        ctx.fillText(f2t(i/ng*this.step_horizon/1000)+'k',xpos,H-pad+14);\n      }\n      for(var i=0;i<=ng;i++) {\n        var ypos = i/ng*(H-2*pad)+pad;\n        ctx.moveTo(pad, ypos);\n        ctx.lineTo(W-pad, ypos);\n        ctx.fillText(f2t((ng-i)/ng*(this.maxy-this.miny) + this.miny), 0, ypos);\n      }\n      ctx.stroke();\n\n      var N = this.pts.length;\n      if(N<2) return;\n\n      // draw the actual curve\n      var t = function(x, y, s) {\n        var tx = x / s.step_horizon * (W-pad*2) + pad;\n        var ty = H - ((y-s.miny) / (s.maxy-s.miny) * (H-pad*2) + pad);\n        return {tx:tx, ty:ty}\n      }\n\n      ctx.strokeStyle = \"red\";\n      ctx.beginPath()\n      for(var i=0;i<N;i++) {\n        // draw line from i-1 to i\n        var p = this.pts[i];\n        var pt = t(p.step, p.y, this);\n        if(i===0) ctx.moveTo(pt.tx, pt.ty);\n        else ctx.lineTo(pt.tx, pt.ty);\n      }\n      ctx.stroke();\n    }\n  }\n\n  // same as graph but draws multiple lines. For now I'm lazy and duplicating\n  // the code, but in future I will merge these two more nicely.\n  var MultiGraph = function(legend, options) {\n    var options = options || {};\n    this.step_horizon = options.step_horizon || 1000;\n\n    if(typeof options.maxy !== 'undefined') this.maxy_forced = options.maxy;\n    if(typeof options.miny !== 'undefined') this.miny_forced = options.miny;\n\n    this.pts = [];\n    \n    this.maxy = -9999;\n    this.miny = 9999;\n    this.numlines = 0;\n\n    this.numlines = legend.length;\n    this.legend = legend;\n    this.styles = [\"red\", \"blue\", \"green\", \"black\", \"magenta\", \"cyan\", \"purple\", \"aqua\", \"olive\", \"lime\", \"navy\"];\n    // 17 basic colors: aqua, black, blue, fuchsia, gray, green, lime, maroon, navy, olive, orange, purple, red, silver, teal, white, and yellow\n  }\n\n  MultiGraph.prototype = {\n    // canv is the canvas we wish to update with this new datapoint\n    add: function(step, yl) {\n      var time = new Date().getTime(); // in ms\n      var n = yl.length;\n      for(var k=0;k<n;k++) {\n        var y = yl[k];\n        if(y>this.maxy*0.99) this.maxy = y*1.05;\n        if(y<this.miny*1.01) this.miny = y*0.95;\n      }\n\n      if(typeof this.maxy_forced !== 'undefined') this.maxy = this.maxy_forced;\n      if(typeof this.miny_forced !== 'undefined') this.miny = this.miny_forced;\n\n      this.pts.push({step: step, time: time, yl: yl});\n      if(step > this.step_horizon) this.step_horizon *= 2;\n    },\n    // elt is a canvas we wish to draw into\n    drawSelf: function(canv) {\n      \n      var pad = 25;\n      var H = canv.height;\n      var W = canv.width;\n      var ctx = canv.getContext('2d');\n\n      ctx.clearRect(0, 0, W, H);\n      ctx.font=\"10px Georgia\";\n\n      var f2t = function(x) {\n        var dd = 1.0 * Math.pow(10, 2);\n        return '' + Math.floor(x*dd)/dd;\n      }\n\n      // draw guidelines and values\n      ctx.strokeStyle = \"#999\";\n      ctx.beginPath();\n      var ng = 10;\n      for(var i=0;i<=ng;i++) {\n        var xpos = i/ng*(W-2*pad)+pad;\n        ctx.moveTo(xpos, pad);\n        ctx.lineTo(xpos, H-pad);\n        ctx.fillText(f2t(i/ng*this.step_horizon/1000)+'k',xpos,H-pad+14);\n      }\n      for(var i=0;i<=ng;i++) {\n        var ypos = i/ng*(H-2*pad)+pad;\n        ctx.moveTo(pad, ypos);\n        ctx.lineTo(W-pad, ypos);\n        ctx.fillText(f2t((ng-i)/ng*(this.maxy-this.miny) + this.miny), 0, ypos);\n      }\n      ctx.stroke();\n\n      var N = this.pts.length;\n      if(N<2) return;\n\n      // draw legend\n      for(var k=0;k<this.numlines;k++) {\n        ctx.fillStyle = this.styles[k % this.styles.length];\n        ctx.fillText(this.legend[k], W-pad-100, pad+20+k*16);\n      }\n      ctx.fillStyle = \"black\";\n\n      // draw the actual curve\n      var t = function(x, y, s) {\n        var tx = x / s.step_horizon * (W-pad*2) + pad;\n        var ty = H - ((y-s.miny) / (s.maxy-s.miny) * (H-pad*2) + pad);\n        return {tx:tx, ty:ty}\n      }\n      for(var k=0;k<this.numlines;k++) {\n\n        ctx.strokeStyle = this.styles[k % this.styles.length];\n        ctx.beginPath()\n        for(var i=0;i<N;i++) {\n          // draw line from i-1 to i\n          var p = this.pts[i];\n          var pt = t(p.step, p.yl[k], this);\n          if(i===0) ctx.moveTo(pt.tx, pt.ty);\n          else ctx.lineTo(pt.tx, pt.ty);\n        }\n        ctx.stroke();\n      }\n\n    }\n  }\n\n  exports = exports || {};\n  exports.Graph = Graph;\n  exports.MultiGraph = MultiGraph;\n  return exports;\n\n})(typeof module != 'undefined' && module.exports);  // add exports to module.exports if in node.js\n\n\n"
  },
  {
    "path": "lib/orientation-0.03.js",
    "content": "// get orientation of mobile device\n\n/**\n * Determine the mobile operating system.\n * This function either returns 'iOS', 'Android' or 'unknown'\n *\n * @returns {String}\n */\nfunction getMobileOperatingSystem() {\n  var userAgent = navigator.userAgent || navigator.vendor || window.opera;\n\n  if( userAgent.match( /iPad/i ) || userAgent.match( /iPhone/i ) || userAgent.match( /iPod/i ) )\n  {\n    return 'iOS';\n\n  }\n  else if( userAgent.match( /Android/i ) )\n  {\n\n    return 'Android';\n  }\n  else\n  {\n    return 'unknown';\n  }\n}\n\nvar Orientation = {\n\tenabled: false,\n\tx: 0,\n\ty: 0,\n\tz: 0,\n\talpha: 0,\n\tbeta: 0,\n\tgamma: 0,\n\tnormalizer: 1,\n\ttoString: function() {\n\t\tvar result = \"\";\n\t\tif (this.enabled === true) {\n\t\t\tresult = \"a:\"+this.alpha+\"\\tb:\"+this.beta+\"\\tg:\"+this.gamma+\"\\tx:\"+this.x+\"\\ty:\"+this.y+\"\\tz:\"+this.z;\n\t\t}\n\t\treturn result;\n\t},\n\tgetX: function() {\n\t\tvar result = 0;\n\t\tif (this.x) {\n\t\t\tresult = this.x*this.normalizer;\n\t\t}\n\t\treturn result;\n\t},\n\tgetY: function() {\n\t\tvar result = 0;\n\t\tif (this.y) {\n\t\t\tresult = this.y*this.normalizer;\n\t\t}\n\t\treturn result;\n\t},\n\tgetZ: function() {\n\t\tvar result = 0;\n\t\tif (this.z) {\n\t\t\tresult = this.z;\n\t\t}\n\t\treturn result;\n\t},\n\tgetAlpha: function() {\n\t\tvar result = 0;\n\t\tif (this.alpha) {\n\t\t\tresult = this.alpha;\n\t\t}\n\t\treturn result;\n\t},\n\tgetBeta: function() {\n\t\tvar result = 0;\n\t\tif (this.beta) {\n\t\t\tresult = this.beta;\n\t\t}\n\t\treturn result;\n\t},\n\tgetGamma: function() {\n\t\tvar result = 0;\n\t\tif (this.gamma) {\n\t\t\tresult = this.gamma;\n\t\t}\n\t\treturn result;\n\t},\n\tgetMagnitude: function() {\n\t\tvar result = 0.0;\n\t\tif (this.x && this.y) {\n\t\t\treturn Math.sqrt(this.x*this.x+this.y*this.y);\n\t\t}\n\t\treturn result;\n\t},\n\tgetMag2: function() {\n\t\tvar result = 0.0;\n\t\tif (this.x && this.y) {\n\t\t\treturn this.x*this.x+this.y*this.y;\n\t\t}\n\t\treturn result;\n\t}\n\n};\n\nif (getMobileOperatingSystem() === 'Android') {\n\tOrientation.normalizer = -1.0;\n}\n\nwindow.addEventListener('devicemotion', function (e) {\n    Orientation.x = Math.round(e.accelerationIncludingGravity.x*10)/10;\n    Orientation.y = Math.round(e.accelerationIncludingGravity.y*10)/10;\n    Orientation.z = Math.round(e.accelerationIncludingGravity.z*10)/10;       \n    if (Orientation.getMag2() > 0.00000001) {\n \t\tOrientation.enabled = true;\n\t} else {\n\t\tOrientation.enabled = false;\n\t}     \n}, false);\n\n\nwindow.addEventListener('deviceorientation', function (e) {\n    Orientation.alpha = Math.round(e.alpha*10)/10;\n    Orientation.beta = Math.round(e.beta*10)/10;\n    Orientation.gamma = Math.round(e.gamma*10)/10;           \n}, false);\n\n/*\nif((window.DeviceMotionEvent) || ('listenForDeviceMovement' in window)){ // gyroscope support\n    console.log('DeviceOrientationEvent support OK');\n    Orientation.enabled = true;\n} else {\n    console.log('DeviceOrientationEvent support KO');\n    Orientation.enabled = false;\n}\n*/\n"
  },
  {
    "path": "lib/p5.dom.js",
    "content": "/*! p5.dom.js v0.2.0 February 2, 2015 */\n/**\n * <p>The web is much more than just canvas and p5.dom makes it easy to interact\n * with other HTML5 objects, including text, hyperlink, image, input, video,\n * audio, and webcam.</p>\n * <p>There is a set of creation methods, DOM manipulation methods, and\n * an extended p5.Element that supports a range of HTML elements. See the\n * <a href=\"https://github.com/processing/p5.js/wiki/Beyond-the-canvas\">\n * beyond the canvas tutorial</a> for a full overview of how this addon works.\n *\n * <p>Methods and properties shown in black are part of the p5.js core, items in\n * blue are part of the p5.dom library. You will need to include an extra file\n * in order to access the blue functions. See the\n * <a href=\"http://p5js.org/libraries/#using-a-library\">using a library</a>\n * section for information on how to include this library. p5.dom comes with\n * <a href=\"http://p5js.org/download\">p5 complete</a> or you can download the single file\n * <a href=\"https://raw.githubusercontent.com/lmccart/p5.js/master/lib/addons/p5.dom.js\">\n * here</a>.</p>\n * <p>See <a href=\"https://github.com/processing/p5.js/wiki/Beyond-the-canvas\">tutorial: beyond the canvas]</a>\n * for more info on how to use this libary.</a>\n *\n * @module p5.dom\n * @submodule p5.dom\n * @for p5.dom\n * @main\n */\n\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd)\n    define('p5.dom', ['p5'], function (p5) { (factory(p5));});\n  else if (typeof exports === 'object')\n    factory(require('../p5'));\n  else\n    factory(root['p5']);\n}(this, function (p5) {\n// =============================================================================\n//                         p5 additions\n// =============================================================================\n\n  /**\n   * Searches the page for an element with given ID and returns it as\n   * a p5.Element. The DOM node itself can be accessed with .elt.\n   * Returns null if none found.\n   *\n   * @method getElement\n   * @param  {String} id id of element to search for\n   * @return {Object/p5.Element|Null} p5.Element containing node found\n   */\n  p5.prototype.getElement = function (e) {\n    var res = document.getElementById(e);\n    if (res) {\n      return wrapElement(res);\n    } else {\n      return null;\n    }\n  };\n\n  /**\n   * Searches the page for elements with given class and returns an\n   * array of p5.Elements. The DOM nodes themselves can be accessed\n   * with .elt. Returns an empty array if none found.\n   *\n   * @method getElements\n   * @param  {String} class class name of elements to search for\n   * @return {Array} array of p5.Element wrapped nodes found\n   */\n  p5.prototype.getElements = function (e) {\n    var arr = [];\n    var res = document.getElementsByClassName(e);\n    if (res) {\n      for (var j = 0; j < res.length; j++) {\n        var obj = wrapElement(res[j]);\n        arr.push(obj);\n      }\n    }\n    return arr;\n  };\n\n  /**\n   * Helper function for getElement and getElements.\n   */\n  function wrapElement(elt) {\n    if (elt.tagName === \"VIDEO\" || elt.tagName === \"AUDIO\") {\n      return new p5.MediaElement(elt);\n    } else {\n      return new p5.Element(elt);\n    }\n  }\n\n  /**\n   * Removes all elements created by p5, except any canvas / graphics\n   * elements created by createCanvas or createGraphics.\n   * Event handlers are removed, and element is removed from the DOM.\n   * @method removeElements\n   * @example\n   * <div class='norender'><code>\n   * function setup() {\n   *   createCanvas(100, 100);\n   *   createDiv('this is some text');\n   *   createP('this is a paragraph');\n   * }\n   * function mousePressed() {\n   *   removeElements(); // this will remove the div and p, not canvas\n   * }\n   * </code></div>\n   *\n   */\n  p5.prototype.removeElements = function (e) {\n    for (var i=0; i<this._elements.length; i++) {\n      if (!(this._elements[i].elt instanceof HTMLCanvasElement)) {\n        this._elements[i].remove();\n      }\n    }\n  };\n\n  /**\n   * Helpers for create methods.\n   */\n  function addElement(elt, pInst, media) {\n    var node = pInst._userNode ? pInst._userNode : document.body;\n    node.appendChild(elt);\n    var c = media ? new p5.MediaElement(elt) : new p5.Element(elt);\n    pInst._elements.push(c);\n    return c;\n  }\n\n  /**\n   * Creates a &lt;div&gt;&lt;/div&gt; element in the DOM with given inner HTML.\n   * Appends to the container node if one is specified, otherwise\n   * appends to body.\n   *\n   * @method createDiv\n   * @param  {String} html inner HTML for element created\n   * @return {Object/p5.Element} pointer to p5.Element holding created\n   *                           node\n   */\n\n  /**\n   * Creates a &lt;p&gt;&lt;/p&gt; element in the DOM with given inner HTML. Used\n   * for paragraph length text.\n   * Appends to the container node if one is specified, otherwise\n   * appends to body.\n   *\n   * @method createP\n   * @param  {String} html inner HTML for element created\n   * @return {Object/p5.Element} pointer to p5.Element holding created\n   *                           node\n   */\n\n  /**\n   * Creates a &lt;span&gt;&lt;/span&gt; element in the DOM with given inner HTML.\n   * Appends to the container node if one is specified, otherwise\n   * appends to body.\n   *\n   * @method createSpan\n   * @param  {String} html inner HTML for element created\n   * @return {Object/p5.Element} pointer to p5.Element holding created\n   *                           node\n   */\n  var tags = ['div', 'p', 'span'];\n  tags.forEach(function(tag) {\n    var method = 'create' + tag.charAt(0).toUpperCase() + tag.slice(1);\n    p5.prototype[method] = function(html) {\n      var elt = document.createElement(tag);\n      elt.innerHTML = typeof html === undefined ? \"\" : html;\n      return addElement(elt, this);\n    }\n  });\n\n  /**\n   * Creates an &lt;img /&gt; element in the DOM with given src and\n   * alternate text.\n   * Appends to the container node if one is specified, otherwise\n   * appends to body.\n   *\n   * @method createImg\n   * @param  {String} src src path or url for image\n   * @param  {String} alt alternate text to be used if image does not\n   *                  load\n   * @return {Object/p5.Element} pointer to p5.Element holding created\n   *                           node\n   */\n  p5.prototype.createImg = function(src, alt) {\n    var elt = document.createElement('img');\n    elt.src = src;\n    if (typeof alt !== 'undefined') {\n      elt.alt = alt;\n    }\n    return addElement(elt, this);\n  };\n\n\n  /**\n   * Creates an &lt;a&gt;&lt;/a&gt; element in the DOM for including a hyperlink.\n   * Appends to the container node if one is specified, otherwise\n   * appends to body.\n   *\n   * @method createA\n   * @param  {String} href       url of page to link to\n   * @param  {String} html       inner html of link element to display\n   * @param  {String} [target]   target where new link should open,\n   *                             could be _blank, _self, _parent, _top.\n   * @return {Object/p5.Element} pointer to p5.Element holding created\n   *                           node\n   */\n  p5.prototype.createA = function(href, html, target) {\n    var elt = document.createElement('a');\n    elt.href = href;\n    elt.innerHTML = html;\n    if (target) elt.target = target;\n    return addElement(elt, this);\n  };\n\n  /** INPUT **/\n\n\n  /**\n   * Creates a slider &lt;input&gt;&lt;/input&gt; element in the DOM.\n   * Use .size() to set the display length of the slider.\n   * Appends to the container node if one is specified, otherwise\n   * appends to body.\n   *\n   * @method createSlider\n   * @param  {Number} min minimum value of the slider\n   * @param  {Number} max maximum value of the slider\n   * @param  {Number} [value] default value of the slider\n   * @return {Object/p5.Element} pointer to p5.Element holding created\n   *                           node\n   */\n  p5.prototype.createSlider = function(min, max, value, step) {\n    var elt = document.createElement('input');\n    elt.type = 'range';\n    elt.min = min;\n    elt.max = max;\n    if (step) elt.step = step;\n    if (value) elt.value = value;\n    return addElement(elt, this);\n  };\n\n  /**\n   * Creates a &lt;button&gt;&lt;/button&gt; element in the DOM.\n   * Use .size() to set the display size of the button.\n   * Use .mousePressed() to specify behavior on press.\n   * Appends to the container node if one is specified, otherwise\n   * appends to body.\n   *\n   * @method createButton\n   * @param  {String} label label displayed on the button\n   * @param  {String} [value] value of the button\n   * @return {Object/p5.Element} pointer to p5.Element holding created\n   *                           node\n   */\n  p5.prototype.createButton = function(label, value) {\n    var elt = document.createElement('button');\n    elt.innerHTML = label;\n    elt.value = value;\n    if (value) elt.value = value;\n    return addElement(elt, this);\n  };\n\n  /**\n   * Creates an &lt;input&gt;&lt;/input&gt; element in the DOM for text input.\n   * Use .size() to set the display length of the box.\n   * Appends to the container node if one is specified, otherwise\n   * appends to body.\n   *\n   * @method createInput\n   * @param  {Number} [value] default value of the input box\n   * @return {Object/p5.Element} pointer to p5.Element holding created\n   *                           node\n   */\n  p5.prototype.createInput = function(value) {\n    var elt = document.createElement('input');\n    elt.type = 'text';\n    if (value) elt.value = value;\n    return addElement(elt, this);\n  };\n\n  /**\n   * Creates an &lt;input&gt;&lt;/input&gt; element in the DOM of type 'file'.  \n   * This allows users to select local files for use in a sketch.\n   * \n   * @method createFileInput\n   * @param  {Function} [callback] callback function for when a file loaded\n   * @param  {String} [multiple] optional to allow multiple files selected\n   * @return {Object/p5.Element} pointer to p5.Element holding created DOM element\n   *                           \n   */\n  p5.prototype.createFileInput = function(callback, multiple) {\n\n    // Is the file stuff supported?\n    if (window.File && window.FileReader && window.FileList && window.Blob) {\n      // Yup, we're ok and make an input file selector\n      var elt = document.createElement('input');\n      elt.type = 'file';\n\n      // If we get a second argument that evaluates to true\n      // then we are looking for multiple files\n      if (multiple) {\n        // Anything gets the job done\n        elt.multiple = 'multiple';\n      }\n     \n      // Now let's handle when a file was selected\n      elt.addEventListener('change', handleFileSelect, false);\n\n      // Function to handle when a file is selected\n      // We're simplifying life and assuming that we always\n      // want to load every selected file\n      function handleFileSelect(evt) {\n        // These are the files\n        var files = evt.target.files;\n        // Load each one and trigger a callback\n        for (var i = 0; i < files.length; i++) {\n          var f = files[i];\n          var reader = new FileReader();\n          reader.onload = makeLoader(f);\n          function makeLoader(theFile) {\n            // Making a p5.File object\n            var p5file = new p5.File(theFile);\n            return function(e) {\n              p5file.data = e.target.result;\n              callback(p5file);\n            };\n          };\n          \n          // Text of data?\n          // This should likely be improved\n          if (f.type === 'text') {\n            reader.readAsText(f);\n          } else {\n            reader.readAsDataURL(f);\n          }\n        }\n      }\n      return addElement(elt, this);\n    } else {\n      console.log('The File APIs are not fully supported in this browser. Cannot create element.');\n    }\n  };\n\n\n  /** VIDEO STUFF **/\n\n  function createMedia(pInst, type, src, callback) {\n    var elt = document.createElement(type);\n    if (typeof src === 'string') {\n      src = [src];\n    }\n    for (var i=0; i<src.length; i++) {\n      var source = document.createElement('source');\n      source.src = src[i];\n      elt.appendChild(source);\n    }\n    if (typeof callback !== 'undefined') {\n      elt.addEventListener('canplaythrough', function() {\n        callback();\n      });\n    }\n\n    var c = addElement(elt, pInst, true);\n    c.loadedmetadata = false;\n    // set width and height onload metadata\n    elt.addEventListener('loadedmetadata', function() {\n      c.width = elt.videoWidth;\n      c.height = elt.videoHeight;\n      c.loadedmetadata = true;\n    });\n\n    return c;\n  }\n  /**\n   * Creates an HTML5 &lt;video&gt; element in the DOM for simple playback\n   * of audio/video. Shown by default, can be hidden with .hide()\n   * and drawn into canvas using video(). Appends to the container\n   * node if one is specified, otherwise appends to body. The first parameter\n   * can be either a single string path to a video file, or an array of string\n   * paths to different formats of the same video. This is useful for ensuring\n   * that your video can play across different browsers, as each supports\n   * different formats. See <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/Supported_media_formats\">this\n   * page for further information about supported formats.\n   *\n   * @method createVideo\n   * @param  {String|Array} src  path to a video file, or array of paths for\n   *                             supporting different browsers\n   * @param  {Object} [callback] callback function to be called upon\n   *                             'canplaythrough' event fire, that is, when the\n   *                             browser can play the media, and estimates that\n   *                             enough data has been loaded to play the media\n   *                             up to its end without having to stop for\n   *                             further buffering of content\n   * @return {Object/p5.Element} pointer to video p5.Element\n   */\n  p5.prototype.createVideo = function(src, callback) {\n    return createMedia(this, 'video', src, callback);\n  };\n\n  /** AUDIO STUFF **/\n\n  /**\n   * Creates a hidden HTML5 &lt;audio&gt; element in the DOM for simple audio\n   * playback. Appends to the container node if one is specified,\n   * otherwise appends to body. The first parameter\n   * can be either a single string path to a audio file, or an array of string\n   * paths to different formats of the same audio. This is useful for ensuring\n   * that your audio can play across different browsers, as each supports\n   * different formats. See <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/Supported_media_formats\">this\n   * page for further information about supported formats.\n   *\n   * @method createAudio\n   * @param  {String|Array} src  path to an audio file, or array of paths for\n   *                             supporting different browsers\n   * @param  {Object} [callback] callback function to be called upon\n   *                             'canplaythrough' event fire, that is, when the\n   *                             browser can play the media, and estimates that\n   *                             enough data has been loaded to play the media\n   *                             up to its end without having to stop for\n   *                             further buffering of content\n   * @return {Object/p5.Element} pointer to audio p5.Element\n   */\n  p5.prototype.createAudio = function(src, callback) {\n    return createMedia(this, 'audio', src, callback);\n  };\n\n\n  /** CAMERA STUFF **/\n\n  p5.prototype.VIDEO = 'video';\n  p5.prototype.AUDIO = 'audio';\n\n  navigator.getUserMedia  = navigator.getUserMedia ||\n                            navigator.webkitGetUserMedia ||\n                            navigator.mozGetUserMedia ||\n                            navigator.msGetUserMedia;\n\n  /**\n   * Creates a new &lt;video&gt; element that contains the audio/video feed\n   * from a webcam. This can be drawn onto the canvas using video().\n   *\n   * @method createCapture\n   * @param  {String/Constant}   type type of capture, either VIDEO or\n   *                             AUDIO if none specified, default both\n   * @return {Object/p5.Element} capture video p5.Element\n   */\n  p5.prototype.createCapture = function() {\n    var useVideo, useAudio;\n    var type = arguments[0];\n    if (type === p5.prototype.VIDEO) {\n      useVideo = true;\n    } else if (type === p5.prototype.AUDIO) {\n      useAudio = true;\n    } else {\n      useVideo = true;\n      useAudio = true;\n    }\n\n    var fps;\n    if (typeof arguments[0] === 'number') {\n      fps = arguments[0];\n    } else if (arguments.length == 2 && typeof arguments[1] === 'number') {\n      fps = arguments[1];\n    }\n\n    if (navigator.getUserMedia) {\n      var elt = document.createElement('video');\n\n      var constraints;\n      // if (fps) {\n      //   constraints = { mandatory: { minFrameRate: 1, maxFrameRate: fps } };\n      // }\n\n      useVideo = constraints || useVideo;\n      console.log(useVideo)\n\n      navigator.getUserMedia({video: useVideo, audio: useAudio}, function(stream) {\n        elt.src = window.URL.createObjectURL(stream);\n        elt.play();\n      }, function(e) { console.log(e); });\n    } else {\n      throw 'getUserMedia not supported in this browser';\n    }\n    var c = addElement(elt, this, true);\n    c.loadedmetadata = true;\n    return c;\n  };\n\n  /**\n   * Creates element with given tag in the DOM with given content.\n   * Appends to the container node if one is specified, otherwise\n   * appends to body.\n   *\n   * @method createElement\n   * @param  {String} tag tag for the new element\n   * @param  {String} [content] html content to be inserted into the element\n   * @return {Object/p5.Element} pointer to p5.Element holding created\n   *                           node\n   */\n  p5.prototype.createElement = function(tag, content) {\n    var elt = document.createElement(tag);\n    if (typeof content !== 'undefined') {\n      elt.innerHTML = content;\n    }\n    return addElement(elt, this);\n  };\n\n\n// =============================================================================\n//                         p5.Element additions\n// =============================================================================\n  /**\n   *\n   * Adds specified class to the element.\n   *\n   * @for p5.Element\n   * @method addClass\n   * @param  {String} class name of class to add\n   * @return {p5.Element}\n   */\n  p5.Element.prototype.addClass = function(c) {\n    if (this.elt.className) {\n      // PEND don't add class more than once\n      //var regex = new RegExp('[^a-zA-Z\\d:]?'+c+'[^a-zA-Z\\d:]?');\n      //if (this.elt.className.search(/[^a-zA-Z\\d:]?hi[^a-zA-Z\\d:]?/) === -1) {\n      this.elt.className = this.elt.className+' '+c;\n      //}\n    } else {\n      this.elt.className = c;\n    }\n    return this;\n  }\n\n  /**\n   *\n   * Removes specified class from the element.\n   *\n   * @method removeClass\n   * @param  {String} class name of class to remove\n   * @return {p5.Element}\n   */\n  p5.Element.prototype.removeClass = function(c) {\n    var regex = new RegExp('(?:^|\\\\s)'+c+'(?!\\\\S)');\n    this.elt.className = this.elt.className.replace(regex, '');\n    this.elt.className = this.elt.className.replace(/^\\s+|\\s+$/g, \"\"); //prettify (optional)\n    return this;\n  }\n\n  /**\n   *\n   * Attaches the element  as a child to the parent specified.\n   * Accepts either a string ID, DOM node, or p5.Element\n   *\n   * @method child\n   * @param  {String|Object} child the ID, DOM node, or p5.Element\n   *                         to add to the current element\n   * @return {p5.Element}\n   * @example\n   * <div class='norender'><code>\n   * var div0 = createDiv('this is the parent');\n   * var div1 = createDiv('this is the child');\n   * div0.child(div1); // use p5.Element\n   * </code></div>\n   * <div class='norender'><code>\n   * var div0 = createDiv('this is the parent');\n   * var div1 = createDiv('this is the child');\n   * div1.id('apples');\n   * div0.child('apples'); // use id\n   * </code></div>\n   * <div class='norender'><code>\n   * var div0 = createDiv('this is the parent');\n   * var elt = document.getElementById('myChildDiv');\n   * div0.child(elt); // use element from page\n   * </code></div>\n   */\n  p5.Element.prototype.child = function(c) {\n    if (typeof c === 'string') {\n      c = document.getElementById(c);\n    } else if (c instanceof p5.Element) {\n      c = c.elt;\n    }\n    this.elt.appendChild(c);\n    return this;\n  };\n\n\n  /**\n   *\n   * If an argument is given, sets the inner HTML of the element,\n   * replacing any existing html. If no arguments are given, returns\n   * the inner HTML of the element.\n   *\n   * @for p5.Element\n   * @method html\n   * @param  {String} [html] the HTML to be placed inside the element\n   * @return {p5.Element|String}\n   */\n  p5.Element.prototype.html = function(html) {\n    if (typeof html !== 'undefined') {\n      this.elt.innerHTML = html;\n      return this;\n    } else {\n      return this.elt.innerHTML;\n    }\n  };\n\n  /**\n   *\n   * Sets the position of the element relative to (0, 0) of the\n   * window. Essentially, sets position:absolute and left and top\n   * properties of style.\n   *\n   * @method position\n   * @param  {Number} x x-position relative to upper left of window\n   * @param  {Number} y y-position relative to upper left of window\n   * @return {p5.Element}\n   * @example\n   * <div><code class='norender'>\n   * function setup() {\n   *   var cnv = createCanvas(100, 100);\n   *   // positions canvas 50px to right and 100px\n   *   // below upper left corner of the window\n   *   cnv.position(50, 100);\n   * }\n   * </code></div>\n   */\n  p5.Element.prototype.position = function(x, y) {\n    this.elt.style.position = 'absolute';\n    this.elt.style.left = x+'px';\n    this.elt.style.top = y+'px';\n    return this;\n  };\n\n  /**\n   *\n   * Sets the given style (css) property of the element with the given value.\n   * If no value is specified, returns the value of the given property,\n   * or undefined if the property is not.\n   *\n   * @method style\n   * @param  {String} property   property to be set\n   * @param  {String} [value]    value to assign to property\n   * @return {String|p5.Element} value of property, if no value is specified\n   *                             or p5.Element\n   * @example\n   * <div><code class=\"norender\">\n   * var myDiv = createDiv(\"I like pandas.\");\n   * myDiv.style(\"color\", \"#ff0000\");\n   * myDiv.style(\"font-size\", \"18px\");\n   * </code></div>\n   */\n  p5.Element.prototype.style = function(prop, val) {\n    if (typeof val === 'undefined') {\n      var attrs = prop.split(';');\n      for (var i=0; i<attrs.length; i++) {\n        var parts = attrs[i].split(':');\n        if (parts[0] && parts[1]) {\n          this.elt.style[parts[0].trim()] = parts[1].trim();\n        }\n      }\n      // console.log(this.elt.style)\n    } else {\n      this.elt.style[prop] = val;\n    }\n    return this;\n  };\n\n\n  /**\n   *\n   * Adds a new attribute or changes the value of an existing attribute\n   * on the specified element. If no value is specified, returns the\n   * value of the given attribute, or null if attribute is not set.\n   *\n   * @method attribute\n   * @param  {String} attr       attribute to set\n   * @param  {String} [value]    value to assign to attribute\n   * @return {String|p5.Element} value of attribute, if no value is\n   *                             specified or p5.Element\n   * @example\n   * <div class=\"norender\"><code>\n   * var myDiv = createDiv(\"I like pandas.\");\n   *myDiv.attribute(\"align\", \"center\");\n   * </code></div>\n   */\n  p5.Element.prototype.attribute = function(attr, value) {\n    if (typeof value === 'undefined') {\n      return this.elt.getAttribute(attr);\n    } else {\n      this.elt.setAttribute(attr, value);\n      return this;\n    }\n  };\n\n\n  /**\n   * Either returns the value of the element if no arguments\n   * given, or sets the value of the element.\n   *\n   * @method value\n   * @param  {String|Number}     [value]\n   * @return {String|p5.Element} value of element, if no value is\n   *                             specified or p5.Element\n   */\n  p5.Element.prototype.value = function() {\n    if (arguments.length > 0) {\n      this.elt.value = arguments[0];\n      return this;\n    } else {\n      if (this.elt.type === 'range') {\n        return parseFloat(this.elt.value);\n      }\n      else return this.elt.value;\n    }\n  };\n\n  /**\n   *\n   * Shows the current element. Essentially, setting display:block for the style.\n   *\n   * @method show\n   * @return {p5.Element}\n   */\n  p5.Element.prototype.show = function() {\n    this.elt.style.display = 'block';\n    return this;\n  };\n\n  /**\n   * Hides the current element. Essentially, setting display:none for the style.\n   *\n   * @method hide\n   * @return {p5.Element}\n   */\n  p5.Element.prototype.hide = function() {\n    this.elt.style.display = 'none';\n    return this;\n  };\n\n  /**\n   *\n   * Sets the width and height of the element. AUTO can be used to\n   * only adjust one dimension.\n   *\n   * @method size\n   * @param  {Number} w width of the element\n   * @param  {Number} h height of the element\n   * @return {p5.Element}\n   */\n  p5.Element.prototype.size = function(w, h) {\n    var aW = w;\n    var aH = h;\n    var AUTO = p5.prototype.AUTO;\n\n    if (aW !== AUTO || aH !== AUTO) {\n      if (aW === AUTO) {\n        aW = h * this.elt.width / this.elt.height;\n      } else if (aH === AUTO) {\n        aH = w * this.elt.height / this.elt.width;\n      }\n      // set diff for cnv vs normal div\n      if (this.elt instanceof HTMLCanvasElement) {\n        var j = {};\n        var k  = this.elt.getContext('2d');\n        for (var prop in k) {\n          j[prop] = k[prop];\n        }\n        this.elt.setAttribute('width', aW * this._pInst._pixelDensity);\n        this.elt.setAttribute('height', aH * this._pInst._pixelDensity);\n        this.elt.setAttribute('style', 'width:' + aW + 'px !important; height:' + aH + 'px !important;');\n        this._pInst.scale(this._pInst._pixelDensity, this._pInst._pixelDensity);\n        for (var prop in j) {\n          this.elt.getContext('2d')[prop] = j[prop];\n        }\n      } else {\n        this.elt.style.width = aW+'px';\n        this.elt.style.height = aH+'px';\n        this.elt.width = aW;\n        this.elt.height = aH;\n      }\n      this.width = this.elt.offsetWidth;\n      this.height = this.elt.offsetHeight;\n      if (this._pInst) { // main canvas associated with p5 instance\n        if (this._pInst._curElement.elt === this.elt) {\n          this._pInst._setProperty('width', this.elt.offsetWidth);\n          this._pInst._setProperty('height', this.elt.offsetHeight);\n        }\n      }\n    }\n    return this;\n  };\n\n  /**\n   * Removes the element and deregisters all listeners.\n   * @method remove\n   * @example\n   * <div class='norender'><code>\n   * var myDiv = createDiv('this is some text');\n   * myDiv.remove();\n   * </code></div>\n   */\n  p5.Element.prototype.remove = function() {\n    // deregister events\n    for (var ev in this._events) {\n      this.elt.removeEventListener(ev, this._events[ev]);\n    }\n    if (this.elt.parentNode) {\n      this.elt.parentNode.removeChild(this.elt);\n    }\n    delete(this);\n  };\n\n\n\n// =============================================================================\n//                         p5.MediaElement additions\n// =============================================================================\n\n\n  /**\n   * Extends p5.Element to handle audio and video. In addition to the methods\n   * of p5.Element, it also contains methods for controlling media. It is not\n   * called directly, but p5.MediaElements are created by calling createVideo,\n   * createAudio, and createCapture.\n   *\n   * @class p5.MediaElement\n   * @constructor\n   * @param {String} elt DOM node that is wrapped\n   * @param {Object} [pInst] pointer to p5 instance\n   */\n  p5.MediaElement = function(elt, pInst) {\n    p5.Element.call(this, elt, pInst);\n  };\n  p5.MediaElement.prototype = Object.create(p5.Element.prototype);\n\n\n\n\n  /**\n   * Play an HTML5 media element.\n   *\n   * @method play\n   * @return {p5.Element}\n   */\n  p5.MediaElement.prototype.play = function() {\n    if (this.elt.currentTime === this.elt.duration) {\n      this.elt.currentTime = 0;\n    }\n    this.elt.play();\n    return this;\n  };\n\n  /**\n   * Stops an HTML5 media element (sets current time to zero).\n   *\n   * @method stop\n   * @return {p5.Element}\n   */\n  p5.MediaElement.prototype.stop = function() {\n    this.elt.pause();\n    this.elt.currentTime = 0;\n    return this;\n  };\n\n  /**\n   * Pauses an HTML5 media element.\n   *\n   * @method pause\n   * @return {p5.Element}\n   */\n  p5.MediaElement.prototype.pause = function() {\n    this.elt.pause();\n    return this;\n  };\n\n  /**\n   * Set 'loop' to true for an HTML5 media element, and starts playing.\n   *\n   * @method loop\n   * @return {p5.Element}\n   */\n  p5.MediaElement.prototype.loop = function() {\n    this.elt.setAttribute('loop', true);\n    this.play();\n    return this;\n  };\n  /**\n   * Set 'loop' to false for an HTML5 media element. Element will stop\n   * when it reaches the end.\n   *\n   * @method noLoop\n   * @return {p5.Element}\n   */\n  p5.MediaElement.prototype.noLoop = function() {\n    this.elt.setAttribute('loop', false);\n    return this;\n  };\n\n\n  /**\n   * Set HTML5 media element to autoplay or not.\n   *\n   * @method autoplay\n   * @param {Boolean} autoplay whether the element should autoplay\n   * @return {p5.Element}\n   */\n  p5.MediaElement.prototype.autoplay = function(val) {\n    this.elt.setAttribute('autoplay', val);\n    return this;\n  };\n\n  /**\n   * Sets volume for this HTML5 media element. If no argument is given,\n   * returns the current volume.\n   *\n   * @param {Number}            [val] volume between 0.0 and 1.0\n   * @return {Number|p5.MediaElement} current volume or p5.MediaElement\n   * @method volume\n   */\n  p5.MediaElement.prototype.volume = function(val) {\n    if (typeof val === 'undefined') {\n      return this.elt.volume;\n    } else {\n      this.elt.volume = val;\n    }\n  };\n\n  /**\n   * If no arguments are given, returns the current time of the elmeent.\n   * If an argument is given the current time of the element is set to it.\n   *\n   * @method time\n   * @param {Number} [time] time to jump to (in seconds)\n   * @return {Number|p5.MediaElement} current time (in seconds)\n   *                                  or p5.MediaElement\n   */\n  p5.MediaElement.prototype.time = function(val) {\n    if (typeof val === 'undefined') {\n      return this.elt.currentTime;\n    } else {\n      this.elt.currentTime = val;\n    }\n  };\n\n  /**\n   * Returns the duration of the HTML5 media element.\n   *\n   * @method duration\n   * @return {Number} duration\n   */\n  p5.MediaElement.prototype.duration = function() {\n    return this.elt.duration;\n  };\n  p5.MediaElement.prototype.pixels = [];\n  p5.MediaElement.prototype.loadPixels = function() {\n    if (this.loadedmetadata) { // wait for metadata for w/h\n      if (!this.canvas) {\n        this.canvas = document.createElement('canvas');\n        this.canvas.width = this.width;\n        this.canvas.height = this.height;\n        this.drawingContext = this.canvas.getContext('2d');\n      }\n      this.drawingContext.drawImage(this.elt, 0, 0, this.width, this.height);\n      p5.prototype.loadPixels.call(this);\n    }\n    return this;\n  }\n  p5.MediaElement.prototype.updatePixels =  function(x, y, w, h){\n    if (this.loadedmetadata) { // wait for metadata\n      p5.prototype.updatePixels.call(this, x, y, w, h);\n    }\n    return this;\n  }\n  p5.MediaElement.prototype.get = function(x, y, w, h){\n    if (this.loadedmetadata) { // wait for metadata\n      return p5.prototype.get.call(this, x, y, w, h);\n    } else return [0, 0, 0, 255];\n  };\n  p5.MediaElement.prototype.set = function(x, y, imgOrCol){\n    if (this.loadedmetadata) { // wait for metadata\n      p5.prototype.set.call(this, x, y, imgOrCol);\n    }\n  };\n}));\n"
  },
  {
    "path": "lib/p5.js",
    "content": "/*! p5.js v0.4.2 February 16, 2015 */\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd)\n    define('p5', [], function () { return (root.returnExportsGlobal = factory());});\n  else if (typeof exports === 'object')\n    module.exports = factory();\n  else\n    root['p5'] = factory();\n}(this, function () {\nvar amdclean = {};\namdclean['shim'] = function (require) {\n  window.requestDraw = function () {\n    return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (callback, element) {\n      window.setTimeout(callback, 1000 / 60);\n    };\n  }();\n}({});\namdclean['constants'] = function (require) {\n  var PI = Math.PI;\n  return {\n    ARROW: 'default',\n    CROSS: 'crosshair',\n    HAND: 'pointer',\n    MOVE: 'move',\n    TEXT: 'text',\n    WAIT: 'wait',\n    HALF_PI: PI / 2,\n    PI: PI,\n    QUARTER_PI: PI / 4,\n    TAU: PI * 2,\n    TWO_PI: PI * 2,\n    DEGREES: 'degrees',\n    RADIANS: 'radians',\n    CORNER: 'corner',\n    CORNERS: 'corners',\n    RADIUS: 'radius',\n    RIGHT: 'right',\n    LEFT: 'left',\n    CENTER: 'center',\n    TOP: 'top',\n    BOTTOM: 'bottom',\n    BASELINE: 'alphabetic',\n    POINTS: 'points',\n    LINES: 'lines',\n    TRIANGLES: 'triangles',\n    TRIANGLE_FAN: 'triangles_fan',\n    TRIANGLE_STRIP: 'triangles_strip',\n    QUADS: 'quads',\n    QUAD_STRIP: 'quad_strip',\n    CLOSE: 'close',\n    OPEN: 'open',\n    CHORD: 'chord',\n    PIE: 'pie',\n    PROJECT: 'square',\n    SQUARE: 'butt',\n    ROUND: 'round',\n    BEVEL: 'bevel',\n    MITER: 'miter',\n    RGB: 'rgb',\n    HSB: 'hsb',\n    AUTO: 'auto',\n    ALT: 18,\n    BACKSPACE: 8,\n    CONTROL: 17,\n    DELETE: 46,\n    DOWN_ARROW: 40,\n    ENTER: 13,\n    ESCAPE: 27,\n    LEFT_ARROW: 37,\n    OPTION: 18,\n    RETURN: 13,\n    RIGHT_ARROW: 39,\n    SHIFT: 16,\n    TAB: 9,\n    UP_ARROW: 38,\n    BLEND: 'normal',\n    ADD: 'lighter',\n    DARKEST: 'darken',\n    LIGHTEST: 'lighten',\n    DIFFERENCE: 'difference',\n    EXCLUSION: 'exclusion',\n    MULTIPLY: 'multiply',\n    SCREEN: 'screen',\n    REPLACE: 'source-over',\n    OVERLAY: 'overlay',\n    HARD_LIGHT: 'hard-light',\n    SOFT_LIGHT: 'soft-light',\n    DODGE: 'color-dodge',\n    BURN: 'color-burn',\n    NORMAL: 'normal',\n    ITALIC: 'italic',\n    BOLD: 'bold',\n    LINEAR: 'linear',\n    QUADRATIC: 'quadratic',\n    BEZIER: 'bezier',\n    CURVE: 'curve'\n  };\n}({});\namdclean['core'] = function (require, shim, constants) {\n  'use strict';\n  var constants = constants;\n  var p5 = function (sketch, node, sync) {\n    if (arguments.length === 2 && typeof node === 'boolean') {\n      sync = node;\n      node = undefined;\n    }\n    this._setupDone = false;\n    this._pixelDensity = window.devicePixelRatio || 1;\n    this._startTime = new Date().getTime();\n    this._userNode = node;\n    this._curElement = null;\n    this._elements = [];\n    this._preloadCount = 0;\n    this._updateInterval = 0;\n    this._isGlobal = false;\n    this._loop = true;\n    this._styles = [];\n    this._defaultCanvasSize = {\n      width: 100,\n      height: 100\n    };\n    this._events = {\n      'mousemove': null,\n      'mousedown': null,\n      'mouseup': null,\n      'click': null,\n      'mousewheel': null,\n      'mouseover': null,\n      'mouseout': null,\n      'keydown': null,\n      'keyup': null,\n      'keypress': null,\n      'touchstart': null,\n      'touchmove': null,\n      'touchend': null,\n      'resize': null,\n      'blur': null\n    };\n    this._loadingScreenId = 'p5_loading';\n    this._start = function () {\n      if (this._userNode) {\n        if (typeof this._userNode === 'string') {\n          this._userNode = document.getElementById(this._userNode);\n        }\n      }\n      this._loadingScreen = document.getElementById(this._loadingScreenId);\n      if (!this._loadingScreen) {\n        this._loadingScreen = document.createElement('loadingDiv');\n        this._loadingScreen.innerHTML = 'loading...';\n        this._loadingScreen.style.position = 'absolute';\n        var node = this._userNode || document.body;\n        node.appendChild(this._loadingScreen);\n      }\n      this.createCanvas(this._defaultCanvasSize.width, this._defaultCanvasSize.height, true);\n      var userPreload = this.preload || window.preload;\n      var context = this._isGlobal ? window : this;\n      if (userPreload) {\n        this._preloadMethods.forEach(function (f) {\n          context[f] = function () {\n            var argsArray = Array.prototype.slice.call(arguments);\n            return context._preload(f, argsArray);\n          };\n        });\n        userPreload();\n        if (this._preloadCount === 0) {\n          this._setup();\n          this._runFrames();\n          this._draw();\n        }\n      } else {\n        this._setup();\n        this._runFrames();\n        this._draw();\n      }\n    }.bind(this);\n    this._preload = function (func, args) {\n      var context = this._isGlobal ? window : this;\n      context._setProperty('_preloadCount', context._preloadCount + 1);\n      var preloadCallback = function (resp) {\n        context._setProperty('_preloadCount', context._preloadCount - 1);\n        if (context._preloadCount === 0) {\n          context._setup();\n          context._runFrames();\n          context._draw();\n        }\n      };\n      args.push(preloadCallback);\n      return p5.prototype[func].apply(context, args);\n    }.bind(this);\n    this._setup = function () {\n      var context = this._isGlobal ? window : this;\n      if (typeof context.preload === 'function') {\n        this._preloadMethods.forEach(function (f) {\n          context[f] = p5.prototype[f];\n        });\n      }\n      if (typeof context.setup === 'function') {\n        context.setup();\n      }\n      this.canvas.style.visibility = '';\n      this.canvas.className = this.canvas.className.replace('p5_hidden', '');\n      this._setupDone = true;\n      this._loadingScreen.parentNode.removeChild(this._loadingScreen);\n    }.bind(this);\n    this._draw = function () {\n      var now = new Date().getTime();\n      this._frameRate = 1000 / (now - this._lastFrameTime);\n      this._lastFrameTime = now;\n      this._setProperty('frameCount', this.frameCount + 1);\n      if (this._loop) {\n        if (this._drawInterval) {\n          clearInterval(this._drawInterval);\n        }\n        this._drawInterval = setTimeout(function () {\n          window.requestDraw(this._draw.bind(this));\n        }.bind(this), 1000 / this._targetFrameRate);\n      }\n      this.redraw();\n      this._updatePMouseCoords();\n      this._updatePTouchCoords();\n    }.bind(this);\n    this._runFrames = function () {\n      if (this._updateInterval) {\n        clearInterval(this._updateInterval);\n      }\n    }.bind(this);\n    this._setProperty = function (prop, value) {\n      this[prop] = value;\n      if (this._isGlobal) {\n        window[prop] = value;\n      }\n    }.bind(this);\n    this.remove = function () {\n      if (this._curElement) {\n        this._loop = false;\n        if (this._drawInterval) {\n          clearTimeout(this._drawInterval);\n        }\n        if (this._updateInterval) {\n          clearTimeout(this._updateInterval);\n        }\n        for (var ev in this._events) {\n          window.removeEventListener(ev, this._events[ev]);\n        }\n        for (var i = 0; i < this._elements.length; i++) {\n          var e = this._elements[i];\n          if (e.elt.parentNode) {\n            e.elt.parentNode.removeChild(e.elt);\n          }\n          for (var elt_ev in e._events) {\n            e.elt.removeEventListener(elt_ev, e._events[elt_ev]);\n          }\n        }\n        var self = this;\n        this._registeredMethods.remove.forEach(function (f) {\n          if (typeof f !== 'undefined') {\n            f.call(self);\n          }\n        });\n        if (this._isGlobal) {\n          for (var p in p5.prototype) {\n            try {\n              delete window[p];\n            } catch (x) {\n              window[p] = undefined;\n            }\n          }\n          for (var p2 in this) {\n            if (this.hasOwnProperty(p2)) {\n              try {\n                delete window[p2];\n              } catch (x) {\n                window[p2] = undefined;\n              }\n            }\n          }\n        }\n      }\n    }.bind(this);\n    for (var k in constants) {\n      p5.prototype[k] = constants[k];\n    }\n    if (!sketch) {\n      this._isGlobal = true;\n      for (var p in p5.prototype) {\n        if (typeof p5.prototype[p] === 'function') {\n          var ev = p.substring(2);\n          if (!this._events.hasOwnProperty(ev)) {\n            window[p] = p5.prototype[p].bind(this);\n          }\n        } else {\n          window[p] = p5.prototype[p];\n        }\n      }\n      for (var p2 in this) {\n        if (this.hasOwnProperty(p2)) {\n          window[p2] = this[p2];\n        }\n      }\n    } else {\n      sketch(this);\n    }\n    for (var e in this._events) {\n      var f = this['on' + e];\n      if (f) {\n        var m = f.bind(this);\n        window.addEventListener(e, m);\n        this._events[e] = m;\n      }\n    }\n    var self = this;\n    window.addEventListener('focus', function () {\n      self._setProperty('focused', true);\n    });\n    window.addEventListener('blur', function () {\n      self._setProperty('focused', false);\n    });\n    if (sync) {\n      this._start();\n    } else {\n      if (document.readyState === 'complete') {\n        this._start();\n      } else {\n        window.addEventListener('load', this._start.bind(this), false);\n      }\n    }\n  };\n  p5.prototype._preloadMethods = [\n    'loadJSON',\n    'loadImage',\n    'loadStrings',\n    'loadXML',\n    'loadShape',\n    'loadTable'\n  ];\n  p5.prototype._registeredMethods = {\n    pre: [],\n    post: [],\n    remove: []\n  };\n  p5.prototype.registerPreloadMethod = function (m) {\n    p5.prototype._preloadMethods.push(m);\n  }.bind(this);\n  p5.prototype.registerMethod = function (name, m) {\n    if (!p5.prototype._registeredMethods.hasOwnProperty(name)) {\n      p5.prototype._registeredMethods[name] = [];\n    }\n    p5.prototype._registeredMethods[name].push(m);\n  }.bind(this);\n  return p5;\n}({}, amdclean['shim'], amdclean['constants']);\namdclean['utilscolor_utils'] = function (require, core) {\n  var p5 = core;\n  p5.ColorUtils = {};\n  p5.ColorUtils.hsbaToRGBA = function (hsba) {\n    var h = hsba[0];\n    var s = hsba[1];\n    var v = hsba[2];\n    h /= 255;\n    s /= 255;\n    v /= 255;\n    var RGBA = [];\n    if (s === 0) {\n      RGBA = [\n        Math.round(v * 255),\n        Math.round(v * 255),\n        Math.round(v * 255),\n        hsba[3]\n      ];\n    } else {\n      var var_h = h * 6;\n      if (var_h === 6) {\n        var_h = 0;\n      }\n      var var_i = Math.floor(var_h);\n      var var_1 = v * (1 - s);\n      var var_2 = v * (1 - s * (var_h - var_i));\n      var var_3 = v * (1 - s * (1 - (var_h - var_i)));\n      var var_r;\n      var var_g;\n      var var_b;\n      if (var_i === 0) {\n        var_r = v;\n        var_g = var_3;\n        var_b = var_1;\n      } else if (var_i === 1) {\n        var_r = var_2;\n        var_g = v;\n        var_b = var_1;\n      } else if (var_i === 2) {\n        var_r = var_1;\n        var_g = v;\n        var_b = var_3;\n      } else if (var_i === 3) {\n        var_r = var_1;\n        var_g = var_2;\n        var_b = v;\n      } else if (var_i === 4) {\n        var_r = var_3;\n        var_g = var_1;\n        var_b = v;\n      } else {\n        var_r = v;\n        var_g = var_1;\n        var_b = var_2;\n      }\n      RGBA = [\n        Math.round(var_r * 255),\n        Math.round(var_g * 255),\n        Math.round(var_b * 255),\n        hsba[3]\n      ];\n    }\n    return RGBA;\n  };\n  p5.ColorUtils.rgbaToHSBA = function (rgba) {\n    var var_R = rgba[0] / 255;\n    var var_G = rgba[1] / 255;\n    var var_B = rgba[2] / 255;\n    var var_Min = Math.min(var_R, var_G, var_B);\n    var var_Max = Math.max(var_R, var_G, var_B);\n    var del_Max = var_Max - var_Min;\n    var H;\n    var S;\n    var V = var_Max;\n    if (del_Max === 0) {\n      H = 0;\n      S = 0;\n    } else {\n      S = del_Max / var_Max;\n      var del_R = ((var_Max - var_R) / 6 + del_Max / 2) / del_Max;\n      var del_G = ((var_Max - var_G) / 6 + del_Max / 2) / del_Max;\n      var del_B = ((var_Max - var_B) / 6 + del_Max / 2) / del_Max;\n      if (var_R === var_Max) {\n        H = del_B - del_G;\n      } else if (var_G === var_Max) {\n        H = 1 / 3 + del_R - del_B;\n      } else if (var_B === var_Max) {\n        H = 2 / 3 + del_G - del_R;\n      }\n      if (H < 0) {\n        H += 1;\n      }\n      if (H > 1) {\n        H -= 1;\n      }\n    }\n    return [\n      Math.round(H * 255),\n      Math.round(S * 255),\n      Math.round(V * 255),\n      rgba[3]\n    ];\n  };\n  return p5.ColorUtils;\n}({}, amdclean['core']);\namdclean['p5Color'] = function (require, core, utilscolor_utils, constants) {\n  var p5 = core;\n  var color_utils = utilscolor_utils;\n  var constants = constants;\n  p5.Color = function (pInst, vals) {\n    this.color_array = p5.Color._getFormattedColor.apply(pInst, vals);\n    this._normalizeColorArray(pInst);\n    if (pInst._colorMode === constants.HSB) {\n      this.hsba = this.color_array;\n      this.rgba = color_utils.hsbaToRGBA(this.hsba);\n    } else {\n      this.rgba = this.color_array;\n      this.hsba = color_utils.rgbaToHSBA(this.rgba);\n    }\n    return this;\n  };\n  p5.Color.prototype._normalizeColorArray = function (pInst) {\n    var isRGB = pInst._colorMode === constants.RGB;\n    var maxArr = isRGB ? pInst._maxRGB : pInst._maxHSB;\n    var arr = this.color_array;\n    arr[0] *= 255 / maxArr[0];\n    arr[1] *= 255 / maxArr[1];\n    arr[2] *= 255 / maxArr[2];\n    arr[3] *= 255 / maxArr[3];\n    return arr;\n  };\n  p5.Color.prototype.getHue = function () {\n    return this.hsba[0];\n  };\n  p5.Color.prototype.getSaturation = function () {\n    return this.hsba[1];\n  };\n  p5.Color.prototype.getBrightness = function () {\n    return this.hsba[2];\n  };\n  p5.Color.prototype.getRed = function () {\n    return this.rgba[0];\n  };\n  p5.Color.prototype.getGreen = function () {\n    return this.rgba[1];\n  };\n  p5.Color.prototype.getBlue = function () {\n    return this.rgba[2];\n  };\n  p5.Color.prototype.getAlpha = function () {\n    return this.rgba[3];\n  };\n  p5.Color.prototype.toString = function () {\n    var a = this.rgba;\n    for (var i = 0; i < 3; i++) {\n      a[i] = Math.floor(a[i]);\n    }\n    var alpha = typeof a[3] !== 'undefined' ? a[3] / 255 : 1;\n    return 'rgba(' + a[0] + ',' + a[1] + ',' + a[2] + ',' + alpha + ')';\n  };\n  p5.Color._getFormattedColor = function () {\n    var r, g, b, a;\n    if (arguments.length >= 3) {\n      r = arguments[0];\n      g = arguments[1];\n      b = arguments[2];\n      a = typeof arguments[3] === 'number' ? arguments[3] : 255;\n    } else {\n      if (this._colorMode === constants.RGB) {\n        r = g = b = arguments[0];\n      } else {\n        r = b = arguments[0];\n        g = 0;\n      }\n      a = typeof arguments[1] === 'number' ? arguments[1] : 255;\n    }\n    return [\n      r,\n      g,\n      b,\n      a\n    ];\n  };\n  return p5.Color;\n}({}, amdclean['core'], amdclean['utilscolor_utils'], amdclean['constants']);\namdclean['p5Element'] = function (require, core) {\n  var p5 = core;\n  p5.Element = function (elt, pInst) {\n    this.elt = elt;\n    this._pInst = pInst;\n    this._events = {};\n    this.width = this.elt.offsetWidth;\n    this.height = this.elt.offsetHeight;\n  };\n  p5.Element.prototype.parent = function (p) {\n    if (typeof p === 'string') {\n      p = document.getElementById(p);\n    } else if (p instanceof p5.Element) {\n      p = p.elt;\n    }\n    p.appendChild(this.elt);\n    return this;\n  };\n  p5.Element.prototype.id = function (id) {\n    this.elt.id = id;\n    return this;\n  };\n  p5.Element.prototype.class = function (c) {\n    this.elt.className += ' ' + c;\n    return this;\n  };\n  p5.Element.prototype.mousePressed = function (fxn) {\n    attachListener('mousedown', fxn, this);\n    attachListener('touchstart', fxn, this);\n    return this;\n  };\n  p5.Element.prototype.mouseWheel = function (fxn) {\n    attachListener('mousewheel', fxn, this);\n    return this;\n  };\n  p5.Element.prototype.mouseReleased = function (fxn) {\n    attachListener('mouseup', fxn, this);\n    attachListener('touchend', fxn, this);\n    return this;\n  };\n  p5.Element.prototype.mouseClicked = function (fxn) {\n    attachListener('click', fxn, this);\n    return this;\n  };\n  p5.Element.prototype.mouseMoved = function (fxn) {\n    attachListener('mousemove', fxn, this);\n    attachListener('touchmove', fxn, this);\n    return this;\n  };\n  p5.Element.prototype.mouseOver = function (fxn) {\n    attachListener('mouseover', fxn, this);\n    return this;\n  };\n  p5.Element.prototype.mouseOut = function (fxn) {\n    attachListener('mouseout', fxn, this);\n    return this;\n  };\n  p5.Element.prototype.touchStarted = function (fxn) {\n    attachListener('touchstart', fxn, this);\n    attachListener('mousedown', fxn, this);\n    return this;\n  };\n  p5.Element.prototype.touchMoved = function (fxn) {\n    attachListener('touchmove', fxn, this);\n    attachListener('mousemove', fxn, this);\n    return this;\n  };\n  p5.Element.prototype.touchEnded = function (fxn) {\n    attachListener('touchend', fxn, this);\n    attachListener('mouseup', fxn, this);\n    return this;\n  };\n  p5.Element.prototype.dragOver = function (fxn) {\n    attachListener('dragover', fxn, this);\n    return this;\n  };\n  p5.Element.prototype.dragLeave = function (fxn) {\n    attachListener('dragleave', fxn, this);\n    return this;\n  };\n  p5.Element.prototype.drop = function (callback, fxn) {\n    function makeLoader(theFile) {\n      var p5file = new p5.File(theFile);\n      return function (e) {\n        p5file.data = e.target.result;\n        callback(p5file);\n      };\n    }\n    if (window.File && window.FileReader && window.FileList && window.Blob) {\n      attachListener('dragover', function (evt) {\n        evt.stopPropagation();\n        evt.preventDefault();\n      }, this);\n      attachListener('dragleave', function (evt) {\n        evt.stopPropagation();\n        evt.preventDefault();\n      }, this);\n      if (arguments.length > 1) {\n        attachListener('drop', fxn, this);\n      }\n      attachListener('drop', function (evt) {\n        evt.stopPropagation();\n        evt.preventDefault();\n        var files = evt.dataTransfer.files;\n        for (var i = 0; i < files.length; i++) {\n          var f = files[i];\n          var reader = new FileReader();\n          reader.onload = makeLoader(f);\n          if (f.type === 'text') {\n            reader.readAsText(f);\n          } else {\n            reader.readAsDataURL(f);\n          }\n        }\n      }, this);\n    } else {\n      console.log('The File APIs are not fully supported in this browser.');\n    }\n    return this;\n  };\n  function attachListener(ev, fxn, ctx) {\n    var f = fxn.bind(ctx);\n    ctx.elt.addEventListener(ev, f, false);\n    ctx._events[ev] = f;\n  }\n  p5.Element.prototype._setProperty = function (prop, value) {\n    this[prop] = value;\n  };\n  return p5.Element;\n}({}, amdclean['core']);\namdclean['p5Graphics'] = function (require, core, constants) {\n  var p5 = core;\n  var constants = constants;\n  p5.Graphics = function (elt, pInst, isMainCanvas) {\n    p5.Element.call(this, elt, pInst);\n    this.canvas = elt;\n    this.drawingContext = this.canvas.getContext('2d');\n    this._pInst = pInst;\n    if (isMainCanvas) {\n      this._isMainCanvas = true;\n      this._pInst._setProperty('_curElement', this);\n      this._pInst._setProperty('canvas', this.canvas);\n      this._pInst._setProperty('drawingContext', this.drawingContext);\n      this._pInst._setProperty('width', this.width);\n      this._pInst._setProperty('height', this.height);\n    } else {\n      this.canvas.style.display = 'none';\n      this._styles = [];\n    }\n  };\n  p5.Graphics.prototype = Object.create(p5.Element.prototype);\n  p5.Graphics.prototype._applyDefaults = function () {\n    this.drawingContext.fillStyle = '#FFFFFF';\n    this.drawingContext.strokeStyle = '#000000';\n    this.drawingContext.lineCap = constants.ROUND;\n    this.drawingContext.font = 'normal 12px sans-serif';\n  };\n  p5.Graphics.prototype.resize = function (w, h) {\n    this.width = w;\n    this.height = h;\n    this.elt.width = w * this._pInst._pixelDensity;\n    this.elt.height = h * this._pInst._pixelDensity;\n    this.elt.style.width = w + 'px';\n    this.elt.style.height = h + 'px';\n    if (this._isMainCanvas) {\n      this._pInst._setProperty('width', this.width);\n      this._pInst._setProperty('height', this.height);\n    }\n    this.drawingContext.scale(this._pInst._pixelDensity, this._pInst._pixelDensity);\n  };\n  return p5.Graphics;\n}({}, amdclean['core'], amdclean['constants']);\namdclean['filters'] = function (require) {\n  'use strict';\n  var Filters = {};\n  Filters._toPixels = function (canvas) {\n    if (canvas instanceof ImageData) {\n      return canvas.data;\n    } else {\n      return canvas.getContext('2d').getImageData(0, 0, canvas.width, canvas.height).data;\n    }\n  };\n  Filters._getARGB = function (data, i) {\n    var offset = i * 4;\n    return data[offset + 3] << 24 & 4278190080 | data[offset] << 16 & 16711680 | data[offset + 1] << 8 & 65280 | data[offset + 2] & 255;\n  };\n  Filters._setPixels = function (pixels, data) {\n    var offset = 0;\n    for (var i = 0, al = pixels.length; i < al; i++) {\n      offset = i * 4;\n      pixels[offset + 0] = (data[i] & 16711680) >>> 16;\n      pixels[offset + 1] = (data[i] & 65280) >>> 8;\n      pixels[offset + 2] = data[i] & 255;\n      pixels[offset + 3] = (data[i] & 4278190080) >>> 24;\n    }\n  };\n  Filters._toImageData = function (canvas) {\n    if (canvas instanceof ImageData) {\n      return canvas;\n    } else {\n      return canvas.getContext('2d').getImageData(0, 0, canvas.width, canvas.height);\n    }\n  };\n  Filters._createImageData = function (width, height) {\n    Filters._tmpCanvas = document.createElement('canvas');\n    Filters._tmpCtx = Filters._tmpCanvas.getContext('2d');\n    return this._tmpCtx.createImageData(width, height);\n  };\n  Filters.apply = function (canvas, func, filterParam) {\n    var ctx = canvas.getContext('2d');\n    var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);\n    var newImageData = func(imageData, filterParam);\n    if (newImageData instanceof ImageData) {\n      ctx.putImageData(newImageData, 0, 0, 0, 0, canvas.width, canvas.height);\n    } else {\n      ctx.putImageData(imageData, 0, 0, 0, 0, canvas.width, canvas.height);\n    }\n  };\n  Filters.threshold = function (canvas, level) {\n    var pixels = Filters._toPixels(canvas);\n    if (level === undefined) {\n      level = 0.5;\n    }\n    var thresh = Math.floor(level * 255);\n    for (var i = 0; i < pixels.length; i += 4) {\n      var r = pixels[i];\n      var g = pixels[i + 1];\n      var b = pixels[i + 2];\n      var grey = 0.2126 * r + 0.7152 * g + 0.0722 * b;\n      var val;\n      if (grey >= thresh) {\n        val = 255;\n      } else {\n        val = 0;\n      }\n      pixels[i] = pixels[i + 1] = pixels[i + 2] = val;\n    }\n  };\n  Filters.gray = function (canvas) {\n    var pixels = Filters._toPixels(canvas);\n    for (var i = 0; i < pixels.length; i += 4) {\n      var r = pixels[i];\n      var g = pixels[i + 1];\n      var b = pixels[i + 2];\n      var gray = 0.2126 * r + 0.7152 * g + 0.0722 * b;\n      pixels[i] = pixels[i + 1] = pixels[i + 2] = gray;\n    }\n  };\n  Filters.opaque = function (canvas) {\n    var pixels = Filters._toPixels(canvas);\n    for (var i = 0; i < pixels.length; i += 4) {\n      pixels[i + 3] = 255;\n    }\n    return pixels;\n  };\n  Filters.invert = function (canvas) {\n    var pixels = Filters._toPixels(canvas);\n    for (var i = 0; i < pixels.length; i += 4) {\n      pixels[i] = 255 - pixels[i];\n      pixels[i + 1] = 255 - pixels[i + 1];\n      pixels[i + 2] = 255 - pixels[i + 2];\n    }\n  };\n  Filters.posterize = function (canvas, level) {\n    var pixels = Filters._toPixels(canvas);\n    if (level < 2 || level > 255) {\n      throw new Error('Level must be greater than 2 and less than 255 for posterize');\n    }\n    var levels1 = level - 1;\n    for (var i = 0; i < pixels.length; i += 4) {\n      var rlevel = pixels[i];\n      var glevel = pixels[i + 1];\n      var blevel = pixels[i + 2];\n      pixels[i] = (rlevel * level >> 8) * 255 / levels1;\n      pixels[i + 1] = (glevel * level >> 8) * 255 / levels1;\n      pixels[i + 2] = (blevel * level >> 8) * 255 / levels1;\n    }\n  };\n  Filters.dilate = function (canvas) {\n    var pixels = Filters._toPixels(canvas);\n    var currIdx = 0;\n    var maxIdx = pixels.length ? pixels.length / 4 : 0;\n    var out = new Int32Array(maxIdx);\n    var currRowIdx, maxRowIdx, colOrig, colOut, currLum;\n    var idxRight, idxLeft, idxUp, idxDown, colRight, colLeft, colUp, colDown, lumRight, lumLeft, lumUp, lumDown;\n    while (currIdx < maxIdx) {\n      currRowIdx = currIdx;\n      maxRowIdx = currIdx + canvas.width;\n      while (currIdx < maxRowIdx) {\n        colOrig = colOut = Filters._getARGB(pixels, currIdx);\n        idxLeft = currIdx - 1;\n        idxRight = currIdx + 1;\n        idxUp = currIdx - canvas.width;\n        idxDown = currIdx + canvas.width;\n        if (idxLeft < currRowIdx) {\n          idxLeft = currIdx;\n        }\n        if (idxRight >= maxRowIdx) {\n          idxRight = currIdx;\n        }\n        if (idxUp < 0) {\n          idxUp = 0;\n        }\n        if (idxDown >= maxIdx) {\n          idxDown = currIdx;\n        }\n        colUp = Filters._getARGB(pixels, idxUp);\n        colLeft = Filters._getARGB(pixels, idxLeft);\n        colDown = Filters._getARGB(pixels, idxDown);\n        colRight = Filters._getARGB(pixels, idxRight);\n        currLum = 77 * (colOrig >> 16 & 255) + 151 * (colOrig >> 8 & 255) + 28 * (colOrig & 255);\n        lumLeft = 77 * (colLeft >> 16 & 255) + 151 * (colLeft >> 8 & 255) + 28 * (colLeft & 255);\n        lumRight = 77 * (colRight >> 16 & 255) + 151 * (colRight >> 8 & 255) + 28 * (colRight & 255);\n        lumUp = 77 * (colUp >> 16 & 255) + 151 * (colUp >> 8 & 255) + 28 * (colUp & 255);\n        lumDown = 77 * (colDown >> 16 & 255) + 151 * (colDown >> 8 & 255) + 28 * (colDown & 255);\n        if (lumLeft > currLum) {\n          colOut = colLeft;\n          currLum = lumLeft;\n        }\n        if (lumRight > currLum) {\n          colOut = colRight;\n          currLum = lumRight;\n        }\n        if (lumUp > currLum) {\n          colOut = colUp;\n          currLum = lumUp;\n        }\n        if (lumDown > currLum) {\n          colOut = colDown;\n          currLum = lumDown;\n        }\n        out[currIdx++] = colOut;\n      }\n    }\n    Filters._setPixels(pixels, out);\n  };\n  Filters.erode = function (canvas) {\n    var pixels = Filters._toPixels(canvas);\n    var currIdx = 0;\n    var maxIdx = pixels.length ? pixels.length / 4 : 0;\n    var out = new Int32Array(maxIdx);\n    var currRowIdx, maxRowIdx, colOrig, colOut, currLum;\n    var idxRight, idxLeft, idxUp, idxDown, colRight, colLeft, colUp, colDown, lumRight, lumLeft, lumUp, lumDown;\n    while (currIdx < maxIdx) {\n      currRowIdx = currIdx;\n      maxRowIdx = currIdx + canvas.width;\n      while (currIdx < maxRowIdx) {\n        colOrig = colOut = Filters._getARGB(pixels, currIdx);\n        idxLeft = currIdx - 1;\n        idxRight = currIdx + 1;\n        idxUp = currIdx - canvas.width;\n        idxDown = currIdx + canvas.width;\n        if (idxLeft < currRowIdx) {\n          idxLeft = currIdx;\n        }\n        if (idxRight >= maxRowIdx) {\n          idxRight = currIdx;\n        }\n        if (idxUp < 0) {\n          idxUp = 0;\n        }\n        if (idxDown >= maxIdx) {\n          idxDown = currIdx;\n        }\n        colUp = Filters._getARGB(pixels, idxUp);\n        colLeft = Filters._getARGB(pixels, idxLeft);\n        colDown = Filters._getARGB(pixels, idxDown);\n        colRight = Filters._getARGB(pixels, idxRight);\n        currLum = 77 * (colOrig >> 16 & 255) + 151 * (colOrig >> 8 & 255) + 28 * (colOrig & 255);\n        lumLeft = 77 * (colLeft >> 16 & 255) + 151 * (colLeft >> 8 & 255) + 28 * (colLeft & 255);\n        lumRight = 77 * (colRight >> 16 & 255) + 151 * (colRight >> 8 & 255) + 28 * (colRight & 255);\n        lumUp = 77 * (colUp >> 16 & 255) + 151 * (colUp >> 8 & 255) + 28 * (colUp & 255);\n        lumDown = 77 * (colDown >> 16 & 255) + 151 * (colDown >> 8 & 255) + 28 * (colDown & 255);\n        if (lumLeft < currLum) {\n          colOut = colLeft;\n          currLum = lumLeft;\n        }\n        if (lumRight < currLum) {\n          colOut = colRight;\n          currLum = lumRight;\n        }\n        if (lumUp < currLum) {\n          colOut = colUp;\n          currLum = lumUp;\n        }\n        if (lumDown < currLum) {\n          colOut = colDown;\n          currLum = lumDown;\n        }\n        out[currIdx++] = colOut;\n      }\n    }\n    Filters._setPixels(pixels, out);\n  };\n  var blurRadius;\n  var blurKernelSize;\n  var blurKernel;\n  var blurMult;\n  function buildBlurKernel(r) {\n    var radius = r * 3.5 | 0;\n    radius = radius < 1 ? 1 : radius < 248 ? radius : 248;\n    if (blurRadius !== radius) {\n      blurRadius = radius;\n      blurKernelSize = 1 + blurRadius << 1;\n      blurKernel = new Int32Array(blurKernelSize);\n      blurMult = new Array(blurKernelSize);\n      for (var l = 0; l < blurKernelSize; l++) {\n        blurMult[l] = new Int32Array(256);\n      }\n      var bk, bki;\n      var bm, bmi;\n      for (var i = 1, radiusi = radius - 1; i < radius; i++) {\n        blurKernel[radius + i] = blurKernel[radiusi] = bki = radiusi * radiusi;\n        bm = blurMult[radius + i];\n        bmi = blurMult[radiusi--];\n        for (var j = 0; j < 256; j++) {\n          bm[j] = bmi[j] = bki * j;\n        }\n      }\n      bk = blurKernel[radius] = radius * radius;\n      bm = blurMult[radius];\n      for (var k = 0; k < 256; k++) {\n        bm[k] = bk * k;\n      }\n    }\n  }\n  function blurARGB(canvas, radius) {\n    var pixels = Filters._toPixels(canvas);\n    var width = canvas.width;\n    var height = canvas.height;\n    var numPackedPixels = width * height;\n    var argb = new Int32Array(numPackedPixels);\n    for (var j = 0; j < numPackedPixels; j++) {\n      argb[j] = Filters._getARGB(pixels, j);\n    }\n    var sum, cr, cg, cb, ca;\n    var read, ri, ym, ymi, bk0;\n    var a2 = new Int32Array(numPackedPixels);\n    var r2 = new Int32Array(numPackedPixels);\n    var g2 = new Int32Array(numPackedPixels);\n    var b2 = new Int32Array(numPackedPixels);\n    var yi = 0;\n    buildBlurKernel(radius);\n    var x, y, i;\n    var bm;\n    for (y = 0; y < height; y++) {\n      for (x = 0; x < width; x++) {\n        cb = cg = cr = ca = sum = 0;\n        read = x - blurRadius;\n        if (read < 0) {\n          bk0 = -read;\n          read = 0;\n        } else {\n          if (read >= width) {\n            break;\n          }\n          bk0 = 0;\n        }\n        for (i = bk0; i < blurKernelSize; i++) {\n          if (read >= width) {\n            break;\n          }\n          var c = argb[read + yi];\n          bm = blurMult[i];\n          ca += bm[(c & -16777216) >>> 24];\n          cr += bm[(c & 16711680) >> 16];\n          cg += bm[(c & 65280) >> 8];\n          cb += bm[c & 255];\n          sum += blurKernel[i];\n          read++;\n        }\n        ri = yi + x;\n        a2[ri] = ca / sum;\n        r2[ri] = cr / sum;\n        g2[ri] = cg / sum;\n        b2[ri] = cb / sum;\n      }\n      yi += width;\n    }\n    yi = 0;\n    ym = -blurRadius;\n    ymi = ym * width;\n    for (y = 0; y < height; y++) {\n      for (x = 0; x < width; x++) {\n        cb = cg = cr = ca = sum = 0;\n        if (ym < 0) {\n          bk0 = ri = -ym;\n          read = x;\n        } else {\n          if (ym >= height) {\n            break;\n          }\n          bk0 = 0;\n          ri = ym;\n          read = x + ymi;\n        }\n        for (i = bk0; i < blurKernelSize; i++) {\n          if (ri >= height) {\n            break;\n          }\n          bm = blurMult[i];\n          ca += bm[a2[read]];\n          cr += bm[r2[read]];\n          cg += bm[g2[read]];\n          cb += bm[b2[read]];\n          sum += blurKernel[i];\n          ri++;\n          read += width;\n        }\n        argb[x + yi] = ca / sum << 24 | cr / sum << 16 | cg / sum << 8 | cb / sum;\n      }\n      yi += width;\n      ymi += width;\n      ym++;\n    }\n    Filters._setPixels(pixels, argb);\n  }\n  Filters.blur = function (canvas, radius) {\n    blurARGB(canvas, radius);\n  };\n  return Filters;\n}({});\namdclean['p5Image'] = function (require, core, filters) {\n  'use strict';\n  var p5 = core;\n  var Filters = filters;\n  p5.Image = function (width, height) {\n    this.width = width;\n    this.height = height;\n    this.canvas = document.createElement('canvas');\n    this.canvas.width = this.width;\n    this.canvas.height = this.height;\n    this.drawingContext = this.canvas.getContext('2d');\n    this.pixels = [];\n  };\n  p5.Image.prototype._setProperty = function (prop, value) {\n    this[prop] = value;\n  };\n  p5.Image.prototype.loadPixels = function () {\n    p5.prototype.loadPixels.call(this);\n  };\n  p5.Image.prototype.updatePixels = function (x, y, w, h) {\n    p5.prototype.updatePixels.call(this, x, y, w, h);\n  };\n  p5.Image.prototype.get = function (x, y, w, h) {\n    return p5.prototype.get.call(this, x, y, w, h);\n  };\n  p5.Image.prototype.set = function (x, y, imgOrCol) {\n    p5.prototype.set.call(this, x, y, imgOrCol);\n  };\n  p5.Image.prototype.resize = function (width, height) {\n    width = width || this.canvas.width;\n    height = height || this.canvas.height;\n    var tempCanvas = document.createElement('canvas');\n    tempCanvas.width = width;\n    tempCanvas.height = height;\n    tempCanvas.getContext('2d').drawImage(this.canvas, 0, 0, this.canvas.width, this.canvas.height, 0, 0, tempCanvas.width, tempCanvas.height);\n    this.canvas.width = this.width = width;\n    this.canvas.height = this.height = height;\n    this.drawingContext.drawImage(tempCanvas, 0, 0, width, height, 0, 0, width, height);\n    if (this.pixels.length > 0) {\n      this.loadPixels();\n    }\n  };\n  p5.Image.prototype.copy = function () {\n    p5.prototype.copy.apply(this, arguments);\n  };\n  p5.Image.prototype.mask = function (p5Image) {\n    if (p5Image === undefined) {\n      p5Image = this;\n    }\n    var currBlend = this.drawingContext.globalCompositeOperation;\n    var scaleFactor = 1;\n    if (p5Image instanceof p5.Graphics) {\n      scaleFactor = p5Image._pInst._pixelDensity;\n    }\n    var copyArgs = [\n        p5Image,\n        0,\n        0,\n        scaleFactor * p5Image.width,\n        scaleFactor * p5Image.height,\n        0,\n        0,\n        this.width,\n        this.height\n      ];\n    this.drawingContext.globalCompositeOperation = 'destination-in';\n    this.copy.apply(this, copyArgs);\n    this.drawingContext.globalCompositeOperation = currBlend;\n  };\n  p5.Image.prototype.filter = function (operation, value) {\n    Filters.apply(this.canvas, Filters[operation.toLowerCase()], value);\n  };\n  p5.Image.prototype.blend = function () {\n    p5.prototype.blend.apply(this, arguments);\n  };\n  p5.Image.prototype.save = function (filename, extension) {\n    var mimeType;\n    if (!extension) {\n      extension = 'png';\n      mimeType = 'image/png';\n    } else {\n      switch (extension.toLowerCase()) {\n      case 'png':\n        mimeType = 'image/png';\n        break;\n      case 'jpeg':\n        mimeType = 'image/jpeg';\n        break;\n      case 'jpg':\n        mimeType = 'image/jpeg';\n        break;\n      default:\n        mimeType = 'image/png';\n        break;\n      }\n    }\n    var downloadMime = 'image/octet-stream';\n    var imageData = this.canvas.toDataURL(mimeType);\n    imageData = imageData.replace(mimeType, downloadMime);\n    p5.prototype.downloadFile(imageData, filename, extension);\n  };\n  return p5.Image;\n}({}, amdclean['core'], amdclean['filters']);\namdclean['p5File'] = function (require, core) {\n  var p5 = core;\n  p5.File = function (file, pInst) {\n    this.file = file;\n    this._pInst = pInst;\n    var typeList = file.type.split('/');\n    this.type = typeList[0];\n    this.subtype = typeList[1];\n    this.name = file.name;\n    this.size = file.size;\n    this.data = undefined;\n  };\n  return p5.File;\n}({}, amdclean['core']);\namdclean['polargeometry'] = function (require) {\n  return {\n    degreesToRadians: function (x) {\n      return 2 * Math.PI * x / 360;\n    },\n    radiansToDegrees: function (x) {\n      return 360 * x / (2 * Math.PI);\n    }\n  };\n}({});\namdclean['p5Vector'] = function (require, core, polargeometry, constants) {\n  'use strict';\n  var p5 = core;\n  var polarGeometry = polargeometry;\n  var constants = constants;\n  p5.Vector = function () {\n    var x, y, z;\n    if (arguments[0] instanceof p5) {\n      this.p5 = arguments[0];\n      x = arguments[1][0] || 0;\n      y = arguments[1][1] || 0;\n      z = arguments[1][2] || 0;\n    } else {\n      x = arguments[0] || 0;\n      y = arguments[1] || 0;\n      z = arguments[2] || 0;\n    }\n    this.x = x;\n    this.y = y;\n    this.z = z;\n  };\n  p5.Vector.prototype.set = function (x, y, z) {\n    if (x instanceof p5.Vector) {\n      this.x = x.x || 0;\n      this.y = x.y || 0;\n      this.z = x.z || 0;\n      return this;\n    }\n    if (x instanceof Array) {\n      this.x = x[0] || 0;\n      this.y = x[1] || 0;\n      this.z = x[2] || 0;\n      return this;\n    }\n    this.x = x || 0;\n    this.y = y || 0;\n    this.z = z || 0;\n    return this;\n  };\n  p5.Vector.prototype.copy = function () {\n    if (this.p5) {\n      return new p5.Vector(this.p5, [\n        this.x,\n        this.y,\n        this.z\n      ]);\n    } else {\n      return new p5.Vector(this.x, this.y, this.z);\n    }\n  };\n  p5.Vector.prototype.add = function (x, y, z) {\n    if (x instanceof p5.Vector) {\n      this.x += x.x || 0;\n      this.y += x.y || 0;\n      this.z += x.z || 0;\n      return this;\n    }\n    if (x instanceof Array) {\n      this.x += x[0] || 0;\n      this.y += x[1] || 0;\n      this.z += x[2] || 0;\n      return this;\n    }\n    this.x += x || 0;\n    this.y += y || 0;\n    this.z += z || 0;\n    return this;\n  };\n  p5.Vector.prototype.sub = function (x, y, z) {\n    if (x instanceof p5.Vector) {\n      this.x -= x.x || 0;\n      this.y -= x.y || 0;\n      this.z -= x.z || 0;\n      return this;\n    }\n    if (x instanceof Array) {\n      this.x -= x[0] || 0;\n      this.y -= x[1] || 0;\n      this.z -= x[2] || 0;\n      return this;\n    }\n    this.x -= x || 0;\n    this.y -= y || 0;\n    this.z -= z || 0;\n    return this;\n  };\n  p5.Vector.prototype.mult = function (n) {\n    this.x *= n || 0;\n    this.y *= n || 0;\n    this.z *= n || 0;\n    return this;\n  };\n  p5.Vector.prototype.div = function (n) {\n    this.x /= n;\n    this.y /= n;\n    this.z /= n;\n    return this;\n  };\n  p5.Vector.prototype.mag = function () {\n    return Math.sqrt(this.magSq());\n  };\n  p5.Vector.prototype.magSq = function () {\n    var x = this.x, y = this.y, z = this.z;\n    return x * x + y * y + z * z;\n  };\n  p5.Vector.prototype.dot = function (x, y, z) {\n    if (x instanceof p5.Vector) {\n      return this.dot(x.x, x.y, x.z);\n    }\n    return this.x * (x || 0) + this.y * (y || 0) + this.z * (z || 0);\n  };\n  p5.Vector.prototype.cross = function (v) {\n    var x = this.y * v.z - this.z * v.y;\n    var y = this.z * v.x - this.x * v.z;\n    var z = this.x * v.y - this.y * v.x;\n    if (this.p5) {\n      return new p5.Vector(this.p5, [\n        x,\n        y,\n        z\n      ]);\n    } else {\n      return new p5.Vector(x, y, z);\n    }\n  };\n  p5.Vector.prototype.dist = function (v) {\n    var d = v.copy().sub(this);\n    return d.mag();\n  };\n  p5.Vector.prototype.normalize = function () {\n    return this.div(this.mag());\n  };\n  p5.Vector.prototype.limit = function (l) {\n    var mSq = this.magSq();\n    if (mSq > l * l) {\n      this.div(Math.sqrt(mSq));\n      this.mult(l);\n    }\n    return this;\n  };\n  p5.Vector.prototype.setMag = function (n) {\n    return this.normalize().mult(n);\n  };\n  p5.Vector.prototype.heading = function () {\n    var h = Math.atan2(this.y, this.x);\n    if (this.p5) {\n      if (this.p5._angleMode === constants.RADIANS) {\n        return h;\n      } else {\n        return polarGeometry.radiansToDegrees(h);\n      }\n    } else {\n      return h;\n    }\n  };\n  p5.Vector.prototype.rotate = function (a) {\n    if (this.p5) {\n      if (this.p5._angleMode === constants.DEGREES) {\n        a = polarGeometry.degreesToRadians(a);\n      }\n    }\n    var newHeading = this.heading() + a;\n    var mag = this.mag();\n    this.x = Math.cos(newHeading) * mag;\n    this.y = Math.sin(newHeading) * mag;\n    return this;\n  };\n  p5.Vector.prototype.lerp = function (x, y, z, amt) {\n    if (x instanceof p5.Vector) {\n      return this.lerp(x.x, x.y, x.z, y);\n    }\n    this.x += (x - this.x) * amt || 0;\n    this.y += (y - this.y) * amt || 0;\n    this.z += (z - this.z) * amt || 0;\n    return this;\n  };\n  p5.Vector.prototype.array = function () {\n    return [\n      this.x || 0,\n      this.y || 0,\n      this.z || 0\n    ];\n  };\n  p5.Vector.fromAngle = function (angle) {\n    if (this.p5) {\n      if (this.p5._angleMode === constants.DEGREES) {\n        angle = polarGeometry.degreesToRadians(angle);\n      }\n    }\n    if (this.p5) {\n      return new p5.Vector(this.p5, [\n        Math.cos(angle),\n        Math.sin(angle),\n        0\n      ]);\n    } else {\n      return new p5.Vector(Math.cos(angle), Math.sin(angle), 0);\n    }\n  };\n  p5.Vector.random2D = function () {\n    var angle;\n    if (this.p5) {\n      if (this.p5._angleMode === constants.DEGREES) {\n        angle = this.p5.random(360);\n      } else {\n        angle = this.p5.random(constants.TWO_PI);\n      }\n    } else {\n      angle = Math.random() * Math.PI * 2;\n    }\n    return this.fromAngle(angle);\n  };\n  p5.Vector.random3D = function () {\n    var angle, vz;\n    if (this.p5) {\n      angle = this.p5.random(0, constants.TWO_PI);\n      vz = this.p5.random(-1, 1);\n    } else {\n      angle = Math.random() * Math.PI * 2;\n      vz = Math.random() * 2 - 1;\n    }\n    var vx = Math.sqrt(1 - vz * vz) * Math.cos(angle);\n    var vy = Math.sqrt(1 - vz * vz) * Math.sin(angle);\n    if (this.p5) {\n      return new p5.Vector(this.p5, [\n        vx,\n        vy,\n        vz\n      ]);\n    } else {\n      return new p5.Vector(vx, vy, vz);\n    }\n  };\n  p5.Vector.add = function (v1, v2, target) {\n    if (!target) {\n      target = v1.copy();\n    } else {\n      target.set(v1);\n    }\n    target.add(v2);\n    return target;\n  };\n  p5.Vector.sub = function (v1, v2, target) {\n    if (!target) {\n      target = v1.copy();\n    } else {\n      target.set(v1);\n    }\n    target.sub(v2);\n    return target;\n  };\n  p5.Vector.mult = function (v, n, target) {\n    if (!target) {\n      target = v.copy();\n    } else {\n      target.set(v);\n    }\n    target.mult(n);\n    return target;\n  };\n  p5.Vector.div = function (v, n, target) {\n    if (!target) {\n      target = v.copy();\n    } else {\n      target.set(v);\n    }\n    target.div(n);\n    return target;\n  };\n  p5.Vector.dot = function (v1, v2) {\n    return v1.dot(v2);\n  };\n  p5.Vector.cross = function (v1, v2) {\n    return v1.cross(v2);\n  };\n  p5.Vector.dist = function (v1, v2) {\n    return v1.dist(v2);\n  };\n  p5.Vector.lerp = function (v1, v2, amt, target) {\n    if (!target) {\n      target = v1.copy();\n    } else {\n      target.set(v1);\n    }\n    target.lerp(v2, amt);\n    return target;\n  };\n  p5.Vector.angleBetween = function (v1, v2) {\n    var angle = Math.acos(v1.dot(v2) / (v1.mag() * v2.mag()));\n    if (this.p5) {\n      if (this.p5._angleMode === constants.DEGREES) {\n        angle = polarGeometry.radiansToDegrees(angle);\n      }\n    }\n    return angle;\n  };\n  return p5.Vector;\n}({}, amdclean['core'], amdclean['polargeometry'], amdclean['constants']);\namdclean['p5TableRow'] = function (require, core) {\n  'use strict';\n  var p5 = core;\n  p5.TableRow = function (str, separator) {\n    var arr = [];\n    var obj = {};\n    if (str) {\n      separator = separator || ',';\n      arr = str.split(separator);\n    }\n    for (var i = 0; i < arr.length; i++) {\n      var key = i;\n      var val = arr[i];\n      obj[key] = val;\n    }\n    this.arr = arr;\n    this.obj = obj;\n    this.table = null;\n  };\n  p5.TableRow.prototype.set = function (column, value) {\n    if (typeof column === 'string') {\n      var cPos = this.table.columns.indexOf(column);\n      if (cPos >= 0) {\n        this.obj[column] = value;\n        this.arr[cPos] = value;\n      } else {\n        throw 'This table has no column named \"' + column + '\"';\n      }\n    } else {\n      if (column < this.table.columns.length) {\n        this.arr[column] = value;\n        var cTitle = this.table.columns[column];\n        this.obj[cTitle] = value;\n      } else {\n        throw 'Column #' + column + ' is out of the range of this table';\n      }\n    }\n  };\n  p5.TableRow.prototype.setNum = function (column, value) {\n    var floatVal = parseFloat(value, 10);\n    this.set(column, floatVal);\n  };\n  p5.TableRow.prototype.setString = function (column, value) {\n    var stringVal = value.toString();\n    this.set(column, stringVal);\n  };\n  p5.TableRow.prototype.get = function (column) {\n    if (typeof column === 'string') {\n      return this.obj[column];\n    } else {\n      return this.arr[column];\n    }\n  };\n  p5.TableRow.prototype.getNum = function (column) {\n    var ret;\n    if (typeof column === 'string') {\n      ret = parseFloat(this.obj[column], 10);\n    } else {\n      ret = parseFloat(this.arr[column], 10);\n    }\n    if (ret.toString() === 'NaN') {\n      throw 'Error: ' + this.obj[column] + ' is NaN (Not a Number)';\n    }\n    return ret;\n  };\n  p5.TableRow.prototype.getString = function (column) {\n    if (typeof column === 'string') {\n      return this.obj[column].toString();\n    } else {\n      return this.arr[column].toString();\n    }\n  };\n  return p5.TableRow;\n}({}, amdclean['core']);\namdclean['p5Table'] = function (require, core) {\n  'use strict';\n  var p5 = core;\n  p5.Table = function (rows) {\n    this.columns = [];\n    this.rows = [];\n  };\n  p5.Table.prototype.addRow = function (row) {\n    var r = row || new p5.TableRow();\n    if (typeof r.arr === 'undefined' || typeof r.obj === 'undefined') {\n      throw 'invalid TableRow: ' + r;\n    }\n    r.table = this;\n    this.rows.push(r);\n    return r;\n  };\n  p5.Table.prototype.removeRow = function (id) {\n    this.rows[id].table = null;\n    var chunk = this.rows.splice(id + 1, this.rows.length);\n    this.rows.pop();\n    this.rows = this.rows.concat(chunk);\n  };\n  p5.Table.prototype.getRow = function (r) {\n    return this.rows[r];\n  };\n  p5.Table.prototype.getRows = function () {\n    return this.rows;\n  };\n  p5.Table.prototype.findRow = function (value, column) {\n    if (typeof column === 'string') {\n      for (var i = 0; i < this.rows.length; i++) {\n        if (this.rows[i].obj[column] === value) {\n          return this.rows[i];\n        }\n      }\n    } else {\n      for (var j = 0; j < this.rows.length; j++) {\n        if (this.rows[j].arr[column] === value) {\n          return this.rows[j];\n        }\n      }\n    }\n    return null;\n  };\n  p5.Table.prototype.findRows = function (value, column) {\n    var ret = [];\n    if (typeof column === 'string') {\n      for (var i = 0; i < this.rows.length; i++) {\n        if (this.rows[i].obj[column] === value) {\n          ret.push(this.rows[i]);\n        }\n      }\n    } else {\n      for (var j = 0; j < this.rows.length; j++) {\n        if (this.rows[j].arr[column] === value) {\n          ret.push(this.rows[j]);\n        }\n      }\n    }\n    return ret;\n  };\n  p5.Table.prototype.matchRow = function (regexp, column) {\n    if (typeof column === 'number') {\n      for (var j = 0; j < this.rows.length; j++) {\n        if (this.rows[j].arr[column].match(regexp)) {\n          return this.rows[j];\n        }\n      }\n    } else {\n      for (var i = 0; i < this.rows.length; i++) {\n        if (this.rows[i].obj[column].match(regexp)) {\n          return this.rows[i];\n        }\n      }\n    }\n    return null;\n  };\n  p5.Table.prototype.matchRows = function (regexp, column) {\n    var ret = [];\n    if (typeof column === 'number') {\n      for (var j = 0; j < this.rows.length; j++) {\n        if (this.rows[j].arr[column].match(regexp)) {\n          ret.push(this.rows[j]);\n        }\n      }\n    } else {\n      for (var i = 0; i < this.rows.length; i++) {\n        if (this.rows[i].obj[column].match(regexp)) {\n          ret.push(this.rows[i]);\n        }\n      }\n    }\n    return ret;\n  };\n  p5.Table.prototype.getColumn = function (value) {\n    var ret = [];\n    if (typeof value === 'string') {\n      for (var i = 0; i < this.rows.length; i++) {\n        ret.push(this.rows[i].obj[value]);\n      }\n    } else {\n      for (var j = 0; j < this.rows.length; j++) {\n        ret.push(this.rows[j].arr[value]);\n      }\n    }\n    return ret;\n  };\n  p5.Table.prototype.clearRows = function () {\n    delete this.rows;\n    this.rows = [];\n  };\n  p5.Table.prototype.addColumn = function (title) {\n    var t = title || null;\n    this.columns.push(t);\n  };\n  p5.Table.prototype.getColumnCount = function () {\n    return this.columns.length;\n  };\n  p5.Table.prototype.getRowCount = function () {\n    return this.rows.length;\n  };\n  p5.Table.prototype.removeTokens = function (chars, column) {\n    var escape = function (s) {\n      return s.replace(/[-\\/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n    };\n    var charArray = [];\n    for (var i = 0; i < chars.length; i++) {\n      charArray.push(escape(chars.charAt(i)));\n    }\n    var regex = new RegExp(charArray.join('|'), 'g');\n    if (typeof column === 'undefined') {\n      for (var c = 0; c < this.columns.length; c++) {\n        for (var d = 0; d < this.rows.length; d++) {\n          var s = this.rows[d].arr[c];\n          s = s.replace(regex, '');\n          this.rows[d].arr[c] = s;\n          this.rows[d].obj[this.columns[c]] = s;\n        }\n      }\n    } else if (typeof column === 'string') {\n      for (var j = 0; j < this.rows.length; j++) {\n        var val = this.rows[j].obj[column];\n        val = val.replace(regex, '');\n        this.rows[j].obj[column] = val;\n        var pos = this.columns.indexOf(column);\n        this.rows[j].arr[pos] = val;\n      }\n    } else {\n      for (var k = 0; k < this.rows.length; k++) {\n        var str = this.rows[k].arr[column];\n        str = str.replace(regex, '');\n        this.rows[k].arr[column] = str;\n        this.rows[k].obj[this.columns[column]] = str;\n      }\n    }\n  };\n  p5.Table.prototype.trim = function (column) {\n    var regex = new RegExp(' ', 'g');\n    if (typeof column === 'undefined') {\n      for (var c = 0; c < this.columns.length; c++) {\n        for (var d = 0; d < this.rows.length; d++) {\n          var s = this.rows[d].arr[c];\n          s = s.replace(regex, '');\n          this.rows[d].arr[c] = s;\n          this.rows[d].obj[this.columns[c]] = s;\n        }\n      }\n    } else if (typeof column === 'string') {\n      for (var j = 0; j < this.rows.length; j++) {\n        var val = this.rows[j].obj[column];\n        val = val.replace(regex, '');\n        this.rows[j].obj[column] = val;\n        var pos = this.columns.indexOf(column);\n        this.rows[j].arr[pos] = val;\n      }\n    } else {\n      for (var k = 0; k < this.rows.length; k++) {\n        var str = this.rows[k].arr[column];\n        str = str.replace(regex, '');\n        this.rows[k].arr[column] = str;\n        this.rows[k].obj[this.columns[column]] = str;\n      }\n    }\n  };\n  p5.Table.prototype.removeColumn = function (c) {\n    var cString;\n    var cNumber;\n    if (typeof c === 'string') {\n      cString = c;\n      cNumber = this.columns.indexOf(c);\n      console.log('string');\n    } else {\n      cNumber = c;\n      cString = this.columns[c];\n    }\n    var chunk = this.columns.splice(cNumber + 1, this.columns.length);\n    this.columns.pop();\n    this.columns = this.columns.concat(chunk);\n    for (var i = 0; i < this.rows.length; i++) {\n      var tempR = this.rows[i].arr;\n      var chip = tempR.splice(cNumber + 1, tempR.length);\n      tempR.pop();\n      this.rows[i].arr = tempR.concat(chip);\n      delete this.rows[i].obj[cString];\n    }\n  };\n  return p5.Table;\n}({}, amdclean['core']);\namdclean['colorcreating_reading'] = function (require, core, p5Color) {\n  'use strict';\n  var p5 = core;\n  p5.prototype.alpha = function (c) {\n    if (c instanceof p5.Color || c instanceof Array) {\n      return this.color(c).getAlpha();\n    } else {\n      throw new Error('Needs p5.Color or pixel array as argument.');\n    }\n  };\n  p5.prototype.blue = function (c) {\n    if (c instanceof p5.Color || c instanceof Array) {\n      return this.color(c).getBlue();\n    } else {\n      throw new Error('Needs p5.Color or pixel array as argument.');\n    }\n  };\n  p5.prototype.brightness = function (c) {\n    if (!c instanceof p5.Color) {\n      throw new Error('Needs p5.Color as argument.');\n    }\n    return c.getBrightness();\n  };\n  p5.prototype.color = function () {\n    if (arguments[0] instanceof p5.Color) {\n      return arguments[0];\n    } else if (arguments[0] instanceof Array) {\n      return new p5.Color(this, arguments[0]);\n    } else {\n      var args = Array.prototype.slice.call(arguments);\n      return new p5.Color(this, args);\n    }\n  };\n  p5.prototype.green = function (c) {\n    if (c instanceof p5.Color || c instanceof Array) {\n      return this.color(c).getGreen();\n    } else {\n      throw new Error('Needs p5.Color or pixel array as argument.');\n    }\n  };\n  p5.prototype.hue = function (c) {\n    if (!c instanceof p5.Color) {\n      throw new Error('Needs p5.Color as argument.');\n    }\n    return c.getHue();\n  };\n  p5.prototype.lerpColor = function (c1, c2, amt) {\n    if (c1 instanceof Array) {\n      var c = [];\n      for (var i = 0; i < c1.length; i++) {\n        c.push(p5.prototype.lerp(c1[i], c2[i], amt));\n      }\n      return c;\n    } else if (c1 instanceof p5.Color) {\n      var pc = [];\n      for (var j = 0; j < 4; j++) {\n        pc.push(p5.prototype.lerp(c1.rgba[j], c2.rgba[j], amt));\n      }\n      return new p5.Color(this, pc);\n    } else {\n      return p5.prototype.lerp(c1, c2, amt);\n    }\n  };\n  p5.prototype.red = function (c) {\n    if (c instanceof p5.Color || c instanceof Array) {\n      return this.color(c).getRed();\n    } else {\n      throw new Error('Needs p5.Color or pixel array as argument.');\n    }\n  };\n  p5.prototype.saturation = function (c) {\n    if (!c instanceof p5.Color) {\n      throw new Error('Needs p5.Color as argument.');\n    }\n    return c.getSaturation();\n  };\n  return p5;\n}({}, amdclean['core'], amdclean['p5Color']);\namdclean['colorsetting'] = function (require, core, constants, p5Color) {\n  'use strict';\n  var p5 = core;\n  var constants = constants;\n  p5.prototype._doStroke = true;\n  p5.prototype._doFill = true;\n  p5.prototype._colorMode = constants.RGB;\n  p5.prototype._maxRGB = [\n    255,\n    255,\n    255,\n    255\n  ];\n  p5.prototype._maxHSB = [\n    255,\n    255,\n    255,\n    255\n  ];\n  p5.prototype.background = function () {\n    this.drawingContext.save();\n    this.drawingContext.setTransform(1, 0, 0, 1, 0, 0);\n    this.drawingContext.scale(this._pixelDensity, this._pixelDensity);\n    if (arguments[0] instanceof p5.Image) {\n      this.image(arguments[0], 0, 0, this.width, this.height);\n    } else {\n      var curFill = this.drawingContext.fillStyle;\n      var color = this.color.apply(this, arguments);\n      var newFill = color.toString();\n      this.drawingContext.fillStyle = newFill;\n      this.drawingContext.fillRect(0, 0, this.width, this.height);\n      this.drawingContext.fillStyle = curFill;\n    }\n    this.drawingContext.restore();\n  };\n  p5.prototype.clear = function () {\n    this.drawingContext.clearRect(0, 0, this.width, this.height);\n  };\n  p5.prototype.colorMode = function () {\n    if (arguments[0] === constants.RGB || arguments[0] === constants.HSB) {\n      this._colorMode = arguments[0];\n      var isRGB = this._colorMode === constants.RGB;\n      var maxArr = isRGB ? this._maxRGB : this._maxHSB;\n      if (arguments.length === 2) {\n        maxArr[0] = arguments[1];\n        maxArr[1] = arguments[1];\n        maxArr[2] = arguments[1];\n        maxArr[3] = arguments[1];\n      } else if (arguments.length > 2) {\n        maxArr[0] = arguments[1];\n        maxArr[1] = arguments[2];\n        maxArr[2] = arguments[3];\n      }\n      if (arguments.length === 5) {\n        maxArr[3] = arguments[4];\n      }\n    }\n  };\n  p5.prototype.fill = function () {\n    this._setProperty('_doFill', true);\n    var ctx = this.drawingContext;\n    var color = this.color.apply(this, arguments);\n    ctx.fillStyle = color.toString();\n  };\n  p5.prototype.noFill = function () {\n    this._setProperty('_doFill', false);\n  };\n  p5.prototype.noStroke = function () {\n    this._setProperty('_doStroke', false);\n  };\n  p5.prototype.stroke = function () {\n    this._setProperty('_doStroke', true);\n    var ctx = this.drawingContext;\n    var color = this.color.apply(this, arguments);\n    ctx.strokeStyle = color.toString();\n  };\n  return p5;\n}({}, amdclean['core'], amdclean['constants'], amdclean['p5Color']);\namdclean['dataconversion'] = function (require, core) {\n  'use strict';\n  var p5 = core;\n  p5.prototype.float = function (str) {\n    return parseFloat(str);\n  };\n  p5.prototype.int = function (n, radix) {\n    if (typeof n === 'string') {\n      radix = radix || 10;\n      return parseInt(n, radix);\n    } else if (typeof n === 'number') {\n      return n | 0;\n    } else if (typeof n === 'boolean') {\n      return n ? 1 : 0;\n    } else if (n instanceof Array) {\n      return n.map(p5.prototype.int);\n    }\n  };\n  return p5;\n}({}, amdclean['core']);\namdclean['dataarray_functions'] = function (require, core) {\n  'use strict';\n  var p5 = core;\n  p5.prototype.append = function (array, value) {\n    array.push(value);\n    return array;\n  };\n  p5.prototype.arrayCopy = function (src, srcPosition, dst, dstPosition, length) {\n    var start, end;\n    if (typeof length !== 'undefined') {\n      end = Math.min(length, src.length);\n      start = dstPosition;\n      src = src.slice(srcPosition, end + srcPosition);\n    } else {\n      if (typeof dst !== 'undefined') {\n        end = dst;\n        end = Math.min(end, src.length);\n      } else {\n        end = src.length;\n      }\n      start = 0;\n      dst = srcPosition;\n      src = src.slice(0, end);\n    }\n    Array.prototype.splice.apply(dst, [\n      start,\n      end\n    ].concat(src));\n  };\n  p5.prototype.concat = function (list0, list1) {\n    return list0.concat(list1);\n  };\n  p5.prototype.reverse = function (list) {\n    return list.reverse();\n  };\n  p5.prototype.shorten = function (list) {\n    list.pop();\n    return list;\n  };\n  p5.prototype.sort = function (list, count) {\n    var arr = count ? list.slice(0, Math.min(count, list.length)) : list;\n    var rest = count ? list.slice(Math.min(count, list.length)) : [];\n    if (typeof arr[0] === 'string') {\n      arr = arr.sort();\n    } else {\n      arr = arr.sort(function (a, b) {\n        return a - b;\n      });\n    }\n    return arr.concat(rest);\n  };\n  p5.prototype.splice = function (list, value, index) {\n    Array.prototype.splice.apply(list, [\n      index,\n      0\n    ].concat(value));\n    return list;\n  };\n  p5.prototype.subset = function (list, start, count) {\n    if (typeof count !== 'undefined') {\n      return list.slice(start, start + count);\n    } else {\n      return list.slice(start, list.length);\n    }\n  };\n  return p5;\n}({}, amdclean['core']);\namdclean['datastring_functions'] = function (require, core) {\n  'use strict';\n  var p5 = core;\n  p5.prototype.join = function (list, separator) {\n    return list.join(separator);\n  };\n  p5.prototype.match = function (str, reg) {\n    return str.match(reg);\n  };\n  p5.prototype.matchAll = function (str, reg) {\n    var re = new RegExp(reg, 'g');\n    var match = re.exec(str);\n    var matches = [];\n    while (match !== null) {\n      matches.push(match);\n      match = re.exec(str);\n    }\n    return matches;\n  };\n  p5.prototype.nf = function () {\n    if (arguments[0] instanceof Array) {\n      var a = arguments[1];\n      var b = arguments[2];\n      return arguments[0].map(function (x) {\n        return doNf(x, a, b);\n      });\n    } else {\n      return doNf.apply(this, arguments);\n    }\n  };\n  function doNf() {\n    var num = arguments[0];\n    var neg = num < 0;\n    var n = neg ? num.toString().substring(1) : num.toString();\n    var decimalInd = n.indexOf('.');\n    var intPart = decimalInd !== -1 ? n.substring(0, decimalInd) : n;\n    var decPart = decimalInd !== -1 ? n.substring(decimalInd + 1) : '';\n    var str = neg ? '-' : '';\n    if (arguments.length === 3) {\n      for (var i = 0; i < arguments[1] - intPart.length; i++) {\n        str += '0';\n      }\n      str += intPart;\n      str += '.';\n      str += decPart;\n      for (var j = 0; j < arguments[2] - decPart.length; j++) {\n        str += '0';\n      }\n      return str;\n    } else {\n      for (var k = 0; k < Math.max(arguments[1] - intPart.length, 0); k++) {\n        str += '0';\n      }\n      str += n;\n      return str;\n    }\n  }\n  p5.prototype.nfc = function () {\n    if (arguments[0] instanceof Array) {\n      var a = arguments[1];\n      return arguments[0].map(function (x) {\n        return doNfc(x, a);\n      });\n    } else {\n      return doNfc.apply(this, arguments);\n    }\n  };\n  function doNfc() {\n    var num = arguments[0].toString();\n    var dec = num.indexOf('.');\n    var rem = dec !== -1 ? num.substring(dec) : '';\n    var n = dec !== -1 ? num.substring(0, dec) : num;\n    n = n.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n    if (arguments[1] === 0) {\n      rem = '';\n    }\n    if (arguments.length > 1) {\n      rem = rem.substring(0, arguments[1] + 1);\n    }\n    return n + rem;\n  }\n  p5.prototype.nfp = function () {\n    var nfRes = this.nf(arguments);\n    if (nfRes instanceof Array) {\n      return nfRes.map(addNfp);\n    } else {\n      return addNfp(nfRes);\n    }\n  };\n  function addNfp() {\n    return parseFloat(arguments[0]) > 0 ? '+' + arguments[0].toString() : arguments[0].toString();\n  }\n  p5.prototype.nfs = function () {\n    var nfRes = this.nf(arguments);\n    if (nfRes instanceof Array) {\n      return nfRes.map(addNfs);\n    } else {\n      return addNfs(nfRes);\n    }\n  };\n  function addNfs() {\n    return parseFloat(arguments[0]) > 0 ? ' ' + arguments[0].toString() : arguments[0].toString();\n  }\n  p5.prototype.split = function (str, delim) {\n    return str.split(delim);\n  };\n  p5.prototype.splitTokens = function () {\n    var d = arguments.length > 0 ? arguments[1] : /\\s/g;\n    return arguments[0].split(d).filter(function (n) {\n      return n;\n    });\n  };\n  p5.prototype.trim = function (str) {\n    if (str instanceof Array) {\n      return str.map(this.trim);\n    } else {\n      return str.trim();\n    }\n  };\n  return p5;\n}({}, amdclean['core']);\namdclean['environment'] = function (require, core, constants) {\n  'use strict';\n  var p5 = core;\n  var C = constants;\n  var standardCursors = [\n      C.ARROW,\n      C.CROSS,\n      C.HAND,\n      C.MOVE,\n      C.TEXT,\n      C.WAIT\n    ];\n  p5.prototype._frameRate = 0;\n  p5.prototype._lastFrameTime = new Date().getTime();\n  p5.prototype._targetFrameRate = 60;\n  p5.prototype.frameCount = 0;\n  p5.prototype.focused = true;\n  p5.prototype.cursor = function (type, x, y) {\n    var cursor = 'auto';\n    var canvas = this._curElement.elt;\n    if (standardCursors.indexOf(type) > -1) {\n      cursor = type;\n    } else if (typeof type === 'string') {\n      var coords = '';\n      if (x && y && (typeof x === 'number' && typeof y === 'number')) {\n        coords = x + ' ' + y;\n      }\n      if (type.substring(0, 6) !== 'http://') {\n        cursor = 'url(' + type + ') ' + coords + ', auto';\n      } else if (/\\.(cur|jpg|jpeg|gif|png|CUR|JPG|JPEG|GIF|PNG)$/.test(type)) {\n        cursor = 'url(' + type + ') ' + coords + ', auto';\n      } else {\n        cursor = type;\n      }\n    }\n    canvas.style.cursor = cursor;\n  };\n  p5.prototype.frameRate = function (fps) {\n    if (typeof fps === 'undefined') {\n      return this._frameRate;\n    } else {\n      this._setProperty('_targetFrameRate', fps);\n      this._runFrames();\n      return this;\n    }\n  };\n  p5.prototype.getFrameRate = function () {\n    return this.frameRate();\n  };\n  p5.prototype.setFrameRate = function (fps) {\n    return this.frameRate(fps);\n  };\n  p5.prototype.noCursor = function () {\n    this._curElement.elt.style.cursor = 'none';\n  };\n  p5.prototype.displayWidth = screen.width;\n  p5.prototype.displayHeight = screen.height;\n  p5.prototype.windowWidth = window.innerWidth;\n  p5.prototype.windowHeight = window.innerHeight;\n  p5.prototype.onresize = function (e) {\n    this._setProperty('windowWidth', window.innerWidth);\n    this._setProperty('windowHeight', window.innerHeight);\n    var context = this._isGlobal ? window : this;\n    var executeDefault;\n    if (typeof context.windowResized === 'function') {\n      executeDefault = context.windowResized(e);\n      if (executeDefault !== undefined && !executeDefault) {\n        e.preventDefault();\n      }\n    }\n  };\n  p5.prototype.width = 0;\n  p5.prototype.height = 0;\n  p5.prototype.fullscreen = function (val) {\n    if (typeof val === 'undefined') {\n      return document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement;\n    } else {\n      if (val) {\n        launchFullscreen(document.documentElement);\n      } else {\n        exitFullscreen();\n      }\n    }\n  };\n  p5.prototype.devicePixelScaling = function (val) {\n    if (val) {\n      this._pixelDensity = window.devicePixelRatio || 1;\n    } else {\n      this._pixelDensity = 1;\n    }\n    this.resizeCanvas(this.width, this.height, true);\n  };\n  function launchFullscreen(element) {\n    var enabled = document.fullscreenEnabled || document.webkitFullscreenEnabled || document.mozFullScreenEnabled || document.msFullscreenEnabled;\n    if (!enabled) {\n      throw new Error('Fullscreen not enabled in this browser.');\n    }\n    if (element.requestFullscreen) {\n      element.requestFullscreen();\n    } else if (element.mozRequestFullScreen) {\n      element.mozRequestFullScreen();\n    } else if (element.webkitRequestFullscreen) {\n      element.webkitRequestFullscreen();\n    } else if (element.msRequestFullscreen) {\n      element.msRequestFullscreen();\n    }\n  }\n  function exitFullscreen() {\n    if (document.exitFullscreen) {\n      document.exitFullscreen();\n    } else if (document.mozCancelFullScreen) {\n      document.mozCancelFullScreen();\n    } else if (document.webkitExitFullscreen) {\n      document.webkitExitFullscreen();\n    }\n  }\n  p5.prototype.getURL = function () {\n    return location.href;\n  };\n  p5.prototype.getURLPath = function () {\n    return location.pathname.split('/').filter(function (v) {\n      return v !== '';\n    });\n  };\n  p5.prototype.getURLParams = function () {\n    var re = /[?&]([^&=]+)(?:[&=])([^&=]+)/gim;\n    var m;\n    var v = {};\n    while ((m = re.exec(location.search)) != null) {\n      if (m.index === re.lastIndex) {\n        re.lastIndex++;\n      }\n      v[m[1]] = m[2];\n    }\n    return v;\n  };\n  return p5;\n}({}, amdclean['core'], amdclean['constants']);\namdclean['imageimage'] = function (require, core, constants) {\n  'use strict';\n  var p5 = core;\n  var constants = constants;\n  p5.prototype._imageMode = constants.CORNER;\n  p5.prototype._tint = null;\n  p5.prototype.createImage = function (width, height) {\n    return new p5.Image(width, height);\n  };\n  return p5;\n}({}, amdclean['core'], amdclean['constants']);\namdclean['canvas'] = function (require, constants) {\n  var constants = constants;\n  return {\n    modeAdjust: function (a, b, c, d, mode) {\n      if (mode === constants.CORNER) {\n        return {\n          x: a,\n          y: b,\n          w: c,\n          h: d\n        };\n      } else if (mode === constants.CORNERS) {\n        return {\n          x: a,\n          y: b,\n          w: c - a,\n          h: d - b\n        };\n      } else if (mode === constants.RADIUS) {\n        return {\n          x: a - c,\n          y: b - d,\n          w: 2 * c,\n          h: 2 * d\n        };\n      } else if (mode === constants.CENTER) {\n        return {\n          x: a - c * 0.5,\n          y: b - d * 0.5,\n          w: c,\n          h: d\n        };\n      }\n    },\n    arcModeAdjust: function (a, b, c, d, mode) {\n      if (mode === constants.CORNER) {\n        return {\n          x: a + c * 0.5,\n          y: b + d * 0.5,\n          w: c,\n          h: d\n        };\n      } else if (mode === constants.CORNERS) {\n        return {\n          x: a,\n          y: b,\n          w: c + a,\n          h: d + b\n        };\n      } else if (mode === constants.RADIUS) {\n        return {\n          x: a,\n          y: b,\n          w: 2 * c,\n          h: 2 * d\n        };\n      } else if (mode === constants.CENTER) {\n        return {\n          x: a,\n          y: b,\n          w: c,\n          h: d\n        };\n      }\n    }\n  };\n}({}, amdclean['constants']);\namdclean['imageloading_displaying'] = function (require, core, filters, canvas, constants) {\n  'use strict';\n  var p5 = core;\n  var Filters = filters;\n  var canvas = canvas;\n  var constants = constants;\n  p5.prototype.loadImage = function (path, successCallback, failureCallback) {\n    var img = new Image();\n    var pImg = new p5.Image(1, 1, this);\n    img.onload = function () {\n      pImg.width = pImg.canvas.width = img.width;\n      pImg.height = pImg.canvas.height = img.height;\n      pImg.canvas.getContext('2d').drawImage(img, 0, 0);\n      if (typeof successCallback === 'function') {\n        successCallback(pImg);\n      }\n    };\n    img.onerror = function (e) {\n      if (typeof failureCallback === 'function') {\n        failureCallback(e);\n      }\n    };\n    if (path.indexOf('data:image/') !== 0) {\n      img.crossOrigin = 'Anonymous';\n    }\n    img.src = path;\n    return pImg;\n  };\n  p5.prototype.image = function (img, x, y, width, height) {\n    var frame = img.canvas || img.elt;\n    x = x || 0;\n    y = y || 0;\n    width = width || img.width;\n    height = height || img.height;\n    var vals = canvas.modeAdjust(x, y, width, height, this._imageMode);\n    try {\n      if (this._tint && img.canvas) {\n        this.drawingContext.drawImage(this._getTintedImageCanvas(img), vals.x, vals.y, vals.w, vals.h);\n      } else {\n        this.drawingContext.drawImage(frame, vals.x, vals.y, vals.w, vals.h);\n      }\n    } catch (e) {\n      if (e.name !== 'NS_ERROR_NOT_AVAILABLE') {\n        throw e;\n      }\n    }\n  };\n  p5.prototype.tint = function () {\n    var c = this.color.apply(this, arguments);\n    this._tint = c.rgba;\n  };\n  p5.prototype.noTint = function () {\n    this._tint = null;\n  };\n  p5.prototype._getTintedImageCanvas = function (img) {\n    if (!img.canvas) {\n      return img;\n    }\n    var pixels = Filters._toPixels(img.canvas);\n    var tmpCanvas = document.createElement('canvas');\n    tmpCanvas.width = img.canvas.width;\n    tmpCanvas.height = img.canvas.height;\n    var tmpCtx = tmpCanvas.getContext('2d');\n    var id = tmpCtx.createImageData(img.canvas.width, img.canvas.height);\n    var newPixels = id.data;\n    for (var i = 0; i < pixels.length; i += 4) {\n      var r = pixels[i];\n      var g = pixels[i + 1];\n      var b = pixels[i + 2];\n      var a = pixels[i + 3];\n      newPixels[i] = r * this._tint[0] / 255;\n      newPixels[i + 1] = g * this._tint[1] / 255;\n      newPixels[i + 2] = b * this._tint[2] / 255;\n      newPixels[i + 3] = a * this._tint[3] / 255;\n    }\n    tmpCtx.putImageData(id, 0, 0);\n    return tmpCanvas;\n  };\n  p5.prototype.imageMode = function (m) {\n    if (m === constants.CORNER || m === constants.CORNERS || m === constants.CENTER) {\n      this._imageMode = m;\n    }\n  };\n  return p5;\n}({}, amdclean['core'], amdclean['filters'], amdclean['canvas'], amdclean['constants']);\namdclean['imagepixels'] = function (require, core, filters, p5Color) {\n  'use strict';\n  var p5 = core;\n  var Filters = filters;\n  p5.prototype.pixels = [];\n  p5.prototype.blend = function () {\n    var currBlend = this.drawingContext.globalCompositeOperation;\n    var blendMode = arguments[arguments.length - 1];\n    var copyArgs = Array.prototype.slice.call(arguments, 0, arguments.length - 1);\n    this.drawingContext.globalCompositeOperation = blendMode;\n    this.copy.apply(this, copyArgs);\n    this.drawingContext.globalCompositeOperation = currBlend;\n  };\n  p5.prototype.copy = function () {\n    var srcImage, sx, sy, sw, sh, dx, dy, dw, dh;\n    if (arguments.length === 9) {\n      srcImage = arguments[0];\n      sx = arguments[1];\n      sy = arguments[2];\n      sw = arguments[3];\n      sh = arguments[4];\n      dx = arguments[5];\n      dy = arguments[6];\n      dw = arguments[7];\n      dh = arguments[8];\n    } else if (arguments.length === 8) {\n      sx = arguments[0];\n      sy = arguments[1];\n      sw = arguments[2];\n      sh = arguments[3];\n      dx = arguments[4];\n      dy = arguments[5];\n      dw = arguments[6];\n      dh = arguments[7];\n      srcImage = this;\n    } else {\n      throw new Error('Signature not supported');\n    }\n    var s = srcImage.canvas.width / srcImage.width;\n    this.drawingContext.drawImage(srcImage.canvas, s * sx, s * sy, s * sw, s * sh, dx, dy, dw, dh);\n  };\n  p5.prototype.filter = function (operation, value) {\n    Filters.apply(this.canvas, Filters[operation.toLowerCase()], value);\n  };\n  p5.prototype.get = function (x, y, w, h) {\n    if (x === undefined && y === undefined && w === undefined && h === undefined) {\n      x = 0;\n      y = 0;\n      w = this.width;\n      h = this.height;\n    } else if (w === undefined && h === undefined) {\n      w = 1;\n      h = 1;\n    }\n    if (x > this.width || y > this.height || x < 0 || y < 0) {\n      return [\n        0,\n        0,\n        0,\n        255\n      ];\n    }\n    var imageData = this.drawingContext.getImageData(x, y, w, h);\n    var data = imageData.data;\n    if (w === 1 && h === 1) {\n      var pixels = [];\n      for (var i = 0; i < data.length; i += 4) {\n        pixels.push(data[i], data[i + 1], data[i + 2], data[i + 3]);\n      }\n      return pixels;\n    } else {\n      w = Math.min(w, this.width);\n      h = Math.min(h, this.height);\n      var region = new p5.Image(w, h);\n      region.canvas.getContext('2d').putImageData(imageData, 0, 0, 0, 0, w, h);\n      return region;\n    }\n  };\n  p5.prototype.loadPixels = function () {\n    var width = this.width;\n    var height = this.height;\n    var imageData = this.drawingContext.getImageData(0, 0, width, height);\n    this._setProperty('imageData', imageData);\n    this._setProperty('pixels', imageData.data);\n  };\n  p5.prototype.set = function (x, y, imgOrCol) {\n    if (imgOrCol instanceof p5.Image) {\n      this.drawingContext.save();\n      this.drawingContext.setTransform(1, 0, 0, 1, 0, 0);\n      this.drawingContext.scale(this._pixelDensity, this._pixelDensity);\n      this.drawingContext.drawImage(imgOrCol.canvas, x, y);\n      this.loadPixels.call(this);\n      this.drawingContext.restore();\n    } else {\n      var idx = 4 * (y * this.width + x);\n      if (!this.imageData) {\n        this.loadPixels.call(this);\n      }\n      if (typeof imgOrCol === 'number') {\n        if (idx < this.pixels.length) {\n          this.pixels[idx] = imgOrCol;\n          this.pixels[idx + 1] = imgOrCol;\n          this.pixels[idx + 2] = imgOrCol;\n          this.pixels[idx + 3] = 255;\n        }\n      } else if (imgOrCol instanceof Array) {\n        if (imgOrCol.length < 4) {\n          throw new Error('pixel array must be of the form [R, G, B, A]');\n        }\n        if (idx < this.pixels.length) {\n          this.pixels[idx] = imgOrCol[0];\n          this.pixels[idx + 1] = imgOrCol[1];\n          this.pixels[idx + 2] = imgOrCol[2];\n          this.pixels[idx + 3] = imgOrCol[3];\n        }\n      } else if (imgOrCol instanceof p5.Color) {\n        if (idx < this.pixels.length) {\n          this.pixels[idx] = imgOrCol.rgba[0];\n          this.pixels[idx + 1] = imgOrCol.rgba[1];\n          this.pixels[idx + 2] = imgOrCol.rgba[2];\n          this.pixels[idx + 3] = imgOrCol.rgba[3];\n        }\n      }\n    }\n  };\n  p5.prototype.updatePixels = function (x, y, w, h) {\n    if (x === undefined && y === undefined && w === undefined && h === undefined) {\n      x = 0;\n      y = 0;\n      w = this.width;\n      h = this.height;\n    }\n    this.drawingContext.putImageData(this.imageData, x, y, 0, 0, w, h);\n  };\n  return p5;\n}({}, amdclean['core'], amdclean['filters'], amdclean['p5Color']);\n!function (name, context, definition) {\n  if (typeof module != 'undefined' && module.exports)\n    module.exports = definition();\n  else if (typeof define == 'function' && define.amd)\n    define('reqwest', definition);\n  else\n    context[name] = definition();\n}('reqwest', amdclean, function () {\n  var win = window, doc = document, twoHundo = /^(20\\d|1223)$/, byTag = 'getElementsByTagName', readyState = 'readyState', contentType = 'Content-Type', requestedWith = 'X-Requested-With', head = doc[byTag]('head')[0], uniqid = 0, callbackPrefix = 'reqwest_' + +new Date(), lastValue, xmlHttpRequest = 'XMLHttpRequest', xDomainRequest = 'XDomainRequest', noop = function () {\n    }, isArray = typeof Array.isArray == 'function' ? Array.isArray : function (a) {\n      return a instanceof Array;\n    }, defaultHeaders = {\n      'contentType': 'application/x-www-form-urlencoded',\n      'requestedWith': xmlHttpRequest,\n      'accept': {\n        '*': 'text/javascript, text/html, application/xml, text/xml, */*',\n        'xml': 'application/xml, text/xml',\n        'html': 'text/html',\n        'text': 'text/plain',\n        'json': 'application/json, text/javascript',\n        'js': 'application/javascript, text/javascript'\n      }\n    }, xhr = function (o) {\n      if (o['crossOrigin'] === true) {\n        var xhr = win[xmlHttpRequest] ? new XMLHttpRequest() : null;\n        if (xhr && 'withCredentials' in xhr) {\n          return xhr;\n        } else if (win[xDomainRequest]) {\n          return new XDomainRequest();\n        } else {\n          throw new Error('Browser does not support cross-origin requests');\n        }\n      } else if (win[xmlHttpRequest]) {\n        return new XMLHttpRequest();\n      } else {\n        return new ActiveXObject('Microsoft.XMLHTTP');\n      }\n    }, globalSetupOptions = {\n      dataFilter: function (data) {\n        return data;\n      }\n    };\n  function handleReadyState(r, success, error) {\n    return function () {\n      if (r._aborted)\n        return error(r.request);\n      if (r.request && r.request[readyState] == 4) {\n        r.request.onreadystatechange = noop;\n        if (twoHundo.test(r.request.status))\n          success(r.request);\n        else\n          error(r.request);\n      }\n    };\n  }\n  function setHeaders(http, o) {\n    var headers = o['headers'] || {}, h;\n    headers['Accept'] = headers['Accept'] || defaultHeaders['accept'][o['type']] || defaultHeaders['accept']['*'];\n    if (!o['crossOrigin'] && !headers[requestedWith])\n      headers[requestedWith] = defaultHeaders['requestedWith'];\n    if (!headers[contentType])\n      headers[contentType] = o['contentType'] || defaultHeaders['contentType'];\n    for (h in headers)\n      headers.hasOwnProperty(h) && 'setRequestHeader' in http && http.setRequestHeader(h, headers[h]);\n  }\n  function setCredentials(http, o) {\n    if (typeof o['withCredentials'] !== 'undefined' && typeof http.withCredentials !== 'undefined') {\n      http.withCredentials = !!o['withCredentials'];\n    }\n  }\n  function generalCallback(data) {\n    lastValue = data;\n  }\n  function urlappend(url, s) {\n    return url + (/\\?/.test(url) ? '&' : '?') + s;\n  }\n  function handleJsonp(o, fn, err, url) {\n    var reqId = uniqid++, cbkey = o['jsonpCallback'] || 'callback', cbval = o['jsonpCallbackName'] || reqwest.getcallbackPrefix(reqId), cbreg = new RegExp('((^|\\\\?|&)' + cbkey + ')=([^&]+)'), match = url.match(cbreg), script = doc.createElement('script'), loaded = 0, isIE10 = navigator.userAgent.indexOf('MSIE 10.0') !== -1;\n    if (match) {\n      if (match[3] === '?') {\n        url = url.replace(cbreg, '$1=' + cbval);\n      } else {\n        cbval = match[3];\n      }\n    } else {\n      url = urlappend(url, cbkey + '=' + cbval);\n    }\n    win[cbval] = generalCallback;\n    script.type = 'text/javascript';\n    script.src = url;\n    script.async = true;\n    if (typeof script.onreadystatechange !== 'undefined' && !isIE10) {\n      script.event = 'onclick';\n      script.htmlFor = script.id = '_reqwest_' + reqId;\n    }\n    script.onload = script.onreadystatechange = function () {\n      if (script[readyState] && script[readyState] !== 'complete' && script[readyState] !== 'loaded' || loaded) {\n        return false;\n      }\n      script.onload = script.onreadystatechange = null;\n      script.onclick && script.onclick();\n      fn(lastValue);\n      lastValue = undefined;\n      head.removeChild(script);\n      loaded = 1;\n    };\n    head.appendChild(script);\n    return {\n      abort: function () {\n        script.onload = script.onreadystatechange = null;\n        err({}, 'Request is aborted: timeout', {});\n        lastValue = undefined;\n        head.removeChild(script);\n        loaded = 1;\n      }\n    };\n  }\n  function getRequest(fn, err) {\n    var o = this.o, method = (o['method'] || 'GET').toUpperCase(), url = typeof o === 'string' ? o : o['url'], data = o['processData'] !== false && o['data'] && typeof o['data'] !== 'string' ? reqwest.toQueryString(o['data']) : o['data'] || null, http, sendWait = false;\n    if ((o['type'] == 'jsonp' || method == 'GET') && data) {\n      url = urlappend(url, data);\n      data = null;\n    }\n    if (o['type'] == 'jsonp')\n      return handleJsonp(o, fn, err, url);\n    http = o.xhr && o.xhr(o) || xhr(o);\n    http.open(method, url, o['async'] === false ? false : true);\n    setHeaders(http, o);\n    setCredentials(http, o);\n    if (win[xDomainRequest] && http instanceof win[xDomainRequest]) {\n      http.onload = fn;\n      http.onerror = err;\n      http.onprogress = function () {\n      };\n      sendWait = true;\n    } else {\n      http.onreadystatechange = handleReadyState(this, fn, err);\n    }\n    o['before'] && o['before'](http);\n    if (sendWait) {\n      setTimeout(function () {\n        http.send(data);\n      }, 200);\n    } else {\n      http.send(data);\n    }\n    return http;\n  }\n  function Reqwest(o, fn) {\n    this.o = o;\n    this.fn = fn;\n    init.apply(this, arguments);\n  }\n  function setType(url) {\n    var m = url.match(/\\.(json|jsonp|html|xml)(\\?|$)/);\n    return m ? m[1] : 'js';\n  }\n  function init(o, fn) {\n    this.url = typeof o == 'string' ? o : o['url'];\n    this.timeout = null;\n    this._fulfilled = false;\n    this._successHandler = function () {\n    };\n    this._fulfillmentHandlers = [];\n    this._errorHandlers = [];\n    this._completeHandlers = [];\n    this._erred = false;\n    this._responseArgs = {};\n    var self = this, type = o['type'] || setType(this.url);\n    fn = fn || function () {\n    };\n    if (o['timeout']) {\n      this.timeout = setTimeout(function () {\n        self.abort();\n      }, o['timeout']);\n    }\n    if (o['success']) {\n      this._successHandler = function () {\n        o['success'].apply(o, arguments);\n      };\n    }\n    if (o['error']) {\n      this._errorHandlers.push(function () {\n        o['error'].apply(o, arguments);\n      });\n    }\n    if (o['complete']) {\n      this._completeHandlers.push(function () {\n        o['complete'].apply(o, arguments);\n      });\n    }\n    function complete(resp) {\n      o['timeout'] && clearTimeout(self.timeout);\n      self.timeout = null;\n      while (self._completeHandlers.length > 0) {\n        self._completeHandlers.shift()(resp);\n      }\n    }\n    function success(resp) {\n      resp = type !== 'jsonp' ? self.request : resp;\n      var filteredResponse = globalSetupOptions.dataFilter(resp.responseText, type), r = filteredResponse;\n      try {\n        resp.responseText = r;\n      } catch (e) {\n      }\n      if (r) {\n        switch (type) {\n        case 'json':\n          try {\n            resp = win.JSON ? win.JSON.parse(r) : eval('(' + r + ')');\n          } catch (err) {\n            return error(resp, 'Could not parse JSON in response', err);\n          }\n          break;\n        case 'js':\n          resp = eval(r);\n          break;\n        case 'html':\n          resp = r;\n          break;\n        case 'xml':\n          resp = resp.responseXML && resp.responseXML.parseError && resp.responseXML.parseError.errorCode && resp.responseXML.parseError.reason ? null : resp.responseXML;\n          break;\n        }\n      }\n      self._responseArgs.resp = resp;\n      self._fulfilled = true;\n      fn(resp);\n      self._successHandler(resp);\n      while (self._fulfillmentHandlers.length > 0) {\n        resp = self._fulfillmentHandlers.shift()(resp);\n      }\n      complete(resp);\n    }\n    function error(resp, msg, t) {\n      resp = self.request;\n      self._responseArgs.resp = resp;\n      self._responseArgs.msg = msg;\n      self._responseArgs.t = t;\n      self._erred = true;\n      while (self._errorHandlers.length > 0) {\n        self._errorHandlers.shift()(resp, msg, t);\n      }\n      complete(resp);\n    }\n    this.request = getRequest.call(this, success, error);\n  }\n  Reqwest.prototype = {\n    abort: function () {\n      this._aborted = true;\n      this.request.abort();\n    },\n    retry: function () {\n      init.call(this, this.o, this.fn);\n    },\n    then: function (success, fail) {\n      success = success || function () {\n      };\n      fail = fail || function () {\n      };\n      if (this._fulfilled) {\n        this._responseArgs.resp = success(this._responseArgs.resp);\n      } else if (this._erred) {\n        fail(this._responseArgs.resp, this._responseArgs.msg, this._responseArgs.t);\n      } else {\n        this._fulfillmentHandlers.push(success);\n        this._errorHandlers.push(fail);\n      }\n      return this;\n    },\n    always: function (fn) {\n      if (this._fulfilled || this._erred) {\n        fn(this._responseArgs.resp);\n      } else {\n        this._completeHandlers.push(fn);\n      }\n      return this;\n    },\n    fail: function (fn) {\n      if (this._erred) {\n        fn(this._responseArgs.resp, this._responseArgs.msg, this._responseArgs.t);\n      } else {\n        this._errorHandlers.push(fn);\n      }\n      return this;\n    }\n  };\n  function reqwest(o, fn) {\n    return new Reqwest(o, fn);\n  }\n  function normalize(s) {\n    return s ? s.replace(/\\r?\\n/g, '\\r\\n') : '';\n  }\n  function serial(el, cb) {\n    var n = el.name, t = el.tagName.toLowerCase(), optCb = function (o) {\n        if (o && !o['disabled'])\n          cb(n, normalize(o['attributes']['value'] && o['attributes']['value']['specified'] ? o['value'] : o['text']));\n      }, ch, ra, val, i;\n    if (el.disabled || !n)\n      return;\n    switch (t) {\n    case 'input':\n      if (!/reset|button|image|file/i.test(el.type)) {\n        ch = /checkbox/i.test(el.type);\n        ra = /radio/i.test(el.type);\n        val = el.value;\n        (!(ch || ra) || el.checked) && cb(n, normalize(ch && val === '' ? 'on' : val));\n      }\n      break;\n    case 'textarea':\n      cb(n, normalize(el.value));\n      break;\n    case 'select':\n      if (el.type.toLowerCase() === 'select-one') {\n        optCb(el.selectedIndex >= 0 ? el.options[el.selectedIndex] : null);\n      } else {\n        for (i = 0; el.length && i < el.length; i++) {\n          el.options[i].selected && optCb(el.options[i]);\n        }\n      }\n      break;\n    }\n  }\n  function eachFormElement() {\n    var cb = this, e, i, serializeSubtags = function (e, tags) {\n        var i, j, fa;\n        for (i = 0; i < tags.length; i++) {\n          fa = e[byTag](tags[i]);\n          for (j = 0; j < fa.length; j++)\n            serial(fa[j], cb);\n        }\n      };\n    for (i = 0; i < arguments.length; i++) {\n      e = arguments[i];\n      if (/input|select|textarea/i.test(e.tagName))\n        serial(e, cb);\n      serializeSubtags(e, [\n        'input',\n        'select',\n        'textarea'\n      ]);\n    }\n  }\n  function serializeQueryString() {\n    return reqwest.toQueryString(reqwest.serializeArray.apply(null, arguments));\n  }\n  function serializeHash() {\n    var hash = {};\n    eachFormElement.apply(function (name, value) {\n      if (name in hash) {\n        hash[name] && !isArray(hash[name]) && (hash[name] = [hash[name]]);\n        hash[name].push(value);\n      } else\n        hash[name] = value;\n    }, arguments);\n    return hash;\n  }\n  reqwest.serializeArray = function () {\n    var arr = [];\n    eachFormElement.apply(function (name, value) {\n      arr.push({\n        name: name,\n        value: value\n      });\n    }, arguments);\n    return arr;\n  };\n  reqwest.serialize = function () {\n    if (arguments.length === 0)\n      return '';\n    var opt, fn, args = Array.prototype.slice.call(arguments, 0);\n    opt = args.pop();\n    opt && opt.nodeType && args.push(opt) && (opt = null);\n    opt && (opt = opt.type);\n    if (opt == 'map')\n      fn = serializeHash;\n    else if (opt == 'array')\n      fn = reqwest.serializeArray;\n    else\n      fn = serializeQueryString;\n    return fn.apply(null, args);\n  };\n  reqwest.toQueryString = function (o, trad) {\n    var prefix, i, traditional = trad || false, s = [], enc = encodeURIComponent, add = function (key, value) {\n        value = 'function' === typeof value ? value() : value == null ? '' : value;\n        s[s.length] = enc(key) + '=' + enc(value);\n      };\n    if (isArray(o)) {\n      for (i = 0; o && i < o.length; i++)\n        add(o[i]['name'], o[i]['value']);\n    } else {\n      for (prefix in o) {\n        if (o.hasOwnProperty(prefix))\n          buildParams(prefix, o[prefix], traditional, add);\n      }\n    }\n    return s.join('&').replace(/%20/g, '+');\n  };\n  function buildParams(prefix, obj, traditional, add) {\n    var name, i, v, rbracket = /\\[\\]$/;\n    if (isArray(obj)) {\n      for (i = 0; obj && i < obj.length; i++) {\n        v = obj[i];\n        if (traditional || rbracket.test(prefix)) {\n          add(prefix, v);\n        } else {\n          buildParams(prefix + '[' + (typeof v === 'object' ? i : '') + ']', v, traditional, add);\n        }\n      }\n    } else if (obj && obj.toString() === '[object Object]') {\n      for (name in obj) {\n        buildParams(prefix + '[' + name + ']', obj[name], traditional, add);\n      }\n    } else {\n      add(prefix, obj);\n    }\n  }\n  reqwest.getcallbackPrefix = function () {\n    return callbackPrefix;\n  };\n  reqwest.compat = function (o, fn) {\n    if (o) {\n      o['type'] && (o['method'] = o['type']) && delete o['type'];\n      o['dataType'] && (o['type'] = o['dataType']);\n      o['jsonpCallback'] && (o['jsonpCallbackName'] = o['jsonpCallback']) && delete o['jsonpCallback'];\n      o['jsonp'] && (o['jsonpCallback'] = o['jsonp']);\n    }\n    return new Reqwest(o, fn);\n  };\n  reqwest.ajaxSetup = function (options) {\n    options = options || {};\n    for (var k in options) {\n      globalSetupOptions[k] = options[k];\n    }\n  };\n  return reqwest;\n});\namdclean['inputfiles'] = function (require, core, reqwest) {\n  'use strict';\n  var p5 = core;\n  var reqwest = reqwest;\n  p5.prototype.createInput = function () {\n    throw 'not yet implemented';\n  };\n  p5.prototype.createReader = function () {\n    throw 'not yet implemented';\n  };\n  p5.prototype.loadBytes = function () {\n    throw 'not yet implemented';\n  };\n  p5.prototype.loadJSON = function () {\n    var path = arguments[0];\n    var callback = arguments[1];\n    var ret = [];\n    var t = 'json';\n    if (typeof arguments[2] === 'string') {\n      if (arguments[2] === 'jsonp' || arguments[2] === 'json') {\n        t = arguments[2];\n      }\n    }\n    reqwest({\n      url: path,\n      type: t,\n      crossOrigin: true\n    }).then(function (resp) {\n      for (var k in resp) {\n        ret[k] = resp[k];\n      }\n      if (typeof callback !== 'undefined') {\n        callback(resp);\n      }\n    });\n    return ret;\n  };\n  p5.prototype.loadStrings = function (path, callback) {\n    var ret = [];\n    var req = new XMLHttpRequest();\n    req.open('GET', path, true);\n    req.onreadystatechange = function () {\n      if (req.readyState === 4 && (req.status === 200 || req.status === 0)) {\n        var arr = req.responseText.match(/[^\\r\\n]+/g);\n        for (var k in arr) {\n          ret[k] = arr[k];\n        }\n        if (typeof callback !== 'undefined') {\n          callback(ret);\n        }\n      }\n    };\n    req.send(null);\n    return ret;\n  };\n  p5.prototype.loadTable = function (path) {\n    var callback = null;\n    var options = [];\n    var header = false;\n    var sep = ',';\n    for (var i = 1; i < arguments.length; i++) {\n      if (typeof arguments[i] === 'function') {\n        callback = arguments[i];\n      } else if (typeof arguments[i] === 'string') {\n        options.push(arguments[i]);\n        if (arguments[i] === 'header') {\n          header = true;\n        }\n        if (arguments[i] === 'csv') {\n          sep = ',';\n        } else if (arguments[i] === 'tsv') {\n          sep = '\\t';\n        }\n      }\n    }\n    var ret = [];\n    var t = new p5.Table();\n    var req = new XMLHttpRequest();\n    req.open('GET', path, true);\n    req.onreadystatechange = function () {\n      if (req.readyState === 4 && (req.status === 200 || req.status === 0)) {\n        var arr = req.responseText.match(/[^\\r\\n]+/g);\n        for (var k in arr) {\n          ret[k] = arr[k];\n        }\n        if (typeof callback !== 'undefined') {\n          var i, row;\n          if (header) {\n            t.columns = new p5.TableRow(ret[0]).arr;\n            for (i = 1; i < ret.length; i++) {\n              row = new p5.TableRow(ret[i], sep);\n              row.obj = makeObject(row.arr, t.columns);\n              t.addRow(row);\n            }\n          } else {\n            for (i = 0; i < ret[0].split(sep).length; i++) {\n              t.columns[i] = i.toString();\n            }\n            for (i = 0; i < ret.length; i++) {\n              row = new p5.TableRow(ret[i], sep);\n              t.addRow(row);\n            }\n          }\n          callback(t);\n        }\n      }\n    };\n    req.send(null);\n    return t;\n  };\n  function makeObject(row, headers) {\n    var ret = {};\n    headers = headers || [];\n    if (typeof headers === 'undefined') {\n      for (var j = 0; j < row.length; j++) {\n        headers[j.toString()] = j;\n      }\n    }\n    for (var i = 0; i < headers.length; i++) {\n      var key = headers[i];\n      var val = row[i];\n      ret[key] = val;\n    }\n    return ret;\n  }\n  p5.prototype.loadXML = function (path, callback) {\n    var ret = [];\n    reqwest({\n      url: path,\n      type: 'xml',\n      crossOrigin: true\n    }).then(function (resp) {\n      callback(resp);\n    });\n    return ret;\n  };\n  p5.prototype.parseXML = function () {\n    throw 'not yet implemented';\n  };\n  p5.prototype.selectFolder = function () {\n    throw 'not yet implemented';\n  };\n  p5.prototype.selectInput = function () {\n    throw 'not yet implemented';\n  };\n  p5.prototype.httpGet = function () {\n    var args = Array.prototype.slice.call(arguments);\n    args.push('GET');\n    p5.prototype.httpDo.apply(this, args);\n  };\n  p5.prototype.httpPost = function () {\n    var args = Array.prototype.slice.call(arguments);\n    args.push('POST');\n    p5.prototype.httpDo.apply(this, args);\n  };\n  p5.prototype.httpDo = function () {\n    var method = 'GET';\n    var path = arguments[0];\n    var data = {};\n    var type = '';\n    var callback;\n    for (var i = 1; i < arguments.length; i++) {\n      var a = arguments[i];\n      if (typeof a === 'string') {\n        if (a === 'GET' || a === 'POST' || a === 'PUT') {\n          method = a;\n        } else {\n          type = a;\n        }\n      } else if (typeof a === 'object') {\n        data = a;\n      } else if (typeof a === 'function') {\n        callback = a;\n      }\n    }\n    if (type === '') {\n      if (path.indexOf('json') !== -1) {\n        type = 'json';\n      } else if (path.indexOf('xml') !== -1) {\n        type = 'xml';\n      } else {\n        type = 'text';\n      }\n    }\n    reqwest({\n      url: path,\n      method: method,\n      data: data,\n      type: type,\n      crossOrigin: true,\n      success: function (resp) {\n        if (typeof callback !== 'undefined') {\n          if (type === 'text') {\n            callback(resp.response);\n          } else {\n            callback(resp);\n          }\n        }\n      }\n    });\n  };\n  return p5;\n}({}, amdclean['core'], amdclean['reqwest']);\namdclean['inputkeyboard'] = function (require, core) {\n  'use strict';\n  var p5 = core;\n  var downKeys = {};\n  p5.prototype.isKeyPressed = false;\n  p5.prototype.keyIsPressed = false;\n  p5.prototype.key = '';\n  p5.prototype.keyCode = 0;\n  p5.prototype.onkeydown = function (e) {\n    this._setProperty('isKeyPressed', true);\n    this._setProperty('keyIsPressed', true);\n    this._setProperty('keyCode', e.which);\n    downKeys[e.which] = true;\n    var key = String.fromCharCode(e.which);\n    if (!key) {\n      key = e.which;\n    }\n    this._setProperty('key', key);\n    var keyPressed = this.keyPressed || window.keyPressed;\n    if (typeof keyPressed === 'function' && !e.charCode) {\n      var executeDefault = keyPressed(e);\n      if (executeDefault === false) {\n        e.preventDefault();\n      }\n    }\n  };\n  p5.prototype.onkeyup = function (e) {\n    var keyReleased = this.keyReleased || window.keyReleased;\n    this._setProperty('isKeyPressed', false);\n    this._setProperty('keyIsPressed', false);\n    downKeys[e.which] = false;\n    var key = String.fromCharCode(e.which);\n    if (!key) {\n      key = e.which;\n    }\n    this._setProperty('key', key);\n    this._setProperty('keyCode', e.which);\n    if (typeof keyReleased === 'function') {\n      var executeDefault = keyReleased(e);\n      if (executeDefault === false) {\n        e.preventDefault();\n      }\n    }\n  };\n  p5.prototype.onkeypress = function (e) {\n    this._setProperty('keyCode', e.which);\n    this._setProperty('key', String.fromCharCode(e.which));\n    var keyTyped = this.keyTyped || window.keyTyped;\n    if (typeof keyTyped === 'function') {\n      var executeDefault = keyTyped(e);\n      if (executeDefault === false) {\n        e.preventDefault();\n      }\n    }\n  };\n  p5.prototype.onblur = function (e) {\n    downKeys = {};\n  };\n  p5.prototype.keyIsDown = function (code) {\n    return downKeys[code];\n  };\n  return p5;\n}({}, amdclean['core']);\namdclean['inputmouse'] = function (require, core, constants) {\n  'use strict';\n  var p5 = core;\n  var constants = constants;\n  p5.prototype.mouseX = 0;\n  p5.prototype.mouseY = 0;\n  p5.prototype.pmouseX = 0;\n  p5.prototype.pmouseY = 0;\n  p5.prototype.winMouseX = 0;\n  p5.prototype.winMouseY = 0;\n  p5.prototype.pwinMouseX = 0;\n  p5.prototype.pwinMouseY = 0;\n  p5.prototype.mouseButton = 0;\n  p5.prototype.mouseIsPressed = false;\n  p5.prototype.isMousePressed = false;\n  p5.prototype._updateMouseCoords = function (e) {\n    if (e.type === 'touchstart' || e.type === 'touchmove' || e.type === 'touchend') {\n      this._setProperty('mouseX', this.touchX);\n      this._setProperty('mouseY', this.touchY);\n    } else {\n      if (this._curElement !== null) {\n        var mousePos = getMousePos(this._curElement.elt, e);\n        this._setProperty('mouseX', mousePos.x);\n        this._setProperty('mouseY', mousePos.y);\n      }\n    }\n    this._setProperty('winMouseX', e.pageX);\n    this._setProperty('winMouseY', e.pageY);\n  };\n  p5.prototype._updatePMouseCoords = function (e) {\n    this._setProperty('pmouseX', this.mouseX);\n    this._setProperty('pmouseY', this.mouseY);\n    this._setProperty('pwinMouseX', this.winMouseX);\n    this._setProperty('pwinMouseY', this.winMouseY);\n  };\n  function getMousePos(canvas, evt) {\n    var rect = canvas.getBoundingClientRect();\n    return {\n      x: evt.clientX - rect.left,\n      y: evt.clientY - rect.top\n    };\n  }\n  p5.prototype._setMouseButton = function (e) {\n    if (e.button === 1) {\n      this._setProperty('mouseButton', constants.CENTER);\n    } else if (e.button === 2) {\n      this._setProperty('mouseButton', constants.RIGHT);\n    } else {\n      this._setProperty('mouseButton', constants.LEFT);\n      if (e.type === 'touchstart' || e.type === 'touchmove') {\n        this._setProperty('mouseX', this.touchX);\n        this._setProperty('mouseY', this.touchY);\n      }\n    }\n  };\n  p5.prototype.onmousemove = function (e) {\n    var context = this._isGlobal ? window : this;\n    var executeDefault;\n    this._updateMouseCoords(e);\n    if (!this.isMousePressed) {\n      if (typeof context.mouseMoved === 'function') {\n        executeDefault = context.mouseMoved(e);\n        if (executeDefault === false) {\n          e.preventDefault();\n        }\n      }\n    } else {\n      if (typeof context.mouseDragged === 'function') {\n        executeDefault = context.mouseDragged(e);\n        if (executeDefault === false) {\n          e.preventDefault();\n        }\n      } else if (typeof context.touchMoved === 'function') {\n        executeDefault = context.touchMoved(e);\n        if (executeDefault === false) {\n          e.preventDefault();\n        }\n        this._updateTouchCoords(e);\n      }\n    }\n  };\n  p5.prototype.onmousedown = function (e) {\n    var context = this._isGlobal ? window : this;\n    var executeDefault;\n    this._setProperty('isMousePressed', true);\n    this._setProperty('mouseIsPressed', true);\n    this._setMouseButton(e);\n    this._updateMouseCoords(e);\n    if (typeof context.mousePressed === 'function') {\n      executeDefault = context.mousePressed(e);\n      if (executeDefault === false) {\n        e.preventDefault();\n      }\n    } else if (typeof context.touchStarted === 'function') {\n      executeDefault = context.touchStarted(e);\n      if (executeDefault === false) {\n        e.preventDefault();\n      }\n      this._updateTouchCoords(e);\n    }\n  };\n  p5.prototype.onmouseup = function (e) {\n    var context = this._isGlobal ? window : this;\n    var executeDefault;\n    this._setProperty('isMousePressed', false);\n    this._setProperty('mouseIsPressed', false);\n    if (typeof context.mouseReleased === 'function') {\n      executeDefault = context.mouseReleased(e);\n      if (executeDefault === false) {\n        e.preventDefault();\n      }\n    } else if (typeof context.touchEnded === 'function') {\n      executeDefault = context.touchEnded(e);\n      if (executeDefault === false) {\n        e.preventDefault();\n      }\n      this._updateTouchCoords(e);\n    }\n  };\n  p5.prototype.onclick = function (e) {\n    var context = this._isGlobal ? window : this;\n    if (typeof context.mouseClicked === 'function') {\n      var executeDefault = context.mouseClicked(e);\n      if (executeDefault === false) {\n        e.preventDefault();\n      }\n    }\n  };\n  p5.prototype.onmousewheel = function (e) {\n    var context = this._isGlobal ? window : this;\n    if (typeof context.mouseWheel === 'function') {\n      var executeDefault = context.mouseWheel(e);\n      if (executeDefault === false) {\n        e.preventDefault();\n      }\n    }\n  };\n  return p5;\n}({}, amdclean['core'], amdclean['constants']);\namdclean['inputtime_date'] = function (require, core) {\n  'use strict';\n  var p5 = core;\n  p5.prototype.day = function () {\n    return new Date().getDate();\n  };\n  p5.prototype.hour = function () {\n    return new Date().getHours();\n  };\n  p5.prototype.minute = function () {\n    return new Date().getMinutes();\n  };\n  p5.prototype.millis = function () {\n    return new Date().getTime() - this._startTime;\n  };\n  p5.prototype.month = function () {\n    return new Date().getMonth() + 1;\n  };\n  p5.prototype.second = function () {\n    return new Date().getSeconds();\n  };\n  p5.prototype.year = function () {\n    return new Date().getFullYear();\n  };\n  return p5;\n}({}, amdclean['core']);\namdclean['inputtouch'] = function (require, core) {\n  'use strict';\n  var p5 = core;\n  p5.prototype.touchX = 0;\n  p5.prototype.touchY = 0;\n  p5.prototype.ptouchX = 0;\n  p5.prototype.ptouchY = 0;\n  p5.prototype.touches = [];\n  p5.prototype.touchIsDown = false;\n  p5.prototype._updateTouchCoords = function (e) {\n    if (e.type === 'mousedown' || e.type === 'mousemove' || e.type === 'mouseup') {\n      this._setProperty('touchX', this.mouseX);\n      this._setProperty('touchY', this.mouseY);\n    } else {\n      var touchPos = getTouchPos(this._curElement.elt, e, 0);\n      this._setProperty('touchX', touchPos.x);\n      this._setProperty('touchY', touchPos.y);\n      var touches = [];\n      for (var i = 0; i < e.changedTouches.length; i++) {\n        var pos = getTouchPos(this._curElement.elt, e, i);\n        touches[i] = {\n          x: pos.x,\n          y: pos.y\n        };\n      }\n      this._setProperty('touches', touches);\n    }\n  };\n  p5.prototype._updatePTouchCoords = function () {\n    this._setProperty('ptouchX', this.touchX);\n    this._setProperty('ptouchY', this.touchY);\n  };\n  function getTouchPos(canvas, e, i) {\n    i = i || 0;\n    var rect = canvas.getBoundingClientRect();\n    return {\n      x: e.changedTouches[i].pageX - rect.left,\n      y: e.changedTouches[i].pageY - rect.top\n    };\n  }\n  p5.prototype.ontouchstart = function (e) {\n    var context = this._isGlobal ? window : this;\n    var executeDefault;\n    this._updateTouchCoords(e);\n    this._setProperty('touchIsDown', true);\n    if (typeof context.touchStarted === 'function') {\n      executeDefault = context.touchStarted(e);\n      if (executeDefault === false) {\n        e.preventDefault();\n      }\n    } else if (typeof context.mousePressed === 'function') {\n      executeDefault = context.mousePressed(e);\n      if (executeDefault === false) {\n        e.preventDefault();\n      }\n    }\n  };\n  p5.prototype.ontouchmove = function (e) {\n    var context = this._isGlobal ? window : this;\n    var executeDefault;\n    this._updateTouchCoords(e);\n    if (typeof context.touchMoved === 'function') {\n      executeDefault = context.touchMoved(e);\n      if (executeDefault === false) {\n        e.preventDefault();\n      }\n    } else if (typeof context.mouseDragged === 'function') {\n      executeDefault = context.mouseDragged(e);\n      if (executeDefault === false) {\n        e.preventDefault();\n      }\n      this._updateMouseCoords(e);\n    }\n  };\n  p5.prototype.ontouchend = function (e) {\n    this._updateTouchCoords(e);\n    if (this.touches.length === 0) {\n      this._setProperty('touchIsDown', false);\n    }\n    var context = this._isGlobal ? window : this;\n    var executeDefault;\n    if (typeof context.touchEnded === 'function') {\n      executeDefault = context.touchEnded(e);\n      if (executeDefault === false) {\n        e.preventDefault();\n      }\n    } else if (typeof context.mouseReleased === 'function') {\n      executeDefault = context.mouseReleased(e);\n      if (executeDefault === false) {\n        e.preventDefault();\n      }\n      this._updateMouseCoords(e);\n    }\n  };\n  return p5;\n}({}, amdclean['core']);\namdclean['mathmath'] = function (require, core) {\n  'use strict';\n  var p5 = core;\n  p5.prototype.createVector = function (x, y, z) {\n    if (this instanceof p5) {\n      return new p5.Vector(this, arguments);\n    } else {\n      return new p5.Vector(x, y, z);\n    }\n  };\n  return p5;\n}({}, amdclean['core']);\namdclean['mathcalculation'] = function (require, core) {\n  'use strict';\n  var p5 = core;\n  p5.prototype.abs = Math.abs;\n  p5.prototype.ceil = Math.ceil;\n  p5.prototype.constrain = function (n, low, high) {\n    return Math.max(Math.min(n, high), low);\n  };\n  p5.prototype.dist = function (x1, y1, x2, y2) {\n    return Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));\n  };\n  p5.prototype.exp = Math.exp;\n  p5.prototype.floor = Math.floor;\n  p5.prototype.lerp = function (start, stop, amt) {\n    return amt * (stop - start) + start;\n  };\n  p5.prototype.log = Math.log;\n  p5.prototype.mag = function (x, y) {\n    return Math.sqrt(x * x + y * y);\n  };\n  p5.prototype.map = function (n, start1, stop1, start2, stop2) {\n    return (n - start1) / (stop1 - start1) * (stop2 - start2) + start2;\n  };\n  p5.prototype.max = function () {\n    if (arguments[0] instanceof Array) {\n      return Math.max.apply(null, arguments[0]);\n    } else {\n      return Math.max.apply(null, arguments);\n    }\n  };\n  p5.prototype.min = function () {\n    if (arguments[0] instanceof Array) {\n      return Math.min.apply(null, arguments[0]);\n    } else {\n      return Math.min.apply(null, arguments);\n    }\n  };\n  p5.prototype.norm = function (n, start, stop) {\n    return this.map(n, start, stop, 0, 1);\n  };\n  p5.prototype.pow = Math.pow;\n  p5.prototype.round = Math.round;\n  p5.prototype.sq = function (n) {\n    return n * n;\n  };\n  p5.prototype.sqrt = Math.sqrt;\n  return p5;\n}({}, amdclean['core']);\namdclean['mathrandom'] = function (require, core) {\n  'use strict';\n  var p5 = core;\n  var seeded = false;\n  var lcg = function () {\n      var m = 4294967296, a = 1664525, c = 1013904223, seed, z;\n      return {\n        setSeed: function (val) {\n          z = seed = (val == null ? Math.random() * m : val) >>> 0;\n        },\n        getSeed: function () {\n          return seed;\n        },\n        rand: function () {\n          z = (a * z + c) % m;\n          return z / m;\n        }\n      };\n    }();\n  p5.prototype.randomSeed = function (seed) {\n    lcg.setSeed(seed);\n    seeded = true;\n  };\n  p5.prototype.random = function (min, max) {\n    var rand;\n    if (seeded) {\n      rand = lcg.rand();\n    } else {\n      rand = Math.random();\n    }\n    if (arguments.length === 0) {\n      return rand;\n    } else if (arguments.length === 1) {\n      return rand * min;\n    } else {\n      if (min > max) {\n        var tmp = min;\n        min = max;\n        max = tmp;\n      }\n      return rand * (max - min) + min;\n    }\n  };\n  var y2;\n  var previous = false;\n  p5.prototype.randomGaussian = function (mean, sd) {\n    var y1, x1, x2, w;\n    if (previous) {\n      y1 = y2;\n      previous = false;\n    } else {\n      do {\n        x1 = this.random(2) - 1;\n        x2 = this.random(2) - 1;\n        w = x1 * x1 + x2 * x2;\n      } while (w >= 1);\n      w = Math.sqrt(-2 * Math.log(w) / w);\n      y1 = x1 * w;\n      y2 = x2 * w;\n      previous = true;\n    }\n    var m = mean || 0;\n    var s = sd || 1;\n    return y1 * s + m;\n  };\n  return p5;\n}({}, amdclean['core']);\namdclean['mathnoise'] = function (require, core) {\n  'use strict';\n  var p5 = core;\n  var PERLIN_YWRAPB = 4;\n  var PERLIN_YWRAP = 1 << PERLIN_YWRAPB;\n  var PERLIN_ZWRAPB = 8;\n  var PERLIN_ZWRAP = 1 << PERLIN_ZWRAPB;\n  var PERLIN_SIZE = 4095;\n  var perlin_octaves = 4;\n  var perlin_amp_falloff = 0.5;\n  var SINCOS_PRECISION = 0.5;\n  var SINCOS_LENGTH = Math.floor(360 / SINCOS_PRECISION);\n  var sinLUT = new Array(SINCOS_LENGTH);\n  var cosLUT = new Array(SINCOS_LENGTH);\n  var DEG_TO_RAD = Math.PI / 180;\n  for (var i = 0; i < SINCOS_LENGTH; i++) {\n    sinLUT[i] = Math.sin(i * DEG_TO_RAD * SINCOS_PRECISION);\n    cosLUT[i] = Math.cos(i * DEG_TO_RAD * SINCOS_PRECISION);\n  }\n  var perlin_PI = SINCOS_LENGTH;\n  perlin_PI >>= 1;\n  var perlin;\n  p5.prototype.noise = function (x, y, z) {\n    y = y || 0;\n    z = z || 0;\n    if (perlin == null) {\n      perlin = new Array(PERLIN_SIZE + 1);\n      for (var i = 0; i < PERLIN_SIZE + 1; i++) {\n        perlin[i] = Math.random();\n      }\n    }\n    if (x < 0) {\n      x = -x;\n    }\n    if (y < 0) {\n      y = -y;\n    }\n    if (z < 0) {\n      z = -z;\n    }\n    var xi = Math.floor(x), yi = Math.floor(y), zi = Math.floor(z);\n    var xf = x - xi;\n    var yf = y - yi;\n    var zf = z - zi;\n    var rxf, ryf;\n    var r = 0;\n    var ampl = 0.5;\n    var n1, n2, n3;\n    var noise_fsc = function (i) {\n      return 0.5 * (1 - cosLUT[Math.floor(i * perlin_PI) % SINCOS_LENGTH]);\n    };\n    for (var o = 0; o < perlin_octaves; o++) {\n      var of = xi + (yi << PERLIN_YWRAPB) + (zi << PERLIN_ZWRAPB);\n      rxf = noise_fsc(xf);\n      ryf = noise_fsc(yf);\n      n1 = perlin[of & PERLIN_SIZE];\n      n1 += rxf * (perlin[of + 1 & PERLIN_SIZE] - n1);\n      n2 = perlin[of + PERLIN_YWRAP & PERLIN_SIZE];\n      n2 += rxf * (perlin[of + PERLIN_YWRAP + 1 & PERLIN_SIZE] - n2);\n      n1 += ryf * (n2 - n1);\n      of += PERLIN_ZWRAP;\n      n2 = perlin[of & PERLIN_SIZE];\n      n2 += rxf * (perlin[of + 1 & PERLIN_SIZE] - n2);\n      n3 = perlin[of + PERLIN_YWRAP & PERLIN_SIZE];\n      n3 += rxf * (perlin[of + PERLIN_YWRAP + 1 & PERLIN_SIZE] - n3);\n      n2 += ryf * (n3 - n2);\n      n1 += noise_fsc(zf) * (n2 - n1);\n      r += n1 * ampl;\n      ampl *= perlin_amp_falloff;\n      xi <<= 1;\n      xf *= 2;\n      yi <<= 1;\n      yf *= 2;\n      zi <<= 1;\n      zf *= 2;\n      if (xf >= 1) {\n        xi++;\n        xf--;\n      }\n      if (yf >= 1) {\n        yi++;\n        yf--;\n      }\n      if (zf >= 1) {\n        zi++;\n        zf--;\n      }\n    }\n    return r;\n  };\n  p5.prototype.noiseDetail = function (lod, falloff) {\n    if (lod > 0) {\n      perlin_octaves = lod;\n    }\n    if (falloff > 0) {\n      perlin_amp_falloff = falloff;\n    }\n  };\n  p5.prototype.noiseSeed = function (seed) {\n    var lcg = function () {\n        var m = 4294967296, a = 1664525, c = 1013904223, seed, z;\n        return {\n          setSeed: function (val) {\n            z = seed = (val == null ? Math.random() * m : val) >>> 0;\n          },\n          getSeed: function () {\n            return seed;\n          },\n          rand: function () {\n            z = (a * z + c) % m;\n            return z / m;\n          }\n        };\n      }();\n    lcg.setSeed(seed);\n    perlin = new Array(PERLIN_SIZE + 1);\n    for (var i = 0; i < PERLIN_SIZE + 1; i++) {\n      perlin[i] = lcg.rand();\n    }\n  };\n  return p5;\n}({}, amdclean['core']);\namdclean['mathtrigonometry'] = function (require, core, polargeometry, constants) {\n  'use strict';\n  var p5 = core;\n  var polarGeometry = polargeometry;\n  var constants = constants;\n  p5.prototype._angleMode = constants.RADIANS;\n  p5.prototype.acos = function (ratio) {\n    if (this._angleMode === constants.RADIANS) {\n      return Math.acos(ratio);\n    } else {\n      return polarGeometry.radiansToDegrees(Math.acos(ratio));\n    }\n  };\n  p5.prototype.asin = function (ratio) {\n    if (this._angleMode === constants.RADIANS) {\n      return Math.asin(ratio);\n    } else {\n      return polarGeometry.radiansToDegrees(Math.asin(ratio));\n    }\n  };\n  p5.prototype.atan = function (ratio) {\n    if (this._angleMode === constants.RADIANS) {\n      return Math.atan(ratio);\n    } else {\n      return polarGeometry.radiansToDegrees(Math.atan(ratio));\n    }\n  };\n  p5.prototype.atan2 = function (y, x) {\n    if (this._angleMode === constants.RADIANS) {\n      return Math.atan2(y, x);\n    } else {\n      return polarGeometry.radiansToDegrees(Math.atan2(y, x));\n    }\n  };\n  p5.prototype.cos = function (angle) {\n    if (this._angleMode === constants.RADIANS) {\n      return Math.cos(angle);\n    } else {\n      return Math.cos(this.radians(angle));\n    }\n  };\n  p5.prototype.sin = function (angle) {\n    if (this._angleMode === constants.RADIANS) {\n      return Math.sin(angle);\n    } else {\n      return Math.sin(this.radians(angle));\n    }\n  };\n  p5.prototype.tan = function (angle) {\n    if (this._angleMode === constants.RADIANS) {\n      return Math.tan(angle);\n    } else {\n      return Math.tan(this.radians(angle));\n    }\n  };\n  p5.prototype.degrees = function (angle) {\n    return polarGeometry.radiansToDegrees(angle);\n  };\n  p5.prototype.radians = function (angle) {\n    return polarGeometry.degreesToRadians(angle);\n  };\n  p5.prototype.angleMode = function (mode) {\n    if (mode === constants.DEGREES || mode === constants.RADIANS) {\n      this._angleMode = mode;\n    }\n  };\n  return p5;\n}({}, amdclean['core'], amdclean['polargeometry'], amdclean['constants']);\namdclean['outputfiles'] = function (require, core) {\n  'use strict';\n  var p5 = core;\n  window.URL = window.URL || window.webkitURL;\n  p5.prototype._pWriters = [];\n  p5.prototype.beginRaw = function () {\n    throw 'not yet implemented';\n  };\n  p5.prototype.beginRecord = function () {\n    throw 'not yet implemented';\n  };\n  p5.prototype.createOutput = function () {\n    throw 'not yet implemented';\n  };\n  p5.prototype.createWriter = function (name, extension) {\n    var newPW;\n    for (var i in p5.prototype._pWriters) {\n      if (p5.prototype._pWriters[i].name === name) {\n        newPW = new p5.PrintWriter(name + window.millis(), extension);\n        p5.prototype._pWriters.push(newPW);\n        return newPW;\n      }\n    }\n    newPW = new p5.PrintWriter(name, extension);\n    p5.prototype._pWriters.push(newPW);\n    return newPW;\n  };\n  p5.prototype.endRaw = function () {\n    throw 'not yet implemented';\n  };\n  p5.prototype.endRecord = function () {\n    throw 'not yet implemented';\n  };\n  p5.PrintWriter = function (filename, extension) {\n    var self = this;\n    this.name = filename;\n    this.content = '';\n    this.print = function (data) {\n      this.content += data;\n    };\n    this.println = function (data) {\n      this.content += data + '\\n';\n    };\n    this.flush = function () {\n      this.content = '';\n    };\n    this.close = function () {\n      var arr = [];\n      arr.push(this.content);\n      p5.prototype.writeFile(arr, filename, extension);\n      for (var i in p5.prototype._pWriters) {\n        if (p5.prototype._pWriters[i].name === this.name) {\n          p5.prototype._pWriters.splice(i, 1);\n        }\n      }\n      self.flush();\n      self = {};\n    };\n  };\n  p5.prototype.saveBytes = function () {\n    throw 'not yet implemented';\n  };\n  p5.prototype.save = function (object, _filename, _options) {\n    var args = arguments;\n    var cnv = this._curElement.elt;\n    if (args.length === 0) {\n      p5.prototype.saveCanvas(cnv);\n      return;\n    } else if (args[0] instanceof p5.Graphics) {\n      p5.prototype.saveCanvas(args[0].elt, args[1], args[2]);\n      return;\n    } else if (typeof args[0] === 'string') {\n      p5.prototype.saveCanvas(cnv, args[0]);\n    } else {\n      var extension = _checkFileExtension(args[1], args[2])[1];\n      switch (extension) {\n      case 'json':\n        p5.prototype.saveJSON(args[0], args[1], args[2]);\n        break;\n      case 'txt':\n        p5.prototype.saveStrings(args[0], args[1], args[2]);\n        break;\n      default:\n        if (args[0] instanceof Array) {\n          p5.prototype.saveStrings(args[0], args[1], args[2]);\n        } else if (args[0] instanceof p5.Table) {\n          p5.prototype.saveTable(args[0], args[1], args[2], args[3]);\n        } else if (args[0] instanceof p5.Image) {\n          p5.prototype.saveCanvas(args[0].canvas, args[1]);\n        } else if (args[0] instanceof p5.SoundFile) {\n          p5.prototype.saveSound(args[0], args[1], args[2], args[3]);\n        } else if (args[0] instanceof Object) {\n          p5.prototype.saveJSON(args[0], args[1], args[2]);\n        }\n      }\n    }\n  };\n  p5.prototype.saveJSON = function (json, filename, opt) {\n    var stringify;\n    if (opt) {\n      stringify = JSON.stringify(json);\n    } else {\n      stringify = JSON.stringify(json, undefined, 2);\n    }\n    this.saveStrings(stringify.split('\\n'), filename, 'json');\n  };\n  p5.prototype.saveJSONObject = p5.prototype.saveJSON;\n  p5.prototype.saveJSONArray = p5.prototype.saveJSON;\n  p5.prototype.saveStream = function () {\n    throw 'not yet implemented';\n  };\n  p5.prototype.saveStrings = function (list, filename, extension) {\n    var ext = extension || 'txt';\n    var pWriter = this.createWriter(filename, ext);\n    for (var i in list) {\n      if (i < list.length - 1) {\n        pWriter.println(list[i]);\n      } else {\n        pWriter.print(list[i]);\n      }\n    }\n    pWriter.close();\n    pWriter.flush();\n  };\n  p5.prototype.saveXML = function () {\n    throw 'not yet implemented';\n  };\n  p5.prototype.selectOutput = function () {\n    throw 'not yet implemented';\n  };\n  p5.prototype.saveTable = function (table, filename, options) {\n    var pWriter = this.createWriter(filename, options);\n    var header = table.columns;\n    var sep = ',';\n    if (options === 'tsv') {\n      sep = '\\t';\n    }\n    if (options !== 'html') {\n      if (header[0] !== '0') {\n        for (var h = 0; h < header.length; h++) {\n          if (h < header.length - 1) {\n            pWriter.print(header[h] + sep);\n          } else {\n            pWriter.println(header[h]);\n          }\n        }\n      }\n      for (var i = 0; i < table.rows.length; i++) {\n        var j;\n        for (j = 0; j < table.rows[i].arr.length; j++) {\n          if (j < table.rows[i].arr.length - 1) {\n            pWriter.print(table.rows[i].arr[j] + sep);\n          } else if (i < table.rows.length - 1) {\n            pWriter.println(table.rows[i].arr[j]);\n          } else {\n            pWriter.print(table.rows[i].arr[j]);\n          }\n        }\n      }\n    } else {\n      pWriter.println('<html>');\n      pWriter.println('<head>');\n      var str = '  <meta http-equiv=\"content-type\" content';\n      str += '=\"text/html;charset=utf-8\" />';\n      pWriter.println(str);\n      pWriter.println('</head>');\n      pWriter.println('<body>');\n      pWriter.println('  <table>');\n      if (header[0] !== '0') {\n        pWriter.println('    <tr>');\n        for (var k = 0; k < header.length; k++) {\n          var e = escapeHelper(header[k]);\n          pWriter.println('      <td>' + e);\n          pWriter.println('      </td>');\n        }\n        pWriter.println('    </tr>');\n      }\n      for (var row = 0; row < table.rows.length; row++) {\n        pWriter.println('    <tr>');\n        for (var col = 0; col < table.columns.length; col++) {\n          var entry = table.rows[row].getString(col);\n          var htmlEntry = escapeHelper(entry);\n          pWriter.println('      <td>' + htmlEntry);\n          pWriter.println('      </td>');\n        }\n        pWriter.println('    </tr>');\n      }\n      pWriter.println('  </table>');\n      pWriter.println('</body>');\n      pWriter.print('</html>');\n    }\n    pWriter.close();\n    pWriter.flush();\n  };\n  var escapeHelper = function (content) {\n    return content.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;').replace(/'/g, '&#039;');\n  };\n  p5.prototype.writeFile = function (dataToDownload, filename, extension) {\n    var type = 'application/octet-stream';\n    if (p5.prototype._isSafari()) {\n      type = 'text/plain';\n    }\n    var blob = new Blob(dataToDownload, { 'type': type });\n    var href = window.URL.createObjectURL(blob);\n    p5.prototype.downloadFile(href, filename, extension);\n  };\n  p5.prototype.downloadFile = function (href, fName, extension) {\n    var fx = _checkFileExtension(fName, extension);\n    var filename = fx[0];\n    var ext = fx[1];\n    var a = document.createElement('a');\n    a.href = href;\n    a.download = filename;\n    a.onclick = destroyClickedElement;\n    a.style.display = 'none';\n    document.body.appendChild(a);\n    if (p5.prototype._isSafari()) {\n      var aText = 'Hello, Safari user! To download this file...\\n';\n      aText += '1. Go to File --> Save As.\\n';\n      aText += '2. Choose \"Page Source\" as the Format.\\n';\n      aText += '3. Name it with this extension: .\"' + ext + '\"';\n      alert(aText);\n    }\n    a.click();\n    href = null;\n  };\n  function _checkFileExtension(filename, extension) {\n    if (!extension) {\n      extension = '';\n    }\n    if (!filename) {\n      filename = 'untitled';\n    }\n    var ext = '';\n    if (filename && filename.indexOf('.') > -1) {\n      ext = filename.split('.').pop();\n    }\n    if (extension) {\n      if (ext !== extension) {\n        ext = extension;\n        filename = filename + '.' + ext;\n      }\n    }\n    return [\n      filename,\n      ext\n    ];\n  }\n  p5.prototype._checkFileExtension = _checkFileExtension;\n  p5.prototype._isSafari = function () {\n    var x = Object.prototype.toString.call(window.HTMLElement);\n    return x.indexOf('Constructor') > 0;\n  };\n  function destroyClickedElement(event) {\n    document.body.removeChild(event.target);\n  }\n  return p5;\n}({}, amdclean['core']);\namdclean['outputimage'] = function (require, core) {\n  'use strict';\n  var p5 = core;\n  var frames = [];\n  p5.prototype.saveCanvas = function (_cnv, filename, extension) {\n    if (!extension) {\n      extension = p5.prototype._checkFileExtension(filename, extension)[1];\n      if (extension === '') {\n        extension = 'png';\n      }\n    }\n    var cnv;\n    if (_cnv) {\n      cnv = _cnv;\n    } else if (this._curElement && this._curElement.elt) {\n      cnv = this._curElement.elt;\n    }\n    if (p5.prototype._isSafari()) {\n      var aText = 'Hello, Safari user!\\n';\n      aText += 'Now capturing a screenshot...\\n';\n      aText += 'To save this image,\\n';\n      aText += 'go to File --> Save As.\\n';\n      alert(aText);\n      window.location.href = cnv.toDataURL();\n    } else {\n      var mimeType;\n      if (typeof extension === 'undefined') {\n        extension = 'png';\n        mimeType = 'image/png';\n      } else {\n        switch (extension) {\n        case 'png':\n          mimeType = 'image/png';\n          break;\n        case 'jpeg':\n          mimeType = 'image/jpeg';\n          break;\n        case 'jpg':\n          mimeType = 'image/jpeg';\n          break;\n        default:\n          mimeType = 'image/png';\n          break;\n        }\n      }\n      var downloadMime = 'image/octet-stream';\n      var imageData = cnv.toDataURL(mimeType);\n      imageData = imageData.replace(mimeType, downloadMime);\n      p5.prototype.downloadFile(imageData, filename, extension);\n    }\n  };\n  p5.prototype.saveFrames = function (fName, ext, _duration, _fps, callback) {\n    var duration = _duration || 3;\n    duration = p5.prototype.constrain(duration, 0, 15);\n    duration = duration * 1000;\n    var fps = _fps || 15;\n    fps = p5.prototype.constrain(fps, 0, 22);\n    var count = 0;\n    var makeFrame = p5.prototype._makeFrame;\n    var cnv = this._curElement.elt;\n    var frameFactory = setInterval(function () {\n        makeFrame(fName + count, ext, cnv);\n        count++;\n      }, 1000 / fps);\n    setTimeout(function () {\n      clearInterval(frameFactory);\n      if (callback) {\n        callback(frames);\n      } else {\n        for (var i = 0; i < frames.length; i++) {\n          var f = frames[i];\n          p5.prototype.downloadFile(f.imageData, f.filename, f.ext);\n        }\n      }\n      frames = [];\n    }, duration + 0.01);\n  };\n  p5.prototype._makeFrame = function (filename, extension, _cnv) {\n    var cnv;\n    if (this) {\n      cnv = this._curElement.elt;\n    } else {\n      cnv = _cnv;\n    }\n    var mimeType;\n    if (!extension) {\n      extension = 'png';\n      mimeType = 'image/png';\n    } else {\n      switch (extension.toLowerCase()) {\n      case 'png':\n        mimeType = 'image/png';\n        break;\n      case 'jpeg':\n        mimeType = 'image/jpeg';\n        break;\n      case 'jpg':\n        mimeType = 'image/jpeg';\n        break;\n      default:\n        mimeType = 'image/png';\n        break;\n      }\n    }\n    var downloadMime = 'image/octet-stream';\n    var imageData = cnv.toDataURL(mimeType);\n    imageData = imageData.replace(mimeType, downloadMime);\n    var thisFrame = {};\n    thisFrame.imageData = imageData;\n    thisFrame.filename = filename;\n    thisFrame.ext = extension;\n    frames.push(thisFrame);\n  };\n  return p5;\n}({}, amdclean['core']);\namdclean['outputtext_area'] = function (require, core) {\n  'use strict';\n  var p5 = core;\n  if (window.console && console.log) {\n    p5.prototype.print = console.log.bind(console);\n  } else {\n    p5.prototype.print = function () {\n    };\n  }\n  p5.prototype.println = p5.prototype.print;\n  return p5;\n}({}, amdclean['core']);\namdclean['renderingrendering'] = function (require, core, constants) {\n  var p5 = core;\n  var constants = constants;\n  p5.prototype.createCanvas = function (w, h, isDefault) {\n    var c;\n    if (isDefault) {\n      c = document.createElement('canvas');\n      c.id = 'defaultCanvas';\n    } else {\n      c = this.canvas;\n    }\n    if (!this._setupDone) {\n      c.className += ' p5_hidden';\n      c.style.visibility = 'hidden';\n    }\n    if (this._userNode) {\n      this._userNode.appendChild(c);\n    } else {\n      document.body.appendChild(c);\n    }\n    if (!this._defaultGraphics) {\n      this._defaultGraphics = new p5.Graphics(c, this, true);\n      this._elements.push(this._defaultGraphics);\n    }\n    this._defaultGraphics.resize(w, h);\n    this._defaultGraphics._applyDefaults();\n    return this._defaultGraphics;\n  };\n  p5.prototype.resizeCanvas = function (w, h, noRedraw) {\n    if (this._defaultGraphics) {\n      this._defaultGraphics.resize(w, h);\n      this._defaultGraphics._applyDefaults();\n      if (!noRedraw) {\n        this.redraw();\n      }\n    }\n  };\n  p5.prototype.noCanvas = function () {\n    if (this.canvas) {\n      this.canvas.parentNode.removeChild(this.canvas);\n    }\n  };\n  p5.prototype.createGraphics = function (w, h) {\n    var c = document.createElement('canvas');\n    var node = this._userNode || document.body;\n    node.appendChild(c);\n    var pg = new p5.Graphics(c, this, false);\n    this._elements.push(pg);\n    for (var p in p5.prototype) {\n      if (!pg.hasOwnProperty(p)) {\n        if (typeof p5.prototype[p] === 'function') {\n          pg[p] = p5.prototype[p].bind(pg);\n        } else {\n          pg[p] = p5.prototype[p];\n        }\n      }\n    }\n    pg.resize(w, h);\n    pg._applyDefaults();\n    return pg;\n  };\n  p5.prototype.blendMode = function (mode) {\n    if (mode === constants.BLEND || mode === constants.DARKEST || mode === constants.LIGHTEST || mode === constants.DIFFERENCE || mode === constants.MULTIPLY || mode === constants.EXCLUSION || mode === constants.SCREEN || mode === constants.REPLACE || mode === constants.OVERLAY || mode === constants.HARD_LIGHT || mode === constants.SOFT_LIGHT || mode === constants.DODGE || mode === constants.BURN || mode === constants.ADD || mode === constants.NORMAL) {\n      this.drawingContext.globalCompositeOperation = mode;\n    } else {\n      throw new Error('Mode ' + mode + ' not recognized.');\n    }\n  };\n  return p5;\n}({}, amdclean['core'], amdclean['constants']);\namdclean['shape2d_primitives'] = function (require, core, canvas, constants) {\n  'use strict';\n  var p5 = core;\n  var canvas = canvas;\n  var constants = constants;\n  var EPSILON = 0.00001;\n  function createArc(radius, startAngle, endAngle) {\n    var twoPI = Math.PI * 2;\n    var curves = [];\n    var piOverTwo = Math.PI / 2;\n    var sgn = startAngle < endAngle ? 1 : -1;\n    var a1 = startAngle;\n    var totalAngle = Math.min(twoPI, Math.abs(endAngle - startAngle));\n    for (; totalAngle > EPSILON;) {\n      var a2 = a1 + sgn * Math.min(totalAngle, piOverTwo);\n      curves.push(createSmallArc(radius, a1, a2));\n      totalAngle -= Math.abs(a2 - a1);\n      a1 = a2;\n    }\n    return curves;\n  }\n  function createSmallArc(r, a1, a2) {\n    var a = (a2 - a1) / 2;\n    var x4 = r * Math.cos(a);\n    var y4 = r * Math.sin(a);\n    var x1 = x4;\n    var y1 = -y4;\n    var k = 0.5522847498;\n    var f = k * Math.tan(a);\n    var x2 = x1 + f * y4;\n    var y2 = y1 + f * x4;\n    var x3 = x2;\n    var y3 = -y2;\n    var ar = a + a1;\n    var cos_ar = Math.cos(ar);\n    var sin_ar = Math.sin(ar);\n    return {\n      x1: r * Math.cos(a1),\n      y1: r * Math.sin(a1),\n      x2: x2 * cos_ar - y2 * sin_ar,\n      y2: x2 * sin_ar + y2 * cos_ar,\n      x3: x3 * cos_ar - y3 * sin_ar,\n      y3: x3 * sin_ar + y3 * cos_ar,\n      x4: r * Math.cos(a2),\n      y4: r * Math.sin(a2)\n    };\n  }\n  p5.prototype.arc = function (x, y, width, height, start, stop, mode) {\n    if (!this._doStroke && !this._doFill) {\n      return;\n    }\n    if (this._angleMode === constants.DEGREES) {\n      start = this.radians(start);\n      stop = this.radians(stop);\n    }\n    var ctx = this.drawingContext;\n    var vals = canvas.arcModeAdjust(x, y, width, height, this._ellipseMode);\n    var curves = createArc(1, start, stop);\n    var rx = vals.w / 2;\n    var ry = vals.h / 2;\n    ctx.beginPath();\n    curves.forEach(function (curve, index) {\n      if (index === 0) {\n        ctx.moveTo(vals.x + curve.x1 * rx, vals.y + curve.y1 * ry);\n      }\n      ctx.bezierCurveTo(vals.x + curve.x2 * rx, vals.y + curve.y2 * ry, vals.x + curve.x3 * rx, vals.y + curve.y3 * ry, vals.x + curve.x4 * rx, vals.y + curve.y4 * ry);\n    });\n    if (this._doFill) {\n      if (mode === constants.PIE || mode == null) {\n        ctx.lineTo(vals.x, vals.y);\n      }\n      ctx.closePath();\n      ctx.fill();\n      if (this._doStroke) {\n        if (mode === constants.CHORD || mode === constants.PIE) {\n          ctx.stroke();\n          return this;\n        }\n      }\n    }\n    if (this._doStroke) {\n      if (mode === constants.OPEN || mode == null) {\n        ctx.beginPath();\n        curves.forEach(function (curve, index) {\n          if (index === 0) {\n            ctx.moveTo(vals.x + curve.x1 * rx, vals.y + curve.y1 * ry);\n          }\n          ctx.bezierCurveTo(vals.x + curve.x2 * rx, vals.y + curve.y2 * ry, vals.x + curve.x3 * rx, vals.y + curve.y3 * ry, vals.x + curve.x4 * rx, vals.y + curve.y4 * ry);\n        });\n        ctx.stroke();\n      }\n    }\n    return this;\n  };\n  p5.prototype.ellipse = function (x, y, w, h) {\n    if (!this._doStroke && !this._doFill) {\n      return;\n    }\n    w = Math.abs(w);\n    h = Math.abs(h);\n    var ctx = this.drawingContext;\n    var vals = canvas.modeAdjust(x, y, w, h, this._ellipseMode);\n    ctx.beginPath();\n    if (w === h) {\n      ctx.arc(vals.x + vals.w / 2, vals.y + vals.w / 2, vals.w / 2, 0, 2 * Math.PI, false);\n    } else {\n      var kappa = 0.5522848, ox = vals.w / 2 * kappa, oy = vals.h / 2 * kappa, xe = vals.x + vals.w, ye = vals.y + vals.h, xm = vals.x + vals.w / 2, ym = vals.y + vals.h / 2;\n      ctx.moveTo(vals.x, ym);\n      ctx.bezierCurveTo(vals.x, ym - oy, xm - ox, vals.y, xm, vals.y);\n      ctx.bezierCurveTo(xm + ox, vals.y, xe, ym - oy, xe, ym);\n      ctx.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye);\n      ctx.bezierCurveTo(xm - ox, ye, vals.x, ym + oy, vals.x, ym);\n      ctx.closePath();\n    }\n    if (this._doFill) {\n      ctx.fill();\n    }\n    if (this._doStroke) {\n      ctx.stroke();\n    }\n    return this;\n  };\n  p5.prototype.line = function (x1, y1, x2, y2) {\n    if (!this._doStroke) {\n      return;\n    }\n    var ctx = this.drawingContext;\n    if (ctx.strokeStyle === 'rgba(0,0,0,0)') {\n      return;\n    }\n    ctx.beginPath();\n    ctx.moveTo(x1, y1);\n    ctx.lineTo(x2, y2);\n    ctx.stroke();\n    return this;\n  };\n  p5.prototype.point = function (x, y) {\n    if (!this._doStroke) {\n      return;\n    }\n    var ctx = this.drawingContext;\n    var s = ctx.strokeStyle;\n    var f = ctx.fillStyle;\n    if (s === 'rgba(0,0,0,0)') {\n      return;\n    }\n    x = Math.round(x);\n    y = Math.round(y);\n    ctx.fillStyle = s;\n    if (ctx.lineWidth > 1) {\n      ctx.beginPath();\n      ctx.arc(x, y, ctx.lineWidth / 2, 0, constants.TWO_PI, false);\n      ctx.fill();\n    } else {\n      ctx.fillRect(x, y, 1, 1);\n    }\n    ctx.fillStyle = f;\n    return this;\n  };\n  p5.prototype.quad = function (x1, y1, x2, y2, x3, y3, x4, y4) {\n    if (!this._doStroke && !this._doFill) {\n      return;\n    }\n    var ctx = this.drawingContext;\n    ctx.beginPath();\n    ctx.moveTo(x1, y1);\n    ctx.lineTo(x2, y2);\n    ctx.lineTo(x3, y3);\n    ctx.lineTo(x4, y4);\n    ctx.closePath();\n    if (this._doFill) {\n      ctx.fill();\n    }\n    if (this._doStroke) {\n      ctx.stroke();\n    }\n    return this;\n  };\n  p5.prototype.rect = function (a, b, c, d) {\n    if (!this._doStroke && !this._doFill) {\n      return;\n    }\n    var vals = canvas.modeAdjust(a, b, c, d, this._rectMode);\n    var ctx = this.drawingContext;\n    if (this._doStroke && ctx.lineWidth % 2 === 1) {\n      ctx.translate(0.5, 0.5);\n    }\n    ctx.beginPath();\n    ctx.rect(vals.x, vals.y, vals.w, vals.h);\n    if (this._doFill) {\n      ctx.fill();\n    }\n    if (this._doStroke) {\n      ctx.stroke();\n    }\n    if (this._doStroke && ctx.lineWidth % 2 === 1) {\n      ctx.translate(-0.5, -0.5);\n    }\n    return this;\n  };\n  p5.prototype.triangle = function (x1, y1, x2, y2, x3, y3) {\n    if (!this._doStroke && !this._doFill) {\n      return;\n    }\n    var ctx = this.drawingContext;\n    ctx.beginPath();\n    ctx.moveTo(x1, y1);\n    ctx.lineTo(x2, y2);\n    ctx.lineTo(x3, y3);\n    ctx.closePath();\n    if (this._doFill) {\n      ctx.fill();\n    }\n    if (this._doStroke) {\n      ctx.stroke();\n    }\n    return this;\n  };\n  return p5;\n}({}, amdclean['core'], amdclean['canvas'], amdclean['constants']);\namdclean['shapeattributes'] = function (require, core, constants) {\n  'use strict';\n  var p5 = core;\n  var constants = constants;\n  p5.prototype._rectMode = constants.CORNER;\n  p5.prototype._ellipseMode = constants.CENTER;\n  p5.prototype.ellipseMode = function (m) {\n    if (m === constants.CORNER || m === constants.CORNERS || m === constants.RADIUS || m === constants.CENTER) {\n      this._ellipseMode = m;\n    }\n    return this;\n  };\n  p5.prototype.noSmooth = function () {\n    this.drawingContext.mozImageSmoothingEnabled = false;\n    this.drawingContext.webkitImageSmoothingEnabled = false;\n    return this;\n  };\n  p5.prototype.rectMode = function (m) {\n    if (m === constants.CORNER || m === constants.CORNERS || m === constants.RADIUS || m === constants.CENTER) {\n      this._rectMode = m;\n    }\n    return this;\n  };\n  p5.prototype.smooth = function () {\n    this.drawingContext.mozImageSmoothingEnabled = true;\n    this.drawingContext.webkitImageSmoothingEnabled = true;\n    return this;\n  };\n  p5.prototype.strokeCap = function (cap) {\n    if (cap === constants.ROUND || cap === constants.SQUARE || cap === constants.PROJECT) {\n      this.drawingContext.lineCap = cap;\n    }\n    return this;\n  };\n  p5.prototype.strokeJoin = function (join) {\n    if (join === constants.ROUND || join === constants.BEVEL || join === constants.MITER) {\n      this.drawingContext.lineJoin = join;\n    }\n    return this;\n  };\n  p5.prototype.strokeWeight = function (w) {\n    if (typeof w === 'undefined' || w === 0) {\n      this.drawingContext.lineWidth = 0.0001;\n    } else {\n      this.drawingContext.lineWidth = w;\n    }\n    return this;\n  };\n  return p5;\n}({}, amdclean['core'], amdclean['constants']);\namdclean['shapecurves'] = function (require, core) {\n  'use strict';\n  var p5 = core;\n  var bezierDetail = 20;\n  var curveDetail = 20;\n  p5.prototype._curveTightness = 0;\n  p5.prototype.bezier = function (x1, y1, x2, y2, x3, y3, x4, y4) {\n    if (!this._doStroke) {\n      return;\n    }\n    this.beginShape();\n    this.vertex(x1, y1);\n    this.bezierVertex(x2, y2, x3, y3, x4, y4);\n    this.endShape();\n    this.stroke();\n    return this;\n  };\n  p5.prototype.bezierDetail = function (d) {\n    bezierDetail = d;\n    return this;\n  };\n  p5.prototype.bezierPoint = function (a, b, c, d, t) {\n    var adjustedT = 1 - t;\n    return Math.pow(adjustedT, 3) * a + 3 * Math.pow(adjustedT, 2) * t * b + 3 * adjustedT * Math.pow(t, 2) * c + Math.pow(t, 3) * d;\n  };\n  p5.prototype.bezierTangent = function (a, b, c, d, t) {\n    var adjustedT = 1 - t;\n    return 3 * d * Math.pow(t, 2) - 3 * c * Math.pow(t, 2) + 6 * c * adjustedT * t - 6 * b * adjustedT * t + 3 * b * Math.pow(adjustedT, 2) - 3 * a * Math.pow(adjustedT, 2);\n  };\n  p5.prototype.curve = function (x1, y1, x2, y2, x3, y3, x4, y4) {\n    if (!this._doStroke) {\n      return;\n    }\n    this.beginShape();\n    this.curveVertex(x1, y1);\n    this.curveVertex(x2, y2);\n    this.curveVertex(x3, y3);\n    this.curveVertex(x4, y4);\n    this.endShape();\n    this.stroke();\n    return this;\n  };\n  p5.prototype.curveDetail = function (d) {\n    curveDetail = d;\n    return this;\n  };\n  p5.prototype.curveTightness = function (t) {\n    this._setProperty('_curveTightness', t);\n  };\n  p5.prototype.curvePoint = function (a, b, c, d, t) {\n    var t3 = t * t * t, t2 = t * t, f1 = -0.5 * t3 + t2 - 0.5 * t, f2 = 1.5 * t3 - 2.5 * t2 + 1, f3 = -1.5 * t3 + 2 * t2 + 0.5 * t, f4 = 0.5 * t3 - 0.5 * t2;\n    return a * f1 + b * f2 + c * f3 + d * f4;\n  };\n  p5.prototype.curveTangent = function (a, b, c, d, t) {\n    var t2 = t * t, f1 = -3 * t2 / 2 + 2 * t - 0.5, f2 = 9 * t2 / 2 - 5 * t, f3 = -9 * t2 / 2 + 4 * t + 0.5, f4 = 3 * t2 / 2 - t;\n    return a * f1 + b * f2 + c * f3 + d * f4;\n  };\n  p5.prototype.curveTightness = function () {\n    throw 'not yet implemented';\n  };\n  return p5;\n}({}, amdclean['core']);\namdclean['shapevertex'] = function (require, core, constants) {\n  'use strict';\n  var p5 = core;\n  var constants = constants;\n  var shapeKind = null;\n  var vertices = [];\n  var contourVertices = [];\n  var isBezier = false;\n  var isCurve = false;\n  var isQuadratic = false;\n  var isContour = false;\n  p5.prototype._doFillStrokeClose = function () {\n    if (this._doFill) {\n      this.drawingContext.fill();\n    }\n    if (this._doStroke) {\n      this.drawingContext.stroke();\n    }\n    this.drawingContext.closePath();\n  };\n  p5.prototype.beginContour = function () {\n    contourVertices = [];\n    isContour = true;\n    return this;\n  };\n  p5.prototype.beginShape = function (kind) {\n    if (kind === constants.POINTS || kind === constants.LINES || kind === constants.TRIANGLES || kind === constants.TRIANGLE_FAN || kind === constants.TRIANGLE_STRIP || kind === constants.QUADS || kind === constants.QUAD_STRIP) {\n      shapeKind = kind;\n    } else {\n      shapeKind = null;\n    }\n    vertices = [];\n    contourVertices = [];\n    return this;\n  };\n  p5.prototype.bezierVertex = function (x2, y2, x3, y3, x4, y4) {\n    if (vertices.length === 0) {\n      throw 'vertex() must be used once before calling bezierVertex()';\n    } else {\n      isBezier = true;\n      var vert = [];\n      for (var i = 0; i < arguments.length; i++) {\n        vert[i] = arguments[i];\n      }\n      vert.isVert = false;\n      if (isContour) {\n        contourVertices.push(vert);\n      } else {\n        vertices.push(vert);\n      }\n    }\n    return this;\n  };\n  p5.prototype.curveVertex = function (x, y) {\n    isCurve = true;\n    this.vertex(x, y);\n    return this;\n  };\n  p5.prototype.endContour = function () {\n    var vert = contourVertices[0].slice();\n    vert.isVert = contourVertices[0].isVert;\n    vert.moveTo = false;\n    contourVertices.push(vert);\n    vertices.push(vertices[0]);\n    for (var i = 0; i < contourVertices.length; i++) {\n      vertices.push(contourVertices[i]);\n    }\n    return this;\n  };\n  p5.prototype.endShape = function (mode) {\n    if (vertices.length === 0) {\n      return this;\n    }\n    if (!this._doStroke && !this._doFill) {\n      return this;\n    }\n    var closeShape = mode === constants.CLOSE;\n    var v;\n    if (closeShape && !isContour) {\n      vertices.push(vertices[0]);\n    }\n    var i, j;\n    var numVerts = vertices.length;\n    if (isCurve && (shapeKind === constants.POLYGON || shapeKind === null)) {\n      if (numVerts > 3) {\n        var b = [], s = 1 - this._curveTightness;\n        this.drawingContext.beginPath();\n        this.drawingContext.moveTo(vertices[1][0], vertices[1][1]);\n        for (i = 1; i + 2 < numVerts; i++) {\n          v = vertices[i];\n          b[0] = [\n            v[0],\n            v[1]\n          ];\n          b[1] = [\n            v[0] + (s * vertices[i + 1][0] - s * vertices[i - 1][0]) / 6,\n            v[1] + (s * vertices[i + 1][1] - s * vertices[i - 1][1]) / 6\n          ];\n          b[2] = [\n            vertices[i + 1][0] + (s * vertices[i][0] - s * vertices[i + 2][0]) / 6,\n            vertices[i + 1][1] + (s * vertices[i][1] - s * vertices[i + 2][1]) / 6\n          ];\n          b[3] = [\n            vertices[i + 1][0],\n            vertices[i + 1][1]\n          ];\n          this.drawingContext.bezierCurveTo(b[1][0], b[1][1], b[2][0], b[2][1], b[3][0], b[3][1]);\n        }\n        if (closeShape) {\n          this.drawingContext.lineTo(vertices[i + 1][0], vertices[i + 1][1]);\n        }\n        this._doFillStrokeClose();\n      }\n    } else if (isBezier && (shapeKind === constants.POLYGON || shapeKind === null)) {\n      this.drawingContext.beginPath();\n      for (i = 0; i < numVerts; i++) {\n        if (vertices[i].isVert) {\n          if (vertices[i].moveTo) {\n            this.drawingContext.moveTo(vertices[i][0], vertices[i][1]);\n          } else {\n            this.drawingContext.lineTo(vertices[i][0], vertices[i][1]);\n          }\n        } else {\n          this.drawingContext.bezierCurveTo(vertices[i][0], vertices[i][1], vertices[i][2], vertices[i][3], vertices[i][4], vertices[i][5]);\n        }\n      }\n      this._doFillStrokeClose();\n    } else if (isQuadratic && (shapeKind === constants.POLYGON || shapeKind === null)) {\n      this.drawingContext.beginPath();\n      for (i = 0; i < numVerts; i++) {\n        if (vertices[i].isVert) {\n          if (vertices[i].moveTo) {\n            this.drawingContext.moveTo([0], vertices[i][1]);\n          } else {\n            this.drawingContext.lineTo(vertices[i][0], vertices[i][1]);\n          }\n        } else {\n          this.drawingContext.quadraticCurveTo(vertices[i][0], vertices[i][1], vertices[i][2], vertices[i][3]);\n        }\n      }\n      this._doFillStrokeClose();\n    } else {\n      if (shapeKind === constants.POINTS) {\n        for (i = 0; i < numVerts; i++) {\n          v = vertices[i];\n          if (this._doStroke) {\n            this.stroke(v[6]);\n          }\n          this.point(v[0], v[1]);\n        }\n      } else if (shapeKind === constants.LINES) {\n        for (i = 0; i + 1 < numVerts; i += 2) {\n          v = vertices[i];\n          if (this._doStroke) {\n            this.stroke(vertices[i + 1][6]);\n          }\n          this.line(v[0], v[1], vertices[i + 1][0], vertices[i + 1][1]);\n        }\n      } else if (shapeKind === constants.TRIANGLES) {\n        for (i = 0; i + 2 < numVerts; i += 3) {\n          v = vertices[i];\n          this.drawingContext.beginPath();\n          this.drawingContext.moveTo(v[0], v[1]);\n          this.drawingContext.lineTo(vertices[i + 1][0], vertices[i + 1][1]);\n          this.drawingContext.lineTo(vertices[i + 2][0], vertices[i + 2][1]);\n          this.drawingContext.lineTo(v[0], v[1]);\n          if (this._doFill) {\n            this.fill(vertices[i + 2][5]);\n            this.drawingContext.fill();\n          }\n          if (this._doStroke) {\n            this.stroke(vertices[i + 2][6]);\n            this.drawingContext.stroke();\n          }\n          this.drawingContext.closePath();\n        }\n      } else if (shapeKind === constants.TRIANGLE_STRIP) {\n        for (i = 0; i + 1 < numVerts; i++) {\n          v = vertices[i];\n          this.drawingContext.beginPath();\n          this.drawingContext.moveTo(vertices[i + 1][0], vertices[i + 1][1]);\n          this.drawingContext.lineTo(v[0], v[1]);\n          if (this._doStroke) {\n            this.stroke(vertices[i + 1][6]);\n          }\n          if (this._doFill) {\n            this.fill(vertices[i + 1][5]);\n          }\n          if (i + 2 < numVerts) {\n            this.drawingContext.lineTo(vertices[i + 2][0], vertices[i + 2][1]);\n            if (this._doStroke) {\n              this.stroke(vertices[i + 2][6]);\n            }\n            if (this._doFill) {\n              this.fill(vertices[i + 2][5]);\n            }\n          }\n          this._doFillStrokeClose();\n        }\n      } else if (shapeKind === constants.TRIANGLE_FAN) {\n        if (numVerts > 2) {\n          this.drawingContext.beginPath();\n          this.drawingContext.moveTo(vertices[0][0], vertices[0][1]);\n          this.drawingContext.lineTo(vertices[1][0], vertices[1][1]);\n          this.drawingContext.lineTo(vertices[2][0], vertices[2][1]);\n          if (this._doFill) {\n            this.fill(vertices[2][5]);\n          }\n          if (this._doStroke) {\n            this.stroke(vertices[2][6]);\n          }\n          this._doFillStrokeClose();\n          for (i = 3; i < numVerts; i++) {\n            v = vertices[i];\n            this.drawingContext.beginPath();\n            this.drawingContext.moveTo(vertices[0][0], vertices[0][1]);\n            this.drawingContext.lineTo(vertices[i - 1][0], vertices[i - 1][1]);\n            this.drawingContext.lineTo(v[0], v[1]);\n            if (this._doFill) {\n              this.fill(v[5]);\n            }\n            if (this._doStroke) {\n              this.stroke(v[6]);\n            }\n            this._doFillStrokeClose();\n          }\n        }\n      } else if (shapeKind === constants.QUADS) {\n        for (i = 0; i + 3 < numVerts; i += 4) {\n          v = vertices[i];\n          this.drawingContext.beginPath();\n          this.drawingContext.moveTo(v[0], v[1]);\n          for (j = 1; j < 4; j++) {\n            this.drawingContext.lineTo(vertices[i + j][0], vertices[i + j][1]);\n          }\n          this.drawingContext.lineTo(v[0], v[1]);\n          if (this._doFill) {\n            this.fill(vertices[i + 3][5]);\n          }\n          if (this._doStroke) {\n            this.stroke(vertices[i + 3][6]);\n          }\n          this._doFillStrokeClose();\n        }\n      } else if (shapeKind === constants.QUAD_STRIP) {\n        if (numVerts > 3) {\n          for (i = 0; i + 1 < numVerts; i += 2) {\n            v = vertices[i];\n            this.drawingContext.beginPath();\n            if (i + 3 < numVerts) {\n              this.drawingContext.moveTo(vertices[i + 2][0], vertices[i + 2][1]);\n              this.drawingContext.lineTo(v[0], v[1]);\n              this.drawingContext.lineTo(vertices[i + 1][0], vertices[i + 1][1]);\n              this.drawingContext.lineTo(vertices[i + 3][0], vertices[i + 3][1]);\n              if (this._doFill) {\n                this.fill(vertices[i + 3][5]);\n              }\n              if (this._doStroke) {\n                this.stroke(vertices[i + 3][6]);\n              }\n            } else {\n              this.drawingContext.moveTo(v[0], v[1]);\n              this.drawingContext.lineTo(vertices[i + 1][0], vertices[i + 1][1]);\n            }\n            this._doFillStrokeClose();\n          }\n        }\n      } else {\n        this.drawingContext.beginPath();\n        this.drawingContext.moveTo(vertices[0][0], vertices[0][1]);\n        for (i = 1; i < numVerts; i++) {\n          v = vertices[i];\n          if (v.isVert) {\n            if (v.moveTo) {\n              this.drawingContext.moveTo(v[0], v[1]);\n            } else {\n              this.drawingContext.lineTo(v[0], v[1]);\n            }\n          }\n        }\n        this._doFillStrokeClose();\n      }\n    }\n    isCurve = false;\n    isBezier = false;\n    isQuadratic = false;\n    isContour = false;\n    if (closeShape) {\n      vertices.pop();\n    }\n    return this;\n  };\n  p5.prototype.quadraticVertex = function (cx, cy, x3, y3) {\n    if (this._contourInited) {\n      var pt = {};\n      pt.x = cx;\n      pt.y = cy;\n      pt.x3 = x3;\n      pt.y3 = y3;\n      pt.type = constants.QUADRATIC;\n      this._contourVertices.push(pt);\n      return this;\n    }\n    if (vertices.length > 0) {\n      isQuadratic = true;\n      var vert = [];\n      for (var i = 0; i < arguments.length; i++) {\n        vert[i] = arguments[i];\n      }\n      vert.isVert = false;\n      if (isContour) {\n        contourVertices.push(vert);\n      } else {\n        vertices.push(vert);\n      }\n    } else {\n      throw 'vertex() must be used once before calling quadraticVertex()';\n    }\n    return this;\n  };\n  p5.prototype.vertex = function (x, y, moveTo) {\n    var vert = [];\n    vert.isVert = true;\n    vert[0] = x;\n    vert[1] = y;\n    vert[2] = 0;\n    vert[3] = 0;\n    vert[4] = 0;\n    vert[5] = this.drawingContext.fillStyle;\n    vert[6] = this.drawingContext.strokeStyle;\n    if (moveTo) {\n      vert.moveTo = moveTo;\n    }\n    if (isContour) {\n      if (contourVertices.length === 0) {\n        vert.moveTo = true;\n      }\n      contourVertices.push(vert);\n    } else {\n      vertices.push(vert);\n    }\n    return this;\n  };\n  return p5;\n}({}, amdclean['core'], amdclean['constants']);\namdclean['structure'] = function (require, core) {\n  'use strict';\n  var p5 = core;\n  p5.prototype.exit = function () {\n    throw 'exit() not implemented, see remove()';\n  };\n  p5.prototype.noLoop = function () {\n    this._loop = false;\n    if (this._drawInterval) {\n      clearInterval(this._drawInterval);\n    }\n  };\n  p5.prototype.loop = function () {\n    this._loop = true;\n    this._draw();\n  };\n  p5.prototype.push = function () {\n    this.drawingContext.save();\n    this._styles.push({\n      doStroke: this._doStroke,\n      doFill: this._doFill,\n      tint: this._tint,\n      imageMode: this._imageMode,\n      rectMode: this._rectMode,\n      ellipseMode: this._ellipseMode,\n      colorMode: this._colorMode,\n      textFont: this.textFont,\n      textLeading: this.textLeading,\n      textSize: this.textSize,\n      textStyle: this.textStyle\n    });\n  };\n  p5.prototype.pop = function () {\n    this.drawingContext.restore();\n    var lastS = this._styles.pop();\n    this._doStroke = lastS.doStroke;\n    this._doFill = lastS.doFill;\n    this._tint = lastS.tint;\n    this._imageMode = lastS.imageMode;\n    this._rectMode = lastS.rectMode;\n    this._ellipseMode = lastS.ellipseMode;\n    this._colorMode = lastS.colorMode;\n    this.textFont = lastS.textFont;\n    this.textLeading = lastS.textLeading;\n    this.textSize = lastS.textSize;\n    this.textStyle = lastS.textStyle;\n  };\n  p5.prototype.pushStyle = function () {\n    throw new Error('pushStyle() not used, see push()');\n  };\n  p5.prototype.popStyle = function () {\n    throw new Error('popStyle() not used, see pop()');\n  };\n  p5.prototype.redraw = function () {\n    var userSetup = this.setup || window.setup;\n    var userDraw = this.draw || window.draw;\n    if (typeof userDraw === 'function') {\n      this.push();\n      if (typeof userSetup === 'undefined') {\n        this.scale(this._pixelDensity, this._pixelDensity);\n      }\n      this._registeredMethods.pre.forEach(function (f) {\n        f.call(this);\n      });\n      userDraw();\n      this._registeredMethods.post.forEach(function (f) {\n        f.call(this);\n      });\n      this.pop();\n    }\n  };\n  p5.prototype.size = function () {\n    throw 'size() not implemented, see createCanvas()';\n  };\n  return p5;\n}({}, amdclean['core']);\namdclean['transform'] = function (require, core, constants, outputtext_area) {\n  'use strict';\n  var p5 = core;\n  var constants = constants;\n  p5.prototype.applyMatrix = function (n00, n01, n02, n10, n11, n12) {\n    this.drawingContext.transform(n00, n01, n02, n10, n11, n12);\n    return this;\n  };\n  p5.prototype.popMatrix = function () {\n    throw new Error('popMatrix() not used, see pop()');\n  };\n  p5.prototype.printMatrix = function () {\n    throw new Error('printMatrix() not implemented');\n  };\n  p5.prototype.pushMatrix = function () {\n    throw new Error('pushMatrix() not used, see push()');\n  };\n  p5.prototype.resetMatrix = function () {\n    this.drawingContext.setTransform(1, 0, 0, 1, 0, 0);\n    return this;\n  };\n  p5.prototype.rotate = function (r) {\n    if (this._angleMode === constants.DEGREES) {\n      r = this.radians(r);\n    }\n    this.drawingContext.rotate(r);\n    return this;\n  };\n  p5.prototype.rotateX = function () {\n    throw 'not yet implemented';\n  };\n  p5.prototype.rotateY = function () {\n    throw 'not yet implemented';\n  };\n  p5.prototype.scale = function () {\n    var x = 1, y = 1;\n    if (arguments.length === 1) {\n      x = y = arguments[0];\n    } else {\n      x = arguments[0];\n      y = arguments[1];\n    }\n    this.drawingContext.scale(x, y);\n    return this;\n  };\n  p5.prototype.shearX = function (angle) {\n    if (this._angleMode === constants.DEGREES) {\n      angle = this.radians(angle);\n    }\n    this.drawingContext.transform(1, 0, this.tan(angle), 1, 0, 0);\n    return this;\n  };\n  p5.prototype.shearY = function (angle) {\n    if (this._angleMode === constants.DEGREES) {\n      angle = this.radians(angle);\n    }\n    this.drawingContext.transform(1, this.tan(angle), 0, 1, 0, 0);\n    return this;\n  };\n  p5.prototype.translate = function (x, y) {\n    this.drawingContext.translate(x, y);\n    return this;\n  };\n  return p5;\n}({}, amdclean['core'], amdclean['constants'], amdclean['outputtext_area']);\namdclean['typographyattributes'] = function (require, core, constants) {\n  'use strict';\n  var p5 = core;\n  var constants = constants;\n  p5.prototype._textLeading = 15;\n  p5.prototype._textFont = 'sans-serif';\n  p5.prototype._textSize = 12;\n  p5.prototype._textStyle = constants.NORMAL;\n  p5.prototype._textAscent = null;\n  p5.prototype._textDescent = null;\n  p5.prototype.textAlign = function (h, v) {\n    if (h === constants.LEFT || h === constants.RIGHT || h === constants.CENTER) {\n      this.drawingContext.textAlign = h;\n    }\n    if (v === constants.TOP || v === constants.BOTTOM || v === constants.CENTER || v === constants.BASELINE) {\n      this.drawingContext.textBaseline = v;\n    }\n  };\n  p5.prototype.textLeading = function (l) {\n    this._setProperty('_textLeading', l);\n  };\n  p5.prototype.textSize = function (s) {\n    this._setProperty('_textSize', s);\n    this._setProperty('_textLeading', s * 1.25);\n    this._applyTextProperties();\n  };\n  p5.prototype.textStyle = function (s) {\n    if (s === constants.NORMAL || s === constants.ITALIC || s === constants.BOLD) {\n      this._setProperty('_textStyle', s);\n      this._applyTextProperties();\n    }\n  };\n  p5.prototype.textWidth = function (s) {\n    return this.drawingContext.measureText(s).width;\n  };\n  p5.prototype.textAscent = function () {\n    if (this._textAscent == null) {\n      this._updateTextMetrics();\n    }\n    return this._textAscent;\n  };\n  p5.prototype.textDescent = function () {\n    if (this._textDescent == null) {\n      this._updateTextMetrics();\n    }\n    return this._textDescent;\n  };\n  p5.prototype._applyTextProperties = function () {\n    this._setProperty('_textAscent', null);\n    this._setProperty('_textDescent', null);\n    var str = this._textStyle + ' ' + this._textSize + 'px ' + this._textFont;\n    this.drawingContext.font = str;\n  };\n  p5.prototype._updateTextMetrics = function () {\n    var text = document.createElement('span');\n    text.style.fontFamily = this._textFont;\n    text.style.fontSize = this._textSize + 'px';\n    text.innerHTML = 'ABCjgq|';\n    var block = document.createElement('div');\n    block.style.display = 'inline-block';\n    block.style.width = '1px';\n    block.style.height = '0px';\n    var container = document.createElement('div');\n    container.appendChild(text);\n    container.appendChild(block);\n    container.style.height = '0px';\n    container.style.overflow = 'hidden';\n    document.body.appendChild(container);\n    block.style.verticalAlign = 'baseline';\n    var blockOffset = this._calculateOffset(block);\n    var textOffset = this._calculateOffset(text);\n    var ascent = blockOffset[1] - textOffset[1];\n    block.style.verticalAlign = 'bottom';\n    blockOffset = this._calculateOffset(block);\n    textOffset = this._calculateOffset(text);\n    var height = blockOffset[1] - textOffset[1];\n    var descent = height - ascent;\n    document.body.removeChild(container);\n    this._setProperty('_textAscent', ascent);\n    this._setProperty('_textDescent', descent);\n  };\n  p5.prototype._calculateOffset = function (object) {\n    var currentLeft = 0, currentTop = 0;\n    if (object.offsetParent) {\n      do {\n        currentLeft += object.offsetLeft;\n        currentTop += object.offsetTop;\n      } while (object = object.offsetParent);\n    } else {\n      currentLeft += object.offsetLeft;\n      currentTop += object.offsetTop;\n    }\n    return [\n      currentLeft,\n      currentTop\n    ];\n  };\n  return p5;\n}({}, amdclean['core'], amdclean['constants']);\namdclean['typographyloading_displaying'] = function (require, core) {\n  'use strict';\n  var p5 = core;\n  p5.prototype.text = function (str, x, y, maxWidth, maxHeight) {\n    if (typeof str === 'number') {\n      str = str.toString();\n    }\n    if (typeof str !== 'string') {\n      return;\n    }\n    if (typeof maxWidth !== 'undefined') {\n      y += this._textLeading;\n      maxHeight += y;\n    }\n    str = str.replace(/(\\t)/g, '  ');\n    var cars = str.split('\\n');\n    for (var ii = 0; ii < cars.length; ii++) {\n      var line = '';\n      var words = cars[ii].split(' ');\n      for (var n = 0; n < words.length; n++) {\n        if (y + this._textLeading <= maxHeight || typeof maxHeight === 'undefined') {\n          var testLine = line + words[n] + ' ';\n          var metrics = this.drawingContext.measureText(testLine);\n          var testWidth = metrics.width;\n          if (typeof maxWidth !== 'undefined' && testWidth > maxWidth) {\n            if (this._doFill) {\n              this.drawingContext.fillText(line, x, y);\n            }\n            if (this._doStroke) {\n              this.drawingContext.strokeText(line, x, y);\n            }\n            line = words[n] + ' ';\n            y += this._textLeading;\n          } else {\n            line = testLine;\n          }\n        }\n      }\n      if (this._doFill) {\n        this.drawingContext.fillText(line, x, y);\n      }\n      if (this._doStroke) {\n        this.drawingContext.strokeText(line, x, y);\n      }\n      y += this._textLeading;\n    }\n  };\n  p5.prototype.textFont = function (str) {\n    this._setProperty('_textFont', str);\n    this._applyTextProperties();\n  };\n  return p5;\n}({}, amdclean['core']);\namdclean['src_app'] = function (require, core, p5Color, p5Element, p5Graphics, p5Image, p5File, p5Vector, p5TableRow, p5Table, colorcreating_reading, colorsetting, constants, dataconversion, dataarray_functions, datastring_functions, environment, imageimage, imageloading_displaying, imagepixels, inputfiles, inputkeyboard, inputmouse, inputtime_date, inputtouch, mathmath, mathcalculation, mathrandom, mathnoise, mathtrigonometry, outputfiles, outputimage, outputtext_area, renderingrendering, shape2d_primitives, shapeattributes, shapecurves, shapevertex, structure, transform, typographyattributes, typographyloading_displaying) {\n  'use strict';\n  var p5 = core;\n  var _globalInit = function () {\n    if (!window.PHANTOMJS && !window.mocha) {\n      if (window.setup && typeof window.setup === 'function' || window.draw && typeof window.draw === 'function') {\n        new p5();\n      }\n    }\n  };\n  if (document.readyState === 'complete') {\n    _globalInit();\n  } else {\n    window.addEventListener('load', _globalInit, false);\n  }\n  return p5;\n}({}, amdclean['core'], amdclean['p5Color'], amdclean['p5Element'], amdclean['p5Graphics'], amdclean['p5Image'], amdclean['p5File'], amdclean['p5Vector'], amdclean['p5TableRow'], amdclean['p5Table'], amdclean['colorcreating_reading'], amdclean['colorsetting'], amdclean['constants'], amdclean['dataconversion'], amdclean['dataarray_functions'], amdclean['datastring_functions'], amdclean['environment'], amdclean['imageimage'], amdclean['imageloading_displaying'], amdclean['imagepixels'], amdclean['inputfiles'], amdclean['inputkeyboard'], amdclean['inputmouse'], amdclean['inputtime_date'], amdclean['inputtouch'], amdclean['mathmath'], amdclean['mathcalculation'], amdclean['mathrandom'], amdclean['mathnoise'], amdclean['mathtrigonometry'], amdclean['outputfiles'], amdclean['outputimage'], amdclean['outputtext_area'], amdclean['renderingrendering'], amdclean['shape2d_primitives'], amdclean['shapeattributes'], amdclean['shapecurves'], amdclean['shapevertex'], amdclean['structure'], amdclean['transform'], amdclean['typographyattributes'], amdclean['typographyloading_displaying']);\nreturn amdclean['src_app'];\n}));"
  },
  {
    "path": "lib/p5.sound.js",
    "content": "/*! p5.sound.js v0.1.7 2015-02-02 */\n(function (root, factory) {\n  if (typeof define === 'function' && define.amd)\n    define('p5.sound', ['p5'], function (p5) { (factory(p5));});\n  else if (typeof exports === 'object')\n    factory(require('../p5'));\n  else\n    factory(root['p5']);\n}(this, function (p5) {\n  /**\n *  p5.sound extends p5 with <a href=\"http://caniuse.com/audio-api\"\n *  target=\"_blank\">Web Audio</a> functionality including audio input,\n *  playback, analysis and synthesis.\n *  <br/><br/>\n *  <a href=\"#/p5.SoundFile\"><b>p5.SoundFile</b></a>: Load and play sound files.<br/>\n *  <a href=\"#/p5.Amplitude\"><b>p5.Amplitude</b></a>: Get the current volume of a sound.<br/>\n *  <a href=\"#/p5.AudioIn\"><b>p5.AudioIn</b></a>: Get sound from an input source, typically\n *    a computer microphone.<br/>\n *  <a href=\"#/p5.FFT\"><b>p5.FFT</b></a>: Analyze the frequency of sound. Returns\n *    results from the frequency spectrum or time domain (waveform).<br/>\n *  <a href=\"#/p5.Oscillator\"><b>p5.Oscillator</b></a>: Generate Sine,\n *    Triangle, Square and Sawtooth waveforms. Base class of\n *    <a href=\"#/p5.Noise\">p5.Noise</a> and <a href=\"#/p5.Pulse\">p5.Pulse</a>.\n *    <br/>\n *  <a href=\"#/p5.Env\"><b>p5.Env</b></a>: An Envelope is a series\n *    of fades over time. Often used to control an object's\n *    output gain level as an \"ADSR Envelope\" (Attack, Decay,\n *    Sustain, Release). Can also modulate other parameters.<br/>\n *  <a href=\"#/p5.Delay\"><b>p5.Delay</b></a>: A delay effect with\n *    parameters for feedback, delayTime, and lowpass filter.<br/>\n *  <a href=\"#/p5.Filter\"><b>p5.Filter</b></a>: Filter the frequency range of a\n *    sound.\n *  <br/>\n *  <a href=\"#/p5.Reverb\"><b>p5.Reverb</b></a>: Add reverb to a sound by specifying\n *    duration and decay. <br/>\n *  <b><a href=\"#/p5.Convolver\">p5.Convolver</a>:</b> Extends\n *  <a href=\"#/p5.Reverb\">p5.Reverb</a> to simulate the sound of real\n *    physical spaces through convolution.<br/>\n *  <b><a href=\"#/p5.SoundRecorder\">p5.SoundRecorder</a></b>: Record sound for playback \n *    / save the .wav file.\n *  <b><a href=\"#/p5.Phrase\">p5.Phrase</a></b>, <b><a href=\"#/p5.Part\">p5.Part</a></b> and\n *  <b><a href=\"#/p5.Score\">p5.Score</a></b>: Compose musical sequences.\n *  <br/><br/>\n *  p5.sound is on <a href=\"https://github.com/therewasaguy/p5.sound/\">GitHub</a>.\n *  Download the latest version \n *  <a href=\"https://github.com/therewasaguy/p5.sound/blob/master/lib/p5.sound.js\">here</a>.\n *  \n *  @module p5.sound\n *  @submodule p5.sound\n *  @for p5.sound\n *  @main\n */\n/**\n *  p5.sound developed by Jason Sigal for the Processing Foundation, Google Summer of Code 2014. The MIT License (MIT).\n *  \n *  http://github.com/therewasaguy/p5.sound\n *\n *  Some of the many audio libraries & resources that inspire p5.sound:\n *   - TONE.js (c) Yotam Mann, 2014. Licensed under The MIT License (MIT). https://github.com/TONEnoTONE/Tone.js\n *   - buzz.js (c) Jay Salvat, 2013. Licensed under The MIT License (MIT). http://buzz.jaysalvat.com/\n *   - Boris Smus Web Audio API book, 2013. Licensed under the Apache License http://www.apache.org/licenses/LICENSE-2.0\n *   - wavesurfer.js https://github.com/katspaugh/wavesurfer.js\n *   - Web Audio Components by Jordan Santell https://github.com/web-audio-components\n *   - Wilm Thoben's Sound library for Processing https://github.com/processing/processing/tree/master/java/libraries/sound\n *   \n *   Web Audio API: http://w3.org/TR/webaudio/\n */\nvar sndcore;\nsndcore = function () {\n  'use strict';\n  /**\n   * Web Audio SHIMS and helper functions to ensure compatability across browsers\n   */\n  // If window.AudioContext is unimplemented, it will alias to window.webkitAudioContext.\n  window.AudioContext = window.AudioContext || window.webkitAudioContext;\n  // Create the Audio Context\n  var audiocontext = new window.AudioContext();\n  /**\n   * <p>Returns the Audio Context for this sketch. Useful for users\n   * who would like to dig deeper into the <a target='_blank' href=\n   * 'http://webaudio.github.io/web-audio-api/'>Web Audio API\n   * </a>.</p>\n   *\n   * @method getAudioContext\n   * @return {Object}    AudioContext for this sketch\n   */\n  p5.prototype.getAudioContext = function () {\n    return audiocontext;\n  };\n  // Polyfills & SHIMS (inspired by tone.js and the AudioContext MonkeyPatch https://github.com/cwilso/AudioContext-MonkeyPatch/ (c) 2013 Chris Wilson, Licensed under the Apache License) //\n  if (typeof audiocontext.createGain !== 'function') {\n    window.audioContext.createGain = window.audioContext.createGainNode;\n  }\n  if (typeof audiocontext.createDelay !== 'function') {\n    window.audioContext.createDelay = window.audioContext.createDelayNode;\n  }\n  if (typeof window.AudioBufferSourceNode.prototype.start !== 'function') {\n    window.AudioBufferSourceNode.prototype.start = window.AudioBufferSourceNode.prototype.noteGrainOn;\n  }\n  if (typeof window.AudioBufferSourceNode.prototype.stop !== 'function') {\n    window.AudioBufferSourceNode.prototype.stop = window.AudioBufferSourceNode.prototype.noteOff;\n  }\n  if (typeof window.OscillatorNode.prototype.start !== 'function') {\n    window.OscillatorNode.prototype.start = window.OscillatorNode.prototype.noteOn;\n  }\n  if (typeof window.OscillatorNode.prototype.stop !== 'function') {\n    window.OscillatorNode.prototype.stop = window.OscillatorNode.prototype.noteOff;\n  }\n  if (!window.AudioContext.prototype.hasOwnProperty('createScriptProcessor')) {\n    window.AudioContext.prototype.createScriptProcessor = window.AudioContext.prototype.createJavaScriptNode;\n  }\n  // Polyfill for AudioIn, also handled by p5.dom createCapture\n  navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;\n  /**\n   * Determine which filetypes are supported (inspired by buzz.js)\n   * The audio element (el) will only be used to test browser support for various audio formats\n   */\n  var el = document.createElement('audio');\n  p5.prototype.isSupported = function () {\n    return !!el.canPlayType;\n  };\n  var isOGGSupported = function () {\n    return !!el.canPlayType && el.canPlayType('audio/ogg; codecs=\"vorbis\"');\n  };\n  var isMP3Supported = function () {\n    return !!el.canPlayType && el.canPlayType('audio/mpeg;');\n  };\n  var isWAVSupported = function () {\n    return !!el.canPlayType && el.canPlayType('audio/wav; codecs=\"1\"');\n  };\n  var isAACSupported = function () {\n    return !!el.canPlayType && (el.canPlayType('audio/x-m4a;') || el.canPlayType('audio/aac;'));\n  };\n  var isAIFSupported = function () {\n    return !!el.canPlayType && el.canPlayType('audio/x-aiff;');\n  };\n  p5.prototype.isFileSupported = function (extension) {\n    switch (extension.toLowerCase()) {\n    case 'mp3':\n      return isMP3Supported();\n    case 'wav':\n      return isWAVSupported();\n    case 'ogg':\n      return isOGGSupported();\n    case 'aac', 'm4a', 'mp4':\n      return isAACSupported();\n    case 'aif', 'aiff':\n      return isAIFSupported();\n    default:\n      return false;\n    }\n  };\n  // if it is iOS, we have to have a user interaction to start Web Audio\n  // http://paulbakaus.com/tutorials/html5/web-audio-on-ios/\n  var iOS = navigator.userAgent.match(/(iPad|iPhone|iPod)/g) ? true : false;\n  if (iOS) {\n    window.addEventListener('touchstart', function () {\n      // create empty buffer\n      var buffer = audiocontext.createBuffer(1, 1, 22050);\n      var source = audiocontext.createBufferSource();\n      source.buffer = buffer;\n      // connect to output (your speakers)\n      source.connect(audiocontext.destination);\n      // play the file\n      source.start(0);\n    }, false);\n  }\n}();\nvar master;\nmaster = function () {\n  'use strict';\n  /**\n   * Master contains AudioContext and the master sound output.\n   */\n  var Master = function () {\n    var audiocontext = p5.prototype.getAudioContext();\n    this.input = audiocontext.createGain();\n    this.output = audiocontext.createGain();\n    //put a hard limiter on the output\n    this.limiter = audiocontext.createDynamicsCompressor();\n    this.limiter.threshold.value = 0;\n    this.limiter.ratio.value = 100;\n    this.audiocontext = audiocontext;\n    this.output.disconnect(this.audiocontext.destination);\n    // an array of input sources\n    this.inputSources = [];\n    // connect input to limiter\n    this.input.connect(this.limiter);\n    // connect limiter to output\n    this.limiter.connect(this.output);\n    // meter is just for measuring global Amplitude\n    this.meter = audiocontext.createGain();\n    this.output.connect(this.meter);\n    // connect output to destination\n    this.output.connect(this.audiocontext.destination);\n    // an array of all sounds in the sketch\n    this.soundArray = [];\n    // an array of all musical parts in the sketch\n    this.parts = [];\n    // file extensions to search for\n    this.extensions = [];\n  };\n  // create a single instance of the p5Sound / master output for use within this sketch\n  var p5sound = new Master();\n  /**\n   *  p5.soundOut is the p5.sound master output. It sends output to\n   *  the destination of this window's web audio context. It contains \n   *  Web Audio API nodes including a dyanmicsCompressor (<code>.limiter</code>),\n   *  and Gain Nodes for <code>.input</code> and <code>.output</code>.\n   *  \n   *  @property p5.soundOut\n   *  @type {Object}\n   */\n  p5.soundOut = p5sound;\n  /**\n   *  a silent connection to the DesinationNode\n   *  which will ensure that anything connected to it\n   *  will not be garbage collected\n   *  \n   *  @private\n   */\n  p5.soundOut._silentNode = p5sound.audiocontext.createGain();\n  p5.soundOut._silentNode.gain.value = 0;\n  p5.soundOut._silentNode.connect(p5sound.audiocontext.destination);\n  return p5sound;\n}(sndcore);\nvar helpers;\nhelpers = function () {\n  'use strict';\n  var p5sound = master;\n  /**\n   *  <p>Set the master amplitude (volume) for sound in this sketch.</p>\n   *\n   *  <p>Note that values greater than 1.0 may lead to digital distortion.</p>\n   * \n   *  <p><b>How This Works</b>: When you load the p5.sound module, it\n   *  creates a single instance of p5sound. All sound objects in this\n   *  module output to p5sound before reaching your computer's output.\n   *  So if you change the amplitude of p5sound, it impacts all of the\n   *  sound in this module.</p>\n   *\n   *  @method masterVolume\n   *  @param {Number} volume   Master amplitude (volume) for sound in\n   *                           this sketch. Should be between 0.0\n   *                           (silence) and 1.0. Values greater than\n   *                           1.0 may lead to digital distortion.\n   *  @example\n   *  <div><code>\n   *  masterVolume(.5);\n   *  </code></div>\n   *   \n   */\n  p5.prototype.masterVolume = function (vol) {\n    p5sound.output.gain.value = vol;\n  };\n  /**\n   * Returns a number representing the sample rate, in samples per second,\n   * of all sound objects in this audio context. It is determined by the\n   * sampling rate of your operating system's sound card, and it is not\n   * currently possile to change.\n   * It is often 44100, or twice the range of human hearing.\n   *\n   * @method sampleRate\n   * @return {Number} samplerate samples per second\n   */\n  p5.prototype.sampleRate = function () {\n    return p5sound.audiocontext.sampleRate;\n  };\n  p5.prototype.getMasterVolume = function () {\n    return p5sound.output.gain.value;\n  };\n  /**\n   *  Returns the closest MIDI note value for\n   *  a given frequency.\n   *  \n   *  @param  {Number} frequency A freqeuncy, for example, the \"A\"\n   *                             above Middle C is 440Hz\n   *  @return {Number}   MIDI note value\n   */\n  p5.prototype.freqToMidi = function (f) {\n    var mathlog2 = Math.log(f / 440) / Math.log(2);\n    var m = Math.round(12 * mathlog2) + 57;\n    return m;\n  };\n  /**\n   *  Returns the frequency value of a MIDI note value.\n   *  General MIDI treats notes as integers where middle C\n   *  is 60, C# is 61, D is 62 etc. Useful for generating\n   *  musical frequencies with oscillators.\n   *  \n   *  @method  midiToFreq\n   *  @param  {Number} midiNote The number of a MIDI note\n   *  @return {Number} Frequency value of the given MIDI note\n   *  @example\n   *  <div><code>\n   *  var notes = [60, 64, 67, 72];\n   *  var i = 0;\n   *  \n   *  function setup() {\n   *    osc = new p5.Oscillator('Triangle');\n   *    osc.start();\n   *    frameRate(1);\n   *  }\n   *  \n   *  function draw() {\n   *    var freq = midiToFreq(notes[i]);\n   *    osc.freq(freq);\n   *    i++;\n   *    if (i >= notes.length){\n   *      i = 0;\n   *    }\n   *  }\n   *  </code></div>\n   */\n  p5.prototype.midiToFreq = function (m) {\n    return 440 * Math.pow(2, (m - 69) / 12);\n  };\n  /**\n   *  List the SoundFile formats that you will include. LoadSound \n   *  will search your directory for these extensions, and will pick\n   *  a format that is compatable with the client's web browser.\n   *  <a href=\"http://media.io/\">Here</a> is a free online file\n   *  converter.\n   *  \n   *  @method soundFormats\n   *  @param {String|Strings} formats i.e. 'mp3', 'wav', 'ogg'\n   *  @example\n   *  <div><code>\n   *  function preload() {\n   *    // set the global sound formats\n   *    soundFormats('mp3', 'ogg');\n   *    \n   *    // load either beatbox.mp3, or .ogg, depending on browser\n   *    mySound = loadSound('../sounds/beatbox.mp3');\n   *  }\n   *\n   *  function setup() {\n   *    mySound.play();\n   *  }\n   *  </code></div>\n   */\n  p5.prototype.soundFormats = function () {\n    // reset extensions array\n    p5sound.extensions = [];\n    // add extensions\n    for (var i = 0; i < arguments.length; i++) {\n      arguments[i] = arguments[i].toLowerCase();\n      if ([\n          'mp3',\n          'wav',\n          'ogg',\n          'm4a',\n          'aac'\n        ].indexOf(arguments[i]) > -1) {\n        p5sound.extensions.push(arguments[i]);\n      } else {\n        throw arguments[i] + ' is not a valid sound format!';\n      }\n    }\n  };\n  p5.prototype.disposeSound = function () {\n    for (var i = 0; i < p5sound.soundArray.length; i++) {\n      p5sound.soundArray[i].dispose();\n    }\n  };\n  // register removeSound to dispose of p5sound SoundFiles, Convolvers,\n  // Oscillators etc when sketch ends\n  p5.prototype.registerMethod('remove', p5.prototype.disposeSound);\n  p5.prototype._checkFileFormats = function (paths) {\n    var path;\n    // if path is a single string, check to see if extension is provided\n    if (typeof paths === 'string') {\n      path = paths;\n      // see if extension is provided\n      var extTest = path.split('.').pop();\n      // if an extension is provided...\n      if ([\n          'mp3',\n          'wav',\n          'ogg',\n          'm4a',\n          'aac'\n        ].indexOf(extTest) > -1) {\n        var supported = p5.prototype.isFileSupported(extTest);\n        if (supported) {\n          path = path;\n        } else {\n          var pathSplit = path.split('.');\n          var pathCore = pathSplit[pathSplit.length - 1];\n          for (var i = 0; i < p5sound.extensions.length; i++) {\n            var extension = p5sound.extensions[i];\n            var supported = p5.prototype.isFileSupported(extension);\n            if (supported) {\n              pathCore = '';\n              if (pathSplit.length === 2) {\n                pathCore += pathSplit[0];\n              }\n              for (var i = 1; i <= pathSplit.length - 2; i++) {\n                var p = pathSplit[i];\n                pathCore += '.' + p;\n              }\n              path = pathCore += '.';\n              path = path += extension;\n              break;\n            }\n          }\n        }\n      } else {\n        for (var i = 0; i < p5sound.extensions.length; i++) {\n          var extension = p5sound.extensions[i];\n          var supported = p5.prototype.isFileSupported(extension);\n          if (supported) {\n            path = path + '.' + extension;\n            break;\n          }\n        }\n      }\n    } else if (typeof paths === 'object') {\n      for (var i = 0; i < paths.length; i++) {\n        var extension = paths[i].split('.').pop();\n        var supported = p5.prototype.isFileSupported(extension);\n        if (supported) {\n          // console.log('.'+extension + ' is ' + supported +\n          //  ' supported by your browser.');\n          path = paths[i];\n          break;\n        }\n      }\n    }\n    return path;\n  };\n  /**\n   *  Used by Osc and Env to chain signal math\n   */\n  p5.prototype._mathChain = function (o, math, thisChain, nextChain, type) {\n    // if this type of math already exists in the chain, replace it\n    for (var i in o.mathOps) {\n      if (o.mathOps[i] instanceof type) {\n        o.mathOps[i].dispose();\n        thisChain = i;\n        if (thisChain < o.mathOps.length - 1) {\n          nextChain = o.mathOps[i + 1];\n        }\n      }\n    }\n    o.mathOps[thisChain - 1].disconnect();\n    o.mathOps[thisChain - 1].connect(math);\n    math.connect(nextChain);\n    o.mathOps[thisChain] = math;\n    return o;\n  };\n}(master);\nvar panner;\npanner = function () {\n  'use strict';\n  var p5sound = master;\n  var ac = p5sound.audiocontext;\n  // Stereo panner\n  p5.Panner = function (input, output, numInputChannels) {\n    this.input = ac.createGain();\n    input.connect(this.input);\n    this.left = ac.createGain();\n    this.right = ac.createGain();\n    this.left.channelInterpretation = 'discrete';\n    this.right.channelInterpretation = 'discrete';\n    // if input is stereo\n    if (numInputChannels > 1) {\n      this.splitter = ac.createChannelSplitter(2);\n      this.input.connect(this.splitter);\n      this.splitter.connect(this.left, 1);\n      this.splitter.connect(this.right, 0);\n    } else {\n      this.input.connect(this.left);\n      this.input.connect(this.right);\n    }\n    this.output = ac.createChannelMerger(2);\n    this.left.connect(this.output, 0, 1);\n    this.right.connect(this.output, 0, 0);\n    this.output.connect(output);\n  };\n  // -1 is left, +1 is right\n  p5.Panner.prototype.pan = function (val, tFromNow) {\n    var time = tFromNow || 0;\n    var t = ac.currentTime + time;\n    var v = (val + 1) / 2;\n    var leftVal = Math.cos(v * Math.PI / 2);\n    var rightVal = Math.sin(v * Math.PI / 2);\n    this.left.gain.linearRampToValueAtTime(leftVal, t);\n    this.right.gain.linearRampToValueAtTime(rightVal, t);\n  };\n  p5.Panner.prototype.inputChannels = function (numChannels) {\n    if (numChannels === 1) {\n      this.input.disconnect();\n      this.input.connect(this.left);\n      this.input.connect(this.right);\n    } else if (numChannels === 2) {\n      if (typeof (this.splitter === 'undefined')) {\n        this.splitter = ac.createChannelSplitter(2);\n      }\n      this.input.disconnect();\n      this.input.connect(this.splitter);\n      this.splitter.connect(this.left, 1);\n      this.splitter.connect(this.right, 0);\n    }\n  };\n  p5.Panner.prototype.connect = function (obj) {\n    this.output.connect(obj);\n  };\n  p5.Panner.prototype.disconnect = function (obj) {\n    this.output.disconnect();\n  };\n  // 3D panner\n  p5.Panner3D = function (input, output) {\n    var panner3D = ac.createPanner();\n    panner3D.panningModel = 'HRTF';\n    panner3D.distanceModel = 'linear';\n    panner3D.setPosition(0, 0, 0);\n    input.connect(panner3D);\n    panner3D.connect(output);\n    panner3D.pan = function (xVal, yVal, zVal) {\n      panner3D.setPosition(xVal, yVal, zVal);\n    };\n    return panner3D;\n  };\n}(master);\nvar soundfile;\nsoundfile = function () {\n  'use strict';\n  var p5sound = master;\n  /**\n   *  <p>SoundFile object with a path to a file.</p>\n   *  \n   *  <p>The p5.SoundFile may not be available immediately because\n   *  it loads the file information asynchronously.</p>\n   * \n   *  <p>To do something with the sound as soon as it loads\n   *  pass the name of a function as the second parameter.</p>\n   *  \n   *  <p>Only one file path is required. However, audio file formats \n   *  (i.e. mp3, ogg, wav and m4a/aac) are not supported by all\n   *  web browsers. If you want to ensure compatability, instead of a single\n   *  file path, you may include an Array of filepaths, and the browser will\n   *  choose a format that works.</p>\n   * \n   *  @class p5.SoundFile\n   *  @constructor\n   *  @param {String/Array} path   path to a sound file (String). Optionally,\n   *                               you may include multiple file formats in\n   *                               an array.\n   *  @param {Function} [callback]   Name of a function to call once file loads\n   *  @return {Object}    p5.SoundFile Object\n   *  @example \n   *  <div><code>\n   *  function preload() {\n   *    mySound = loadSound('assets/drum.mp3');\n   *  }\n   *\n   *  function setup() {\n   *    mySound.play();\n   *  }\n   * \n   * </code></div>\n   */\n  p5.SoundFile = function (paths, onload, whileLoading) {\n    var path = p5.prototype._checkFileFormats(paths);\n    // player variables\n    this.url = path;\n    // array of sources so that they can all be stopped!\n    this.sources = [];\n    // current source\n    this.source = null;\n    this.buffer = null;\n    this.playbackRate = 1;\n    this.gain = 1;\n    this.input = p5sound.audiocontext.createGain();\n    this.output = p5sound.audiocontext.createGain();\n    this.reversed = false;\n    // start and end of playback / loop\n    this.startTime = 0;\n    this.endTime = null;\n    // playing - defaults to false\n    this.playing = false;\n    // paused - defaults to true\n    this.paused = null;\n    // \"restart\" would stop playback before retriggering\n    this.mode = 'sustain';\n    // time that playback was started, in millis\n    this.startMillis = null;\n    this.amplitude = new p5.Amplitude();\n    this.output.connect(this.amplitude.input);\n    // stereo panning\n    this.panPosition = 0;\n    this.panner = new p5.Panner(this.output, p5sound.input, 2);\n    // it is possible to instantiate a soundfile with no path\n    if (this.url) {\n      this.load(onload);\n    }\n    // add this p5.SoundFile to the soundArray\n    p5sound.soundArray.push(this);\n    if (typeof whileLoading === 'function') {\n      this.whileLoading = whileLoading;\n    } else {\n      this.whileLoading = function () {\n      };\n    }\n  };\n  // register preload handling of loadSound\n  p5.prototype.registerPreloadMethod('loadSound');\n  /**\n   *  loadSound() returns a new p5.SoundFile from a specified\n   *  path. If called during preload(), the p5.SoundFile will be ready\n   *  to play in time for setup() and draw(). If called outside of\n   *  preload, the p5.SoundFile will not be ready immediately, so\n   *  loadSound accepts a callback as the second parameter. Using a\n   *  <a href=\"https://github.com/processing/p5.js/wiki/Local-server\">\n   *  local server</a> is recommended when loading external files.\n   *  \n   *  @method loadSound\n   *  @param  {String/Array}   path     Path to the sound file, or an array with\n   *                                    paths to soundfiles in multiple formats\n   *                                    i.e. ['sound.ogg', 'sound.mp3']\n   *  @param {Function} [callback]   Name of a function to call once file loads\n   *  @param {Function} [callback]   Name of a function to call while file is loading.\n   *                                 This function will receive a percentage from 0.0\n   *                                 to 1.0.\n   *  @return {SoundFile}            Returns a p5.SoundFile\n   *  @example \n   *  <div><code>\n   *  function preload() {\n   *   mySound = loadSound('assets/drum.mp3');\n   *  }\n   *\n   *  function setup() {\n   *    mySound.loop();\n   *  }\n   *  </code></div>\n   */\n  p5.prototype.loadSound = function (path, callback, whileLoading) {\n    // if loading locally without a server\n    if (window.location.origin.indexOf('file://') > -1) {\n      alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');\n    }\n    var s = new p5.SoundFile(path, callback, whileLoading);\n    return s;\n  };\n  /**\n   * This is a helper function that the p5.SoundFile calls to load\n   * itself. Accepts a callback (the name of another function)\n   * as an optional parameter.\n   *\n   * @private\n   * @param {Function} [callback]   Name of a function to call once file loads\n   */\n  p5.SoundFile.prototype.load = function (callback) {\n    var sf = this;\n    var request = new XMLHttpRequest();\n    request.addEventListener('progress', function (evt) {\n      sf._updateProgress(evt);\n    }, false);\n    request.open('GET', this.url, true);\n    request.responseType = 'arraybuffer';\n    // decode asyncrohonously\n    var self = this;\n    request.onload = function () {\n      var ac = p5.prototype.getAudioContext();\n      ac.decodeAudioData(request.response, function (buff) {\n        self.buffer = buff;\n        self.panner.inputChannels(buff.numberOfChannels);\n        if (callback) {\n          callback(self);\n        }\n      });\n    };\n    request.send();\n  };\n  p5.SoundFile.prototype._updateProgress = function (evt) {\n    if (evt.lengthComputable) {\n      var percentComplete = Math.log(evt.loaded / evt.total * 9.9);\n      this.whileLoading(percentComplete);\n    } else {\n      console.log('size unknown');\n    }\n  };\n  /**\n   *  Returns true if the sound file finished loading successfully.\n   *  \n   *  @method  isLoaded\n   *  @return {Boolean} \n   */\n  p5.SoundFile.prototype.isLoaded = function () {\n    if (this.buffer) {\n      return true;\n    } else {\n      return false;\n    }\n  };\n  /**\n   * Play the p5.SoundFile\n   *\n   * @method play\n   * @param {Number} [startTime]            (optional) schedule playback to start (in seconds from now).\n   * @param {Number} [rate]             (optional) playback rate\n   * @param {Number} [amp]              (optional) amplitude (volume)\n   *                                     of playback\n   * @param {Number} [cueStart]        (optional) cue start time in seconds\n   * @param {Number} [cueEnd]          (optional) cue end time in seconds\n   */\n  p5.SoundFile.prototype.play = function (time, rate, amp, startTime, endTime) {\n    var now = p5sound.audiocontext.currentTime;\n    var time = time || 0;\n    if (time < 0) {\n      time = 0;\n    }\n    // var tFromNow = time + now;\n    // TO DO: if already playing, create array of buffers for easy stop()\n    if (this.buffer) {\n      // handle restart playmode\n      if (this.mode === 'restart' && this.buffer && this.source) {\n        var now = p5sound.audiocontext.currentTime;\n        this.source.stop(time);\n      }\n      if (startTime) {\n        if (startTime >= 0 && startTime < this.buffer.duration) {\n          this.startTime = startTime;\n        } else {\n          throw 'start time out of range';\n        }\n      }\n      if (endTime) {\n        if (endTime >= 0 && endTime <= this.buffer.duration) {\n          this.endTime = endTime;\n        } else {\n          throw 'end time out of range';\n        }\n      } else {\n        this.endTime = this.buffer.duration;\n      }\n      // make a new source\n      this.source = p5sound.audiocontext.createBufferSource();\n      this.source.buffer = this.buffer;\n      this.source.loop = this.looping;\n      if (this.source.loop === true) {\n        this.source.loopStart = this.startTime;\n        this.source.loopEnd = this.endTime;\n      }\n      this.source.onended = function () {\n      };\n      // firefox method of controlling gain without resetting volume\n      if (!this.source.gain) {\n        this.source.gain = p5sound.audiocontext.createGain();\n        this.source.connect(this.source.gain);\n        // set local amp if provided, otherwise 1\n        var a = amp || 1;\n        this.source.gain.gain.setValueAtTime(a, p5sound.audiocontext.currentTime);\n        this.source.gain.connect(this.output);\n      } else {\n        this.source.gain.value = amp || 1;\n        this.source.connect(this.output);\n      }\n      this.source.playbackRate.cancelScheduledValues(now);\n      rate = rate || Math.abs(this.playbackRate);\n      this.source.playbackRate.setValueAtTime(rate, now);\n      if (this.paused) {\n        this.wasUnpaused = true;\n      }\n      // play the sound\n      if (this.paused && this.wasUnpaused) {\n        this.source.start(time, this.pauseTime, this.endTime);\n      } else {\n        this.wasUnpaused = false;\n        this.pauseTime = 0;\n        this.source.start(time, this.startTime, this.endTime);\n      }\n      this.startSeconds = time + now;\n      this.playing = true;\n      this.paused = false;\n      // add the source to sources array\n      this.sources.push(this.source);\n    } else {\n      throw 'not ready to play file, buffer has yet to load. Try preload()';\n    }\n  };\n  /**\n   *  p5.SoundFile has two play modes: <code>restart</code> and\n   *  <code>sustain</code>. Play Mode determines what happens to a\n   *  p5.SoundFile if it is triggered while in the middle of playback.\n   *  In sustain mode, playback will continue simultaneous to the\n   *  new playback. In restart mode, play() will stop playback\n   *  and start over. Sustain is the default mode. \n   *  \n   *  @method  playMode\n   *  @param  {String} str 'restart' or 'sustain'\n   *  @example\n   *  <div><code>\n   *  function setup(){\n   *    mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n   *  }\n   *  function mouseClicked() {\n   *    mySound.playMode('sustain');\n   *    mySound.play();\n   *  }\n   *  function keyPressed() {\n   *    mySound.playMode('restart');\n   *    mySound.play();\n   *  }\n   * \n   * </code></div>\n   */\n  p5.SoundFile.prototype.playMode = function (str) {\n    var s = str.toLowerCase();\n    // if restart, stop all other sounds from playing\n    if (s === 'restart' && this.buffer && this.source) {\n      for (var i = 0; i < this.sources.length - 1; i++) {\n        var now = p5sound.audiocontext.currentTime;\n        this.sources[i].stop(now);\n      }\n    }\n    // set play mode to effect future playback\n    if (s === 'restart' || s === 'sustain') {\n      this.mode = s;\n    } else {\n      throw 'Invalid play mode. Must be either \"restart\" or \"sustain\"';\n    }\n  };\n  /**\n   *  Pauses a file that is currently playing. If the file is not\n   *  playing, then nothing will happen.\n   *\n   *  After pausing, .play() will resume from the paused\n   *  position.\n   *  If p5.SoundFile had been set to loop before it was paused,\n   *  it will continue to loop after it is unpaused with .play().\n   *\n   *  @method pause\n   *  @param {Number} [startTime] (optional) schedule event to occur\n   *                               seconds from now\n   *  @example\n   *  <div><code>\n   *  var soundFile;\n   *  \n   *  function preload() {\n   *    soundFormats('ogg', 'mp3');\n   *    soundFile = loadSound('../_files/Damscray_-_Dancing_Tiger_02');\n   *  }\n   *  function setup() {\n   *    background(0, 255, 0);\n   *    soundFile.loop();\n   *  }\n   *  function keyTyped() {\n   *    if (key == 'p') {\n   *      soundFile.pause();\n   *      background(255, 0, 0);\n   *    }\n   *  }\n   *  \n   *  function keyReleased() {\n   *    if (key == 'p') {\n   *      soundFile.play();\n   *      background(0, 255, 0);\n   *    }\n   */\n  p5.SoundFile.prototype.pause = function (time) {\n    var now = p5sound.audiocontext.currentTime;\n    var time = time || 0;\n    var pTime = time + now;\n    var keepLoop = this.looping;\n    if (this.isPlaying() && this.buffer && this.source) {\n      this.pauseTime = this.currentTime();\n      this.source.stop(pTime);\n      this.paused = true;\n      this.wasUnpaused = false;\n      this.playing = false;\n    }\n  };\n  /**\n   * Loop the p5.SoundFile. Accepts optional parameters to set the\n   * playback rate, playback volume, loopStart, loopEnd.\n   *\n   * @method loop\n   * @param {Number} [startTime] (optional) schedule event to occur\n   *                             seconds from now\n   * @param {Number} [rate]        (optional) playback rate\n   * @param {Number} [amp]         (optional) playback volume\n   * @param {Number} [cueLoopStart](optional) startTime in seconds\n   * @param {Number} [cueLoopEnd]  (optional) endTime in seconds\n   */\n  p5.SoundFile.prototype.loop = function (rate, amp, loopStart, loopEnd) {\n    this.looping = true;\n    this.play(rate, amp, loopStart, loopEnd);\n  };\n  /**\n   * Set a p5.SoundFile's looping flag to true or false. If the sound\n   * is currently playing, this change will take effect when it\n   * reaches the end of the current playback. \n   * \n   * @param {Boolean} Boolean   set looping to true or false\n   */\n  p5.SoundFile.prototype.setLoop = function (bool) {\n    if (bool === true) {\n      this.looping = true;\n    } else if (bool === false) {\n      this.looping = false;\n    } else {\n      throw 'Error: setLoop accepts either true or false';\n    }\n    if (this.source) {\n      this.source.loop = this.looping;\n    }\n  };\n  /**\n   * Returns 'true' if a p5.SoundFile is looping, 'false' if not.\n   *\n   * @return {Boolean}\n   */\n  p5.SoundFile.prototype.isLooping = function () {\n    if (!this.source) {\n      return false;\n    }\n    if (this.looping === true && this.isPlaying() === true) {\n      return true;\n    }\n    return false;\n  };\n  /**\n   *  Returns true if a p5.SoundFile is playing, false if not (i.e.\n   *  paused or stopped).\n   *\n   *  @method isPlaying\n   *  @return {Boolean}\n   */\n  p5.SoundFile.prototype.isPlaying = function () {\n    if (this.playing !== null) {\n      return this.playing;\n    } else {\n      return false;\n    }\n  };\n  /**\n   *  Returns true if a p5.SoundFile is paused, false if not (i.e.\n   *  playing or stopped).\n   *\n   *  @method  isPaused\n   *  @return {Boolean}\n   */\n  p5.SoundFile.prototype.isPaused = function () {\n    if (!this.paused) {\n      return false;\n    }\n    return this.paused;\n  };\n  /**\n   * Stop soundfile playback.\n   *\n   * @method stop\n   * @param {Number} [startTime] (optional) schedule event to occur\n   *                             in seconds from now\n   */\n  p5.SoundFile.prototype.stop = function (time) {\n    if (this.mode == 'sustain') {\n      this.stopAll();\n      this.playing = false;\n      this.pauseTime = 0;\n      this.wasUnpaused = false;\n      this.paused = false;\n    } else if (this.buffer && this.source) {\n      var now = p5sound.audiocontext.currentTime;\n      var t = time || 0;\n      this.source.stop(now + t);\n      this.playing = false;\n      this.pauseTime = 0;\n      this.wasUnpaused = false;\n      this.paused = false;\n    }\n  };\n  /**\n   *  Stop playback on all of this soundfile's sources.\n   *  @private\n   */\n  p5.SoundFile.prototype.stopAll = function () {\n    if (this.buffer && this.source) {\n      for (var i = 0; i < this.sources.length; i++) {\n        if (this.sources[i] !== null) {\n          var now = p5sound.audiocontext.currentTime;\n          this.sources[i].stop(now);\n        }\n      }\n    }\n  };\n  /**\n   *  Multiply the output volume (amplitude) of a sound file\n   *  between 0.0 (silence) and 1.0 (full volume).\n   *  1.0 is the maximum amplitude of a digital sound, so multiplying\n   *  by greater than 1.0 may cause digital distortion. To\n   *  fade, provide a <code>rampTime</code> parameter. For more\n   *  complex fades, see the Env class.\n   *\n   *  Alternately, you can pass in a signal source such as an\n   *  oscillator to modulate the amplitude with an audio signal.\n   *\n   *  @method  setVolume\n   *  @param {Number|Object} volume  Volume (amplitude) between 0.0\n   *                                     and 1.0 or modulating signal/oscillator\n   *  @param {Number} [rampTime]  Fade for t seconds\n   *  @param {Number} [timeFromNow]  Schedule this event to happen at\n   *                                 t seconds in the future\n   */\n  p5.SoundFile.prototype.setVolume = function (vol, rampTime, tFromNow) {\n    if (typeof vol === 'number') {\n      var rampTime = rampTime || 0;\n      var tFromNow = tFromNow || 0;\n      var now = p5sound.audiocontext.currentTime;\n      var currentVol = this.output.gain.value;\n      this.output.gain.cancelScheduledValues(now + tFromNow);\n      this.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow);\n      this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\n    } else if (vol) {\n      vol.connect(this.output.gain);\n    } else {\n      // return the Gain Node\n      return this.output.gain;\n    }\n  };\n  // same as setVolume, to match Processing Sound\n  p5.SoundFile.prototype.amp = p5.SoundFile.prototype.setVolume;\n  // these are the same thing\n  p5.SoundFile.prototype.fade = p5.SoundFile.prototype.setVolume;\n  p5.SoundFile.prototype.getVolume = function () {\n    return this.output.gain.value;\n  };\n  /**\n   * Set the stereo panning of a p5.sound object to\n   * a floating point number between -1.0 (left) and 1.0 (right).\n   * Default is 0.0 (center).\n   *\n   * @method pan\n   * @param {Number} [panValue]     Set the stereo panner\n   * @param  {Number} timeFromNow schedule this event to happen\n   *                                seconds from now\n   * @example\n   * <div><code>\n   *\n   *  var ball = {};\n   *  var soundFile;\n   *\n   *  function setup() {\n   *    soundFormats('ogg', 'mp3');\n   *    soundFile = loadSound('assets/beatbox.mp3');\n   *  }\n   *  \n   *  function draw() {\n   *    background(0);\n   *    ball.x = constrain(mouseX, 0, width);\n   *    ellipse(ball.x, height/2, 20, 20)\n   *  }\n   *  \n   *  function mousePressed(){\n   *    // map the ball's x location to a panning degree \n   *    // between -1.0 (left) and 1.0 (right)\n   *    var panning = map(ball.x, 0., width,-1.0, 1.0);\n   *    soundFile.pan(panning);\n   *    soundFile.play();\n   *  }\n   *  </div></code>\n   */\n  p5.SoundFile.prototype.pan = function (pval, tFromNow) {\n    this.panPosition = pval;\n    this.panner.pan(pval, tFromNow);\n  };\n  /**\n   * Returns the current stereo pan position (-1.0 to 1.0)\n   *\n   * @return {Number} Returns the stereo pan setting of the Oscillator\n   *                          as a number between -1.0 (left) and 1.0 (right).\n   *                          0.0 is center and default.\n   */\n  p5.SoundFile.prototype.getPan = function () {\n    return this.panPosition;\n  };\n  /**\n   *  Set the playback rate of a sound file. Will change the speed and the pitch.\n   *  Values less than zero will reverse the audio buffer.\n   *\n   *  @method rate\n   *  @param {Number} [playbackRate]     Set the playback rate. 1.0 is normal,\n   *                                     .5 is half-speed, 2.0 is twice as fast.\n   *                                     Must be greater than zero.\n   *  @example\n   *  <div><code>\n   *  var song;\n   *  \n   *  function preload() {\n   *    song = loadSound('assets/Damscray_DancingTiger.mp3');\n   *  }\n   *\n   *  function setup() {\n   *    song.loop();\n   *  }\n   *\n   *  function draw() {\n   *    background(200);\n   *    \n   *    // Set the rate to a range between 0.1 and 4\n   *    // Changing the rate also alters the pitch\n   *    var speed = map(mouseY, 0.1, height, 0, 2);\n   *    speed = constrain(speed, 0.01, 4);\n   *    song.rate(speed);\n   *    \n   *    // Draw a circle to show what is going on\n   *    stroke(0);\n   *    fill(51, 100);\n   *    ellipse(mouseX, 100, 48, 48);\n   *  }\n   *  \n   * </code>\n   * </div>\n   *  \n   */\n  p5.SoundFile.prototype.rate = function (playbackRate) {\n    if (this.playbackRate === playbackRate && this.source) {\n      if (this.source.playbackRate.value === playbackRate) {\n        return;\n      }\n    }\n    this.playbackRate = playbackRate;\n    var rate = playbackRate;\n    if (this.playbackRate === 0 && this.playing) {\n      this.pause();\n    }\n    if (this.playbackRate < 0 && !this.reversed) {\n      var cPos = this.currentTime();\n      var cRate = this.source.playbackRate.value;\n      // this.pause();\n      this.reverseBuffer();\n      rate = Math.abs(playbackRate);\n      var newPos = (cPos - this.duration()) / rate;\n      this.pauseTime = newPos;\n    } else if (this.playbackRate > 0 && this.reversed) {\n      this.reverseBuffer();\n    }\n    if (this.source) {\n      var now = p5sound.audiocontext.currentTime;\n      this.source.playbackRate.cancelScheduledValues(now);\n      this.source.playbackRate.linearRampToValueAtTime(Math.abs(rate), now);\n    }\n  };\n  p5.SoundFile.prototype.getPlaybackRate = function () {\n    return this.playbackRate;\n  };\n  /**\n   * Returns the duration of a sound file in seconds.\n   *\n   * @method duration\n   * @return {Number} The duration of the soundFile in seconds.\n   */\n  p5.SoundFile.prototype.duration = function () {\n    // Return Duration\n    if (this.buffer) {\n      return this.buffer.duration;\n    } else {\n      return 0;\n    }\n  };\n  /**\n   * Return the current position of the p5.SoundFile playhead, in seconds.\n   * Note that if you change the playbackRate while the p5.SoundFile is\n   * playing, the results may not be accurate.\n   *\n   * @method currentTime\n   * @return {Number}   currentTime of the soundFile in seconds.\n   */\n  p5.SoundFile.prototype.currentTime = function () {\n    // TO DO --> make reverse() flip these values appropriately ?\n    var howLong;\n    if (this.isPlaying()) {\n      var timeSinceStart = p5sound.audiocontext.currentTime - this.startSeconds + this.startTime + this.pauseTime;\n      howLong = timeSinceStart * this.playbackRate % (this.duration() * this.playbackRate);\n      // howLong = ( (p5sound.audiocontext.currentTime - this.startSeconds + this.startTime) * this.source.playbackRate.value ) % this.duration();\n      console.log('1');\n      return howLong;\n    } else if (this.paused) {\n      return this.pauseTime;\n    } else {\n      return this.startTime;\n    }\n  };\n  /**\n   * Move the playhead of the song to a position, in seconds. Start\n   * and Stop time. If none are given, will reset the file to play\n   * entire duration from start to finish.\n   *\n   * @method jump\n   * @param {Number} cueTime    cueTime of the soundFile in seconds.\n   * @param {Number} endTime    endTime of the soundFile in seconds.\n   */\n  p5.SoundFile.prototype.jump = function (cueTime, endTime) {\n    if (cueTime < 0 || cueTime > this.buffer.duration) {\n      throw 'jump time out of range';\n    }\n    if (endTime < cueTime || endTime > this.buffer.duration) {\n      throw 'end time out of range';\n    }\n    this.startTime = cueTime || 0;\n    if (endTime) {\n      this.endTime = endTime;\n    } else {\n      this.endTime = this.buffer.duration;\n    }\n    // this.endTime = endTime || this.buffer.duration;\n    if (this.isPlaying()) {\n      var now = p5sound.audiocontext.currentTime;\n      this.stop(now);\n      this.play(cueTime, this.endTime);\n    }\n  };\n  /**\n  * Return the number of channels in a sound file.\n  * For example, Mono = 1, Stereo = 2.\n  *\n  * @method channels\n  * @return {Number} [channels]\n  */\n  p5.SoundFile.prototype.channels = function () {\n    return this.buffer.numberOfChannels;\n  };\n  /**\n  * Return the sample rate of the sound file.\n  *\n  * @method sampleRate\n  * @return {Number} [sampleRate]\n  */\n  p5.SoundFile.prototype.sampleRate = function () {\n    return this.buffer.sampleRate;\n  };\n  /**\n  * Return the number of samples in a sound file.\n  * Equal to sampleRate * duration.\n  *\n  * @method frames\n  * @return {Number} [sampleCount]\n  */\n  p5.SoundFile.prototype.frames = function () {\n    return this.buffer.length;\n  };\n  /**\n   * Returns an array of amplitude peaks in a p5.SoundFile that can be\n   * used to draw a static waveform. Scans through the p5.SoundFile's\n   * audio buffer to find the greatest amplitudes. Accepts one\n   * parameter, 'length', which determines size of the array.\n   * Larger arrays result in more precise waveform visualizations.\n   * \n   * Inspired by Wavesurfer.js.\n   * \n   * @method  getPeaks\n   * @params {Number} [length] length is the size of the returned array.\n   *                          Larger length results in more precision.\n   *                          Defaults to 5*width of the browser window.\n   * @returns {Float32Array} Array of peaks.\n   */\n  p5.SoundFile.prototype.getPeaks = function (length) {\n    if (this.buffer) {\n      // set length to window's width if no length is provided\n      if (!length) {\n        length = window.width * 5;\n      }\n      if (this.buffer) {\n        var buffer = this.buffer;\n        var sampleSize = buffer.length / length;\n        var sampleStep = ~~(sampleSize / 10) || 1;\n        var channels = buffer.numberOfChannels;\n        var peaks = new Float32Array(Math.round(length));\n        for (var c = 0; c < channels; c++) {\n          var chan = buffer.getChannelData(c);\n          for (var i = 0; i < length; i++) {\n            var start = ~~(i * sampleSize);\n            var end = ~~(start + sampleSize);\n            var max = 0;\n            for (var j = start; j < end; j += sampleStep) {\n              var value = chan[j];\n              if (value > max) {\n                max = value;\n              } else if (-value > max) {\n                max = value;\n              }\n            }\n            if (c === 0 || max > peaks[i]) {\n              peaks[i] = max;\n            }\n          }\n        }\n        return peaks;\n      }\n    } else {\n      throw 'Cannot load peaks yet, buffer is not loaded';\n    }\n  };\n  /**\n   *  Reverses the p5.SoundFile's buffer source.\n   *  Playback must be handled separately (see example).\n   *\n   *  @method  reverseBuffer\n   *  @example\n   *  <div><code>\n   *  var drum;\n   *  \n   *  function preload() {\n   *    drum = loadSound('assets/drum.mp3');\n   *  }\n   *\n   *  function setup() {\n   *    drum.reverseBuffer();\n   *    drum.play();\n   *  }\n   *  \n   * </code>\n   * </div>\n   */\n  p5.SoundFile.prototype.reverseBuffer = function () {\n    var curVol = this.getVolume();\n    this.setVolume(0, 0.01, 0);\n    this.pause();\n    if (this.buffer) {\n      Array.prototype.reverse.call(this.buffer.getChannelData(0));\n      Array.prototype.reverse.call(this.buffer.getChannelData(1));\n      // set reversed flag\n      this.reversed = !this.reversed;\n    } else {\n      throw 'SoundFile is not done loading';\n    }\n    this.setVolume(curVol, 0.01, 0.0101);\n    this.play();\n  };\n  // private function for onended behavior\n  p5.SoundFile.prototype._onEnded = function (s) {\n    s.onended = function (s) {\n      var now = p5sound.audiocontext.currentTime;\n      s.stop(now);\n    };\n  };\n  p5.SoundFile.prototype.add = function () {\n  };\n  p5.SoundFile.prototype.dispose = function () {\n    if (this.buffer && this.source) {\n      for (var i = 0; i < this.sources.length - 1; i++) {\n        if (this.sources[i] !== null) {\n          // this.sources[i].disconnect();\n          var now = p5sound.audiocontext.currentTime;\n          this.sources[i].stop(now);\n          this.sources[i] = null;\n        }\n      }\n    }\n    if (this.output) {\n      this.output.disconnect();\n      this.output = null;\n    }\n    if (this.panner) {\n      this.panner.disconnect();\n      this.panner = null;\n    }\n  };\n  /**\n   * Connects the output of a p5sound object to input of another\n   * p5.sound object. For example, you may connect a p5.SoundFile to an\n   * FFT or an Effect. If no parameter is given, it will connect to\n   * the master output. Most p5sound objects connect to the master\n   * output when they are created.\n   *\n   * @method connect\n   * @param {Object} [object] Audio object that accepts an input\n   */\n  p5.SoundFile.prototype.connect = function (unit) {\n    if (!unit) {\n      this.panner.connect(p5sound.input);\n    } else {\n      if (unit.hasOwnProperty('input')) {\n        this.panner.connect(unit.input);\n      } else {\n        this.panner.connect(unit);\n      }\n    }\n  };\n  /**\n   * Disconnects the output of this p5sound object.\n   *\n   * @method disconnect\n   */\n  p5.SoundFile.prototype.disconnect = function (unit) {\n    this.panner.disconnect(unit);\n  };\n  /**\n   *  Read the Amplitude (volume level) of a p5.SoundFile. The\n   *  p5.SoundFile class contains its own instance of the Amplitude\n   *  class to help make it easy to get a SoundFile's volume level.\n   *  Accepts an optional smoothing value (0.0 < 1.0).\n   *  \n   *  @method  getLevel\n   *  @param  {Number} [smoothing] Smoothing is 0.0 by default.\n   *                               Smooths values based on previous values.\n   *  @return {Number}           Volume level (between 0.0 and 1.0)\n   */\n  p5.SoundFile.prototype.getLevel = function (smoothing) {\n    if (smoothing) {\n      this.amplitude.smoothing = smoothing;\n    }\n    return this.amplitude.getLevel();\n  };\n  /**\n   *  Reset the source for this SoundFile to a\n   *  new path (URL).\n   *\n   *  @method  setPath\n   *  @param {String}   path     path to audio file\n   *  @param {Function} callback Callback\n   */\n  p5.SoundFile.prototype.setPath = function (p, callback) {\n    var path = p5.prototype._checkFileFormats(p);\n    this.url = path;\n    this.load(callback);\n  };\n  /**\n   *  Replace the current Audio Buffer with a new Buffer.\n   *  \n   *  @param {Array} buf Array of Float32 Array(s). 2 Float32 Arrays\n   *                     will create a stereo source. 1 will create\n   *                     a mono source.\n   */\n  p5.SoundFile.prototype.setBuffer = function (buf) {\n    var ac = p5sound.audiocontext;\n    var newBuffer = ac.createBuffer(2, buf[0].length, ac.sampleRate);\n    var numChannels = 0;\n    for (var channelNum = 0; channelNum < buf.length; channelNum++) {\n      var channel = newBuffer.getChannelData(channelNum);\n      channel.set(buf[channelNum]);\n      numChannels++;\n    }\n    this.buffer = newBuffer;\n    // set numbers of channels on input to the panner\n    this.panner.inputChannels(numChannels);\n  };\n}(sndcore, master);\nvar amplitude;\namplitude = function () {\n  'use strict';\n  var p5sound = master;\n  /**\n   *  Amplitude measures volume between 0.0 and 1.0.\n   *  Listens to all p5sound by default, or use setInput()\n   *  to listen to a specific sound source. Accepts an optional\n   *  smoothing value, which defaults to 0. \n   *\n   *  @class p5.Amplitude\n   *  @constructor\n   *  @param {Number} [smoothing] between 0.0 and .999 to smooth\n   *                             amplitude readings (defaults to 0)\n   *  @return {Object}    Amplitude Object\n   *  @example\n   *  <div><code>\n   *  var sound, amplitude;\n   *  \n   *  function preload(){\n   *    sound = loadSound('assets/beat.mp3');\n   *  }\n   *  function setup() { \n   *    amplitude = new p5.Amplitude();\n   *    sound.loop();\n   *  }\n   *  function draw() {\n   *    background(0);\n   *    fill(255);\n   *    var level = amplitude.getLevel();\n   *    var size = map(level, 0, 1, 0, 200);\n   *    ellipse(width/2, height/2, size, size);\n   *  }\n   *  function mouseClicked(){\n   *    sound.stop();\n   *  }\n   *  </code></div>\n   */\n  p5.Amplitude = function (smoothing) {\n    // Set to 2048 for now. In future iterations, this should be inherited or parsed from p5sound's default\n    this.bufferSize = 2048;\n    // set audio context\n    this.audiocontext = p5sound.audiocontext;\n    this.processor = this.audiocontext.createScriptProcessor(this.bufferSize);\n    // for connections\n    this.input = this.processor;\n    this.output = this.audiocontext.createGain();\n    // smoothing defaults to 0\n    this.smoothing = smoothing || 0;\n    // the variables to return\n    this.volume = 0;\n    this.average = 0;\n    this.volMax = 0.001;\n    this.normalize = false;\n    this.processor.onaudioprocess = this.volumeAudioProcess.bind(this);\n    this.processor.connect(this.output);\n    this.output.gain.value = 0;\n    // this may only be necessary because of a Chrome bug\n    this.output.connect(this.audiocontext.destination);\n    // connect to p5sound master output by default, unless set by input()\n    p5sound.meter.connect(this.processor);\n  };\n  /**\n   *  Connects to the p5sound instance (master output) by default.\n   *  Optionally, you can pass in a specific source (i.e. a soundfile).\n   *\n   *  @method setInput\n   *  @param {soundObject|undefined} [snd] set the sound source\n   *                                       (optional, defaults to\n   *                                       master output)\n   *  @param {Number|undefined} [smoothing] a range between 0.0 and 1.0\n   *                                        to smooth amplitude readings\n   *  @example\n   *  <div><code>\n   *  function preload(){\n   *    sound1 = loadSound('assets/beat.mp3');\n   *    sound2 = loadSound('assets/drum.mp3');\n   *  }\n   *  function setup(){\n   *    amplitude = new p5.Amplitude();\n   *    sound1.loop();\n   *    sound2.loop();\n   *    amplitude.setInput(sound2);\n   *  }\n   *  function draw() {\n   *    background(0);\n   *    fill(255);\n   *    var level = amplitude.getLevel();\n   *    var size = map(level, 0, 1, 0, 200);\n   *    ellipse(width/2, height/2, size, size);\n   *  }\n   *  function mouseClicked(){\n   *    sound1.stop();\n   *    sound2.stop();\n   *  }\n   *  </code></div>\n   */\n  p5.Amplitude.prototype.setInput = function (source, smoothing) {\n    p5sound.meter.disconnect(this.processor);\n    if (smoothing) {\n      this.smoothing = smoothing;\n    }\n    // connect to the master out of p5s instance if no snd is provided\n    if (source == null) {\n      console.log('Amplitude input source is not ready! Connecting to master output instead');\n      p5sound.meter.connect(this.processor);\n    } else if (source instanceof p5.Signal) {\n      source.output.connect(this.processor);\n    } else if (source) {\n      source.connect(this.processor);\n      this.processor.disconnect();\n      this.processor.connect(this.output);\n    } else {\n      p5sound.meter.connect(this.processor);\n    }\n  };\n  p5.Amplitude.prototype.connect = function (unit) {\n    if (unit) {\n      if (unit.hasOwnProperty('input')) {\n        this.output.connect(unit.input);\n      } else {\n        this.output.connect(unit);\n      }\n    } else {\n      this.output.connect(this.panner.connect(p5sound.input));\n    }\n  };\n  p5.Amplitude.prototype.disconnect = function (unit) {\n    this.output.disconnect();\n  };\n  // Should this be a private function?\n  // TO DO make this stereo / dependent on # of audio channels\n  p5.Amplitude.prototype.volumeAudioProcess = function (event) {\n    // return result\n    var inputBuffer = event.inputBuffer.getChannelData(0);\n    var bufLength = inputBuffer.length;\n    var total = 0;\n    var sum = 0;\n    var x;\n    for (var i = 0; i < bufLength; i++) {\n      x = inputBuffer[i];\n      if (this.normalize) {\n        total += Math.max(Math.min(x / this.volMax, 1), -1);\n        sum += Math.max(Math.min(x / this.volMax, 1), -1) * Math.max(Math.min(x / this.volMax, 1), -1);\n      } else {\n        total += x;\n        sum += x * x;\n      }\n    }\n    var average = total / bufLength;\n    // ... then take the square root of the sum.\n    var rms = Math.sqrt(sum / bufLength);\n    // this.avgVol = Math.max(average, this.volume*this.smoothing);\n    this.volume = Math.max(rms, this.volume * this.smoothing);\n    this.volMax = Math.max(this.volume, this.volMax);\n    // normalized values\n    this.volNorm = Math.max(Math.min(this.volume / this.volMax, 1), 0);\n  };\n  /**\n   *  Returns a single Amplitude reading at the moment it is called.\n   *  For continuous readings, run in the draw loop.\n   *\n   *  @method getLevel\n   *  @return {Number}       Amplitude as a number between 0.0 and 1.0\n   *  @example\n   *  <div><code>\n   *  function preload(){\n   *    sound = loadSound('assets/beat.mp3');\n   *  }\n   *  function setup() { \n   *    amplitude = new p5.Amplitude();\n   *    sound.loop();\n   *  }\n   *  function draw() {\n   *    background(0);\n   *    fill(255);\n   *    var level = amplitude.getLevel();\n   *    var size = map(level, 0, 1, 0, 200);\n   *    ellipse(width/2, height/2, size, size);\n   *  }\n   *  function mouseClicked(){\n   *    sound.stop();\n   *  }\n   *  </code></div>\n   */\n  p5.Amplitude.prototype.getLevel = function () {\n    if (this.normalize) {\n      return this.volNorm;\n    } else {\n      return this.volume;\n    }\n  };\n  /**\n   * Determines whether the results of Amplitude.process() will be\n   * Normalized. To normalize, Amplitude finds the difference the\n   * loudest reading it has processed and the maximum amplitude of\n   * 1.0. Amplitude adds this difference to all values to produce\n   * results that will reliably map between 0.0 and 1.0. However,\n   * if a louder moment occurs, the amount that Normalize adds to\n   * all the values will change. Accepts an optional boolean parameter\n   * (true or false). Normalizing is off by default.\n   *\n   * @method toggleNormalize\n   * @param {boolean} [boolean] set normalize to true (1) or false (0)\n   */\n  p5.Amplitude.prototype.toggleNormalize = function (bool) {\n    if (typeof bool === 'boolean') {\n      this.normalize = bool;\n    } else {\n      this.normalize = !this.normalize;\n    }\n  };\n  /**\n   *  Smooth Amplitude analysis by averaging with the last analysis \n   *  frame. Off by default.\n   *\n   *  @method smooth\n   *  @param {Number} set smoothing from 0.0 <= 1\n   */\n  p5.Amplitude.prototype.smooth = function (s) {\n    if (s >= 0 && s < 1) {\n      this.smoothing = s;\n    } else {\n      console.log('Error: smoothing must be between 0 and 1');\n    }\n  };\n}(master);\nvar fft;\nfft = function () {\n  'use strict';\n  var p5sound = master;\n  /**\n   *  <p>FFT (Fast Fourier Transform) is an analysis algorithm that\n   *  isolates individual\n   *  <a href=\"https://en.wikipedia.org/wiki/Audio_frequency\">\n   *  audio frequencies</a> within a waveform.</p>\n   *\n   *  <p>Once instantiated, a p5.FFT object can return an array based on\n   *  two types of analyses: <br> • <code>FFT.waveform()</code> computes\n   *  amplitude values along the time domain. The array indices correspond\n   *  to samples across a brief moment in time. Each value represents\n   *  amplitude of the waveform at that sample of time.<br>\n   *  • <code>FFT.analyze() </code> computes amplitude values along the\n   *  frequency domain. The array indices correspond to frequencies (i.e.\n   *  pitches), from the lowest to the highest that humans can hear. Each\n   *  value represents amplitude at that slice of the frequency spectrum.\n   *  Use with <code>getEnergy()</code> to measure amplitude at specific\n   *  frequencies, or within a range of frequencies. </p>\n   *\n   *  <p>FFT analyzes a very short snapshot of sound called a sample\n   *  buffer. It returns an array of amplitude measurements, referred\n   *  to as <code>bins</code>. The array is 1024 bins long by default.\n   *  You can change the bin array length, but it must be a power of 2\n   *  between 16 and 1024 in order for the FFT algorithm to function\n   *  correctly. The actual size of the FFT buffer is twice the \n   *  number of bins, so given a standard sample rate, the buffer is\n   *  2048/44100 seconds long.</p>\n   *  \n   * \n   *  @class p5.FFT\n   *  @constructor\n   *  @param {Number} [smoothing]   Smooth results of Freq Spectrum.\n   *                                0.0 < smoothing < 1.0.\n   *                                Defaults to 0.8.\n   *  @param {Number} [bins]    Length of resulting array.\n   *                            Must be a power of two between\n   *                            16 and 1024. Defaults to 1024.\n   *  @return {Object}    FFT Object\n   *  @example\n   *  <div><code>\n   *  function preload(){\n   *    sound = loadSound('assets/Damscray_DancingTiger.mp3');\n   *  }\n   *\n   *  function setup(){\n   *    createCanvas(100,100);\n   *    sound.loop();\n   *    fft = new p5.FFT();\n   *  }\n   *\n   *  function draw(){\n   *    background(0);\n   *\n   *    var spectrum = fft.analyze(); \n   *    noStroke();\n   *    fill(0,255,0); // spectrum is green\n   *    for (var i = 0; i< spectrum.length; i++){\n   *      var x = map(i, 0, spectrum.length, 0, width);\n   *      var h = -height + map(spectrum[i], 0, 255, height, 0);\n   *      rect(x, height, width / spectrum.length, h )\n   *    }\n   *\n   *    var waveform = fft.waveform();\n   *    noFill();\n   *    beginShape();\n   *    stroke(255,0,0); // waveform is red\n   *    strokeWeight(1);\n   *    for (var i = 0; i< waveform.length; i++){\n   *      var x = map(i, 0, waveform.length, 0, width);\n   *      var y = map( waveform[i], 0, 255, 0, height);\n   *      vertex(x,y);\n   *    }\n   *    endShape();\n   *  }\n   *  \n   *  function mouseClicked(){\n   *    sound.stop();\n   *  }\n   *  </code></div>\n   */\n  p5.FFT = function (smoothing, bins) {\n    var SMOOTHING = smoothing || 0.8;\n    if (smoothing === 0) {\n      SMOOTHING = smoothing;\n    }\n    var FFT_SIZE = bins * 2 || 2048;\n    this.analyser = p5sound.audiocontext.createAnalyser();\n    // default connections to p5sound master\n    p5sound.output.connect(this.analyser);\n    this.analyser.smoothingTimeConstant = SMOOTHING;\n    this.analyser.fftSize = FFT_SIZE;\n    this.freqDomain = new Uint8Array(this.analyser.frequencyBinCount);\n    this.timeDomain = new Uint8Array(this.analyser.frequencyBinCount);\n    // predefined frequency ranages, these will be tweakable\n    this.bass = [\n      20,\n      140\n    ];\n    this.lowMid = [\n      140,\n      400\n    ];\n    this.mid = [\n      400,\n      2600\n    ];\n    this.highMid = [\n      2600,\n      5200\n    ];\n    this.treble = [\n      5200,\n      14000\n    ];\n  };\n  /**\n   *  Set the input source for the FFT analysis. If no source is\n   *  provided, FFT will analyze all sound in the sketch.\n   *\n   *  @method  setInput\n   *  @param {Object} [source] p5.sound object (or web audio API source node)\n   *  @param {Number} [bins]  Must be a power of two between 16 and 1024\n   */\n  p5.FFT.prototype.setInput = function (source, bins) {\n    if (bins) {\n      this.analyser.fftSize = bins * 2;\n    }\n    if (source.output) {\n      source.output.connect(this.analyser);\n    } else {\n      source.connect(this.analyser);\n    }\n  };\n  /**\n   *  Returns an array of amplitude values (between 0-255) that represent\n   *  a snapshot of amplitude readings in a single buffer. Length will be\n   *  equal to bins (defaults to 1024). Can be used to draw the waveform\n   *  of a sound. \n   *  \n   *  @method waveform\n   *  @param {Number} [bins]    Must be a power of two between\n   *                            16 and 1024. Defaults to 1024.\n   *  @return {Array}  Array    Array of amplitude values (0-255)\n   *                            over time. Array length = bins.\n   *\n   */\n  p5.FFT.prototype.waveform = function (bins) {\n    if (bins) {\n      this.analyser.fftSize = bins * 2;\n    }\n    this.analyser.getByteTimeDomainData(this.timeDomain);\n    var normalArray = Array.apply([], this.timeDomain);\n    normalArray.length === this.analyser.fftSize;\n    normalArray.constructor === Array;\n    return normalArray;\n  };\n  /**\n   *  Returns an array of amplitude values (between 0 and 255)\n   *  across the frequency spectrum. Length is equal to FFT bins\n   *  (1024 by default). The array indices correspond to frequencies\n   *  (i.e. pitches), from the lowest to the highest that humans can\n   *  hear. Each value represents amplitude at that slice of the\n   *  frequency spectrum. Must be called prior to using\n   *  <code>getEnergy()</code>.\n   *\n   *  @method analyze\n   *  @param {Number} [bins]    Must be a power of two between\n   *                             16 and 1024. Defaults to 1024.\n   *  @return {Array} spectrum    Array of energy (amplitude/volume)\n   *                              values across the frequency spectrum.\n   *                              Lowest energy (silence) = 0, highest\n   *                              possible is 255.\n   *  @example\n   *  <div><code>\n   *  var osc;\n   *  var fft;\n   *\n   *  function setup(){\n   *    createCanvas(100,100);\n   *    osc = new p5.Oscillator();\n   *    osc.start();\n   *    fft = new p5.FFT();\n   *  }\n   *\n   *  function draw(){\n   *    background(0);\n   *\n   *    var freq = map(mouseX, 0, 800, 20, 15000);\n   *    freq = constrain(freq, 1, 20000);\n   *    osc.freq(freq);\n   *\n   *    var spectrum = fft.analyze(); \n   *    noStroke();\n   *    fill(0,255,0); // spectrum is green\n   *    for (var i = 0; i< spectrum.length; i++){\n   *      var x = map(i, 0, spectrum.length, 0, width);\n   *      var h = -height + map(spectrum[i], 0, 255, height, 0);\n   *      rect(x, height, width / spectrum.length, h )\n   *    }\n   *\n   *    stroke(255);\n   *    text('Freq: ' + round(freq)+'Hz', 10, 10); \n   *  }\n   *  </code></div>\n   *                                   \n   *\n   */\n  p5.FFT.prototype.analyze = function (bins) {\n    if (bins) {\n      this.analyser.fftSize = bins * 2;\n    }\n    this.analyser.getByteFrequencyData(this.freqDomain);\n    var normalArray = Array.apply([], this.freqDomain);\n    normalArray.length === this.analyser.fftSize;\n    normalArray.constructor === Array;\n    return normalArray;\n  };\n  /**\n   *  Returns the amount of energy (volume) at a specific\n   *  <a href=\"en.wikipedia.org/wiki/Audio_frequency\" target=\"_blank\">\n   *  frequency</a>, or the average amount of energy between two\n   *  frequencies. Accepts Number(s) corresponding\n   *  to frequency (in Hz), or a String corresponding to predefined\n   *  frequency ranges (\"bass\", \"lowMid\", \"mid\", \"highMid\", \"treble\").\n   *  Returns a range between 0 (no energy/volume at that frequency) and\n   *  255 (maximum energy). \n   *  <em>NOTE: analyze() must be called prior to getEnergy(). Analyze()\n   *  tells the FFT to analyze frequency data, and getEnergy() uses\n   *  the results determine the value at a specific frequency or\n   *  range of frequencies.</em></p>\n   *  \n   *  @method  getEnergy\n   *  @param  {Number|String} frequency1   Will return a value representing\n   *                                energy at this frequency. Alternately,\n   *                                the strings \"bass\", \"lowMid\" \"mid\",\n   *                                \"highMid\", and \"treble\" will return\n   *                                predefined frequency ranges.\n   *  @param  {Number} [frequency2] If a second frequency is given,\n   *                                will return average amount of\n   *                                energy that exists between the\n   *                                two frequencies.\n   *  @return {Number}   Energy   Energy (volume/amplitude) from\n   *                              0 and 255.\n   *                                       \n   */\n  p5.FFT.prototype.getEnergy = function (frequency1, frequency2) {\n    var nyquist = p5sound.audiocontext.sampleRate / 2;\n    if (frequency1 === 'bass') {\n      frequency1 = this.bass[0];\n      frequency2 = this.bass[1];\n    } else if (frequency1 === 'lowMid') {\n      frequency1 = this.lowMid[0];\n      frequency2 = this.lowMid[1];\n    } else if (frequency1 === 'mid') {\n      frequency1 = this.mid[0];\n      frequency2 = this.mid[1];\n    } else if (frequency1 === 'highMid') {\n      frequency1 = this.highMid[0];\n      frequency2 = this.highMid[1];\n    } else if (frequency1 === 'treble') {\n      frequency1 = this.treble[0];\n      frequency2 = this.treble[1];\n    }\n    if (typeof frequency1 !== 'number') {\n      throw 'invalid input for getEnergy()';\n    } else if (!frequency2) {\n      var index = Math.round(frequency1 / nyquist * this.freqDomain.length);\n      return this.freqDomain[index];\n    } else if (frequency1 && frequency2) {\n      // if second is higher than first\n      if (frequency1 > frequency2) {\n        var swap = frequency2;\n        frequency2 = frequency1;\n        frequency1 = swap;\n      }\n      var lowIndex = Math.round(frequency1 / nyquist * this.freqDomain.length);\n      var highIndex = Math.round(frequency2 / nyquist * this.freqDomain.length);\n      var total = 0;\n      var numFrequencies = 0;\n      // add up all of the values for the frequencies\n      for (var i = lowIndex; i <= highIndex; i++) {\n        total += this.freqDomain[i];\n        numFrequencies += 1;\n      }\n      // divide by total number of frequencies\n      var toReturn = total / numFrequencies;\n      return toReturn;\n    } else {\n      throw 'invalid input for getEnergy()';\n    }\n  };\n  // compatability with v.012, changed to getEnergy in v.0121. Will be deprecated...\n  p5.FFT.prototype.getFreq = function (freq1, freq2) {\n    console.log('getFreq() is deprecated. Please use getEnergy() instead.');\n    var x = this.getEnergy(freq1, freq2);\n    return x;\n  };\n  /**\n   *  Smooth FFT analysis by averaging with the last analysis frame.\n   *  \n   *  @method smooth\n   *  @param {Number} smoothing    0.0 < smoothing < 1.0.\n   *                               Defaults to 0.8.\n   */\n  p5.FFT.prototype.smooth = function (s) {\n    this.analyser.smoothingTimeConstant = s;\n  };\n}(master);\n/** Tone.js module by Yotam Mann, MIT License 2014  http://opensource.org/licenses/MIT **/\nvar Tone_core_Tone;\nTone_core_Tone = function () {\n  'use strict';\n  function isUndef(val) {\n    return val === void 0;\n  }\n  var audioContext;\n  if (isUndef(window.AudioContext)) {\n    window.AudioContext = window.webkitAudioContext;\n  }\n  if (isUndef(window.OfflineAudioContext)) {\n    window.OfflineAudioContext = window.webkitOfflineAudioContext;\n  }\n  if (!isUndef(AudioContext)) {\n    audioContext = new AudioContext();\n  } else {\n    throw new Error('Web Audio is not supported in this browser');\n  }\n  if (typeof AudioContext.prototype.createGain !== 'function') {\n    AudioContext.prototype.createGain = AudioContext.prototype.createGainNode;\n  }\n  if (typeof AudioContext.prototype.createDelay !== 'function') {\n    AudioContext.prototype.createDelay = AudioContext.prototype.createDelayNode;\n  }\n  if (typeof AudioContext.prototype.createPeriodicWave !== 'function') {\n    AudioContext.prototype.createPeriodicWave = AudioContext.prototype.createWaveTable;\n  }\n  if (typeof AudioBufferSourceNode.prototype.start !== 'function') {\n    AudioBufferSourceNode.prototype.start = AudioBufferSourceNode.prototype.noteGrainOn;\n  }\n  if (typeof AudioBufferSourceNode.prototype.stop !== 'function') {\n    AudioBufferSourceNode.prototype.stop = AudioBufferSourceNode.prototype.noteOff;\n  }\n  if (typeof OscillatorNode.prototype.start !== 'function') {\n    OscillatorNode.prototype.start = OscillatorNode.prototype.noteOn;\n  }\n  if (typeof OscillatorNode.prototype.stop !== 'function') {\n    OscillatorNode.prototype.stop = OscillatorNode.prototype.noteOff;\n  }\n  if (typeof OscillatorNode.prototype.setPeriodicWave !== 'function') {\n    OscillatorNode.prototype.setPeriodicWave = OscillatorNode.prototype.setWaveTable;\n  }\n  AudioNode.prototype._nativeConnect = AudioNode.prototype.connect;\n  AudioNode.prototype.connect = function (B, outNum, inNum) {\n    if (B.input) {\n      if (Array.isArray(B.input)) {\n        if (isUndef(inNum)) {\n          inNum = 0;\n        }\n        this.connect(B.input[inNum]);\n      } else {\n        this.connect(B.input, outNum, inNum);\n      }\n    } else {\n      try {\n        if (B instanceof AudioNode) {\n          this._nativeConnect(B, outNum, inNum);\n        } else {\n          this._nativeConnect(B, outNum);\n        }\n      } catch (e) {\n        throw new Error('error connecting to node: ' + B);\n      }\n    }\n  };\n  var Tone = function (inputs, outputs) {\n    if (isUndef(inputs) || inputs === 1) {\n      this.input = this.context.createGain();\n    } else if (inputs > 1) {\n      this.input = new Array(inputs);\n    }\n    if (isUndef(outputs) || outputs === 1) {\n      this.output = this.context.createGain();\n    } else if (outputs > 1) {\n      this.output = new Array(inputs);\n    }\n  };\n  Tone.context = audioContext;\n  Tone.prototype.context = Tone.context;\n  Tone.prototype.bufferSize = 2048;\n  Tone.prototype.bufferTime = Tone.prototype.bufferSize / Tone.context.sampleRate;\n  Tone.prototype.connect = function (unit, outputNum, inputNum) {\n    if (Array.isArray(this.output)) {\n      outputNum = this.defaultArg(outputNum, 0);\n      this.output[outputNum].connect(unit, 0, inputNum);\n    } else {\n      this.output.connect(unit, outputNum, inputNum);\n    }\n  };\n  Tone.prototype.disconnect = function (outputNum) {\n    if (Array.isArray(this.output)) {\n      outputNum = this.defaultArg(outputNum, 0);\n      this.output[outputNum].disconnect();\n    } else {\n      this.output.disconnect();\n    }\n  };\n  Tone.prototype.connectSeries = function () {\n    if (arguments.length > 1) {\n      var currentUnit = arguments[0];\n      for (var i = 1; i < arguments.length; i++) {\n        var toUnit = arguments[i];\n        currentUnit.connect(toUnit);\n        currentUnit = toUnit;\n      }\n    }\n  };\n  Tone.prototype.connectParallel = function () {\n    var connectFrom = arguments[0];\n    if (arguments.length > 1) {\n      for (var i = 1; i < arguments.length; i++) {\n        var connectTo = arguments[i];\n        connectFrom.connect(connectTo);\n      }\n    }\n  };\n  Tone.prototype.chain = function () {\n    if (arguments.length > 0) {\n      var currentUnit = this;\n      for (var i = 0; i < arguments.length; i++) {\n        var toUnit = arguments[i];\n        currentUnit.connect(toUnit);\n        currentUnit = toUnit;\n      }\n    }\n  };\n  Tone.prototype.fan = function () {\n    if (arguments.length > 0) {\n      for (var i = 1; i < arguments.length; i++) {\n        this.connect(arguments[i]);\n      }\n    }\n  };\n  AudioNode.prototype.chain = Tone.prototype.chain;\n  AudioNode.prototype.fan = Tone.prototype.fan;\n  Tone.prototype.defaultArg = function (given, fallback) {\n    if (typeof given === 'object' && typeof fallback === 'object') {\n      var ret = {};\n      for (var givenProp in given) {\n        ret[givenProp] = this.defaultArg(given[givenProp], given[givenProp]);\n      }\n      for (var prop in fallback) {\n        ret[prop] = this.defaultArg(given[prop], fallback[prop]);\n      }\n      return ret;\n    } else {\n      return isUndef(given) ? fallback : given;\n    }\n  };\n  Tone.prototype.optionsObject = function (values, keys, defaults) {\n    var options = {};\n    if (values.length === 1 && typeof values[0] === 'object') {\n      options = values[0];\n    } else {\n      for (var i = 0; i < keys.length; i++) {\n        options[keys[i]] = values[i];\n      }\n    }\n    if (!this.isUndef(defaults)) {\n      return this.defaultArg(options, defaults);\n    } else {\n      return options;\n    }\n  };\n  Tone.prototype.isUndef = isUndef;\n  Tone.prototype.equalPowerScale = function (percent) {\n    var piFactor = 0.5 * Math.PI;\n    return Math.sin(percent * piFactor);\n  };\n  Tone.prototype.logScale = function (gain) {\n    return Math.max(this.normalize(this.gainToDb(gain), -100, 0), 0);\n  };\n  Tone.prototype.expScale = function (gain) {\n    return this.dbToGain(this.interpolate(gain, -100, 0));\n  };\n  Tone.prototype.dbToGain = function (db) {\n    return Math.pow(2, db / 6);\n  };\n  Tone.prototype.gainToDb = function (gain) {\n    return 20 * (Math.log(gain) / Math.LN10);\n  };\n  Tone.prototype.interpolate = function (input, outputMin, outputMax) {\n    return input * (outputMax - outputMin) + outputMin;\n  };\n  Tone.prototype.normalize = function (input, inputMin, inputMax) {\n    if (inputMin > inputMax) {\n      var tmp = inputMax;\n      inputMax = inputMin;\n      inputMin = tmp;\n    } else if (inputMin == inputMax) {\n      return 0;\n    }\n    return (input - inputMin) / (inputMax - inputMin);\n  };\n  Tone.prototype.dispose = function () {\n    if (!this.isUndef(this.input)) {\n      if (this.input instanceof AudioNode) {\n        this.input.disconnect();\n      }\n      this.input = null;\n    }\n    if (!this.isUndef(this.output)) {\n      if (this.output instanceof AudioNode) {\n        this.output.disconnect();\n      }\n      this.output = null;\n    }\n  };\n  var _silentNode = null;\n  Tone.prototype.noGC = function () {\n    this.output.connect(_silentNode);\n  };\n  AudioNode.prototype.noGC = function () {\n    this.connect(_silentNode);\n  };\n  Tone.prototype.now = function () {\n    return this.context.currentTime;\n  };\n  Tone.prototype.samplesToSeconds = function (samples) {\n    return samples / this.context.sampleRate;\n  };\n  Tone.prototype.toSamples = function (time) {\n    var seconds = this.toSeconds(time);\n    return Math.round(seconds * this.context.sampleRate);\n  };\n  Tone.prototype.toSeconds = function (time, now) {\n    now = this.defaultArg(now, this.now());\n    if (typeof time === 'number') {\n      return time;\n    } else if (typeof time === 'string') {\n      var plusTime = 0;\n      if (time.charAt(0) === '+') {\n        time = time.slice(1);\n        plusTime = now;\n      }\n      return parseFloat(time) + plusTime;\n    } else {\n      return now;\n    }\n  };\n  Tone.prototype.frequencyToSeconds = function (freq) {\n    return 1 / parseFloat(freq);\n  };\n  Tone.prototype.secondsToFrequency = function (seconds) {\n    return 1 / seconds;\n  };\n  var newContextCallbacks = [];\n  Tone._initAudioContext = function (callback) {\n    callback(Tone.context);\n    newContextCallbacks.push(callback);\n  };\n  Tone.setContext = function (ctx) {\n    Tone.prototype.context = ctx;\n    Tone.context = ctx;\n    for (var i = 0; i < newContextCallbacks.length; i++) {\n      newContextCallbacks[i](ctx);\n    }\n  };\n  Tone.extend = function (child, parent) {\n    if (isUndef(parent)) {\n      parent = Tone;\n    }\n    function TempConstructor() {\n    }\n    TempConstructor.prototype = parent.prototype;\n    child.prototype = new TempConstructor();\n    child.prototype.constructor = child;\n  };\n  Tone.startMobile = function () {\n    var osc = Tone.context.createOscillator();\n    var silent = Tone.context.createGain();\n    silent.gain.value = 0;\n    osc.connect(silent);\n    silent.connect(Tone.context.destination);\n    var now = Tone.context.currentTime;\n    osc.start(now);\n    osc.stop(now + 1);\n  };\n  Tone._initAudioContext(function (audioContext) {\n    Tone.prototype.bufferTime = Tone.prototype.bufferSize / audioContext.sampleRate;\n    _silentNode = audioContext.createGain();\n    _silentNode.gain.value = 0;\n    _silentNode.connect(audioContext.destination);\n  });\n  return Tone;\n}();\n/** Tone.js module by Yotam Mann, MIT License 2014  http://opensource.org/licenses/MIT **/\nvar Tone_signal_SignalBase;\nTone_signal_SignalBase = function (Tone) {\n  'use strict';\n  Tone.SignalBase = function () {\n  };\n  Tone.extend(Tone.SignalBase);\n  Tone.SignalBase.prototype.connect = function (node, outputNumber, inputNumber) {\n    if (node instanceof Tone.Signal) {\n      node.setValue(0);\n    } else if (node instanceof AudioParam) {\n      node.value = 0;\n    }\n    Tone.prototype.connect.call(this, node, outputNumber, inputNumber);\n  };\n  Tone.SignalBase.prototype.dispose = function () {\n    Tone.prototype.dispose.call(this);\n  };\n  return Tone.SignalBase;\n}(Tone_core_Tone);\n/** Tone.js module by Yotam Mann, MIT License 2014  http://opensource.org/licenses/MIT **/\nvar Tone_signal_WaveShaper;\nTone_signal_WaveShaper = function (Tone) {\n  'use strict';\n  Tone.WaveShaper = function (mapping, bufferLen) {\n    this._shaper = this.input = this.output = this.context.createWaveShaper();\n    this._curve = null;\n    if (Array.isArray(mapping)) {\n      this.setCurve(mapping);\n    } else if (isFinite(mapping) || this.isUndef(mapping)) {\n      this._curve = new Float32Array(this.defaultArg(mapping, 1024));\n    } else if (typeof mapping === 'function') {\n      this._curve = new Float32Array(this.defaultArg(bufferLen, 1024));\n      this.setMap(mapping);\n    }\n  };\n  Tone.extend(Tone.WaveShaper, Tone.SignalBase);\n  Tone.WaveShaper.prototype.setMap = function (mapping) {\n    for (var i = 0, len = this._curve.length; i < len; i++) {\n      var normalized = i / len * 2 - 1;\n      var normOffOne = i / (len - 1) * 2 - 1;\n      this._curve[i] = mapping(normalized, i, normOffOne);\n    }\n    this._shaper.curve = this._curve;\n  };\n  Tone.WaveShaper.prototype.setCurve = function (mapping) {\n    if (this._isSafari()) {\n      var first = mapping[0];\n      mapping.unshift(first);\n    }\n    this._curve = new Float32Array(mapping);\n    this._shaper.curve = this._curve;\n  };\n  Tone.WaveShaper.prototype.setOversample = function (oversampling) {\n    this._shaper.oversample = oversampling;\n  };\n  Tone.WaveShaper.prototype._isSafari = function () {\n    var ua = navigator.userAgent.toLowerCase();\n    return ua.indexOf('safari') !== -1 && ua.indexOf('chrome') === -1;\n  };\n  Tone.WaveShaper.prototype.dispose = function () {\n    Tone.prototype.dispose.call(this);\n    this._shaper.disconnect();\n    this._shaper = null;\n    this._curve = null;\n  };\n  return Tone.WaveShaper;\n}(Tone_core_Tone);\n/** Tone.js module by Yotam Mann, MIT License 2014  http://opensource.org/licenses/MIT **/\nvar Tone_signal_Signal;\nTone_signal_Signal = function (Tone) {\n  'use strict';\n  Tone.Signal = function (value) {\n    this._scalar = this.context.createGain();\n    this.input = this.output = this.context.createGain();\n    this._syncRatio = 1;\n    this.value = this.defaultArg(value, 0);\n    Tone.Signal._constant.chain(this._scalar, this.output);\n  };\n  Tone.extend(Tone.Signal, Tone.SignalBase);\n  Tone.Signal.prototype.getValue = function () {\n    return this._scalar.gain.value;\n  };\n  Tone.Signal.prototype.setValue = function (value) {\n    if (this._syncRatio === 0) {\n      value = 0;\n    } else {\n      value *= this._syncRatio;\n    }\n    this._scalar.gain.value = value;\n  };\n  Tone.Signal.prototype.setValueAtTime = function (value, time) {\n    value *= this._syncRatio;\n    this._scalar.gain.setValueAtTime(value, this.toSeconds(time));\n  };\n  Tone.Signal.prototype.setCurrentValueNow = function (now) {\n    now = this.defaultArg(now, this.now());\n    var currentVal = this.getValue();\n    this.cancelScheduledValues(now);\n    this._scalar.gain.setValueAtTime(currentVal, now);\n    return currentVal;\n  };\n  Tone.Signal.prototype.linearRampToValueAtTime = function (value, endTime) {\n    value *= this._syncRatio;\n    this._scalar.gain.linearRampToValueAtTime(value, this.toSeconds(endTime));\n  };\n  Tone.Signal.prototype.exponentialRampToValueAtTime = function (value, endTime) {\n    value *= this._syncRatio;\n    try {\n      this._scalar.gain.exponentialRampToValueAtTime(value, this.toSeconds(endTime));\n    } catch (e) {\n      this._scalar.gain.linearRampToValueAtTime(value, this.toSeconds(endTime));\n    }\n  };\n  Tone.Signal.prototype.exponentialRampToValueNow = function (value, endTime) {\n    var now = this.now();\n    this.setCurrentValueNow(now);\n    if (endTime.toString().charAt(0) === '+') {\n      endTime = endTime.substr(1);\n    }\n    this.exponentialRampToValueAtTime(value, now + this.toSeconds(endTime));\n  };\n  Tone.Signal.prototype.linearRampToValueNow = function (value, endTime) {\n    var now = this.now();\n    this.setCurrentValueNow(now);\n    value *= this._syncRatio;\n    if (endTime.toString().charAt(0) === '+') {\n      endTime = endTime.substr(1);\n    }\n    this._scalar.gain.linearRampToValueAtTime(value, now + this.toSeconds(endTime));\n  };\n  Tone.Signal.prototype.setTargetAtTime = function (value, startTime, timeConstant) {\n    value *= this._syncRatio;\n    this._scalar.gain.setTargetAtTime(value, this.toSeconds(startTime), timeConstant);\n  };\n  Tone.Signal.prototype.setValueCurveAtTime = function (values, startTime, duration) {\n    for (var i = 0; i < values.length; i++) {\n      values[i] *= this._syncRatio;\n    }\n    this._scalar.gain.setValueCurveAtTime(values, this.toSeconds(startTime), this.toSeconds(duration));\n  };\n  Tone.Signal.prototype.cancelScheduledValues = function (startTime) {\n    this._scalar.gain.cancelScheduledValues(this.toSeconds(startTime));\n  };\n  Tone.Signal.prototype.sync = function (signal, ratio) {\n    if (ratio) {\n      this._syncRatio = ratio;\n    } else {\n      if (signal.getValue() !== 0) {\n        this._syncRatio = this.getValue() / signal.getValue();\n      } else {\n        this._syncRatio = 0;\n      }\n    }\n    this._scalar.disconnect();\n    this._scalar = this.context.createGain();\n    this.connectSeries(signal, this._scalar, this.output);\n    this._scalar.gain.value = this._syncRatio;\n  };\n  Tone.Signal.prototype.unsync = function () {\n    var currentGain = this.getValue();\n    this._scalar.disconnect();\n    this._scalar = this.context.createGain();\n    this._scalar.gain.value = currentGain / this._syncRatio;\n    this._syncRatio = 1;\n    Tone.Signal._constant.chain(this._scalar, this.output);\n  };\n  Tone.Signal.prototype.dispose = function () {\n    Tone.prototype.dispose.call(this);\n    this._scalar.disconnect();\n    this._scalar = null;\n  };\n  Object.defineProperty(Tone.Signal.prototype, 'value', {\n    get: function () {\n      return this.getValue();\n    },\n    set: function (val) {\n      this.setValue(val);\n    }\n  });\n  Tone.Signal._generator = null;\n  Tone.Signal._constant = null;\n  Tone._initAudioContext(function (audioContext) {\n    Tone.Signal._generator = audioContext.createOscillator();\n    Tone.Signal._constant = new Tone.WaveShaper([\n      1,\n      1\n    ]);\n    Tone.Signal._generator.connect(Tone.Signal._constant);\n    Tone.Signal._generator.start(0);\n    Tone.Signal._generator.noGC();\n  });\n  return Tone.Signal;\n}(Tone_core_Tone);\n/** Tone.js module by Yotam Mann, MIT License 2014  http://opensource.org/licenses/MIT **/\nvar Tone_signal_Add;\nTone_signal_Add = function (Tone) {\n  'use strict';\n  Tone.Add = function (value) {\n    Tone.call(this, 2, 0);\n    this._sum = this.input[0] = this.input[1] = this.output = this.context.createGain();\n    this._value = null;\n    if (isFinite(value)) {\n      this._value = new Tone.Signal(value);\n      this._value.connect(this._sum);\n    }\n  };\n  Tone.extend(Tone.Add, Tone.SignalBase);\n  Tone.Add.prototype.setValue = function (value) {\n    if (this._value !== null) {\n      this._value.setValue(value);\n    } else {\n      throw new Error('cannot switch from signal to number');\n    }\n  };\n  Tone.Add.prototype.dispose = function () {\n    Tone.prototype.dispose.call(this);\n    this._sum = null;\n    if (this._value) {\n      this._value.dispose();\n      this._value = null;\n    }\n  };\n  return Tone.Add;\n}(Tone_core_Tone);\n/** Tone.js module by Yotam Mann, MIT License 2014  http://opensource.org/licenses/MIT **/\nvar Tone_signal_Multiply;\nTone_signal_Multiply = function (Tone) {\n  'use strict';\n  Tone.Multiply = function (value) {\n    Tone.call(this, 2, 0);\n    this._mult = this.input[0] = this.output = this.context.createGain();\n    this._factor = this.input[1] = this.output.gain;\n    this._factor.value = this.defaultArg(value, 0);\n  };\n  Tone.extend(Tone.Multiply, Tone.SignalBase);\n  Tone.Multiply.prototype.setValue = function (value) {\n    this._factor.value = value;\n  };\n  Tone.Multiply.prototype.dispose = function () {\n    Tone.prototype.dispose.call(this);\n    this._mult = null;\n    this._factor = null;\n  };\n  return Tone.Multiply;\n}(Tone_core_Tone);\n/** Tone.js module by Yotam Mann, MIT License 2014  http://opensource.org/licenses/MIT **/\nvar Tone_signal_Scale;\nTone_signal_Scale = function (Tone) {\n  'use strict';\n  Tone.Scale = function (outputMin, outputMax) {\n    this._outputMin = this.defaultArg(outputMin, 0);\n    this._outputMax = this.defaultArg(outputMax, 1);\n    this._scale = this.input = new Tone.Multiply(1);\n    this._add = this.output = new Tone.Add(0);\n    this._scale.connect(this._add);\n    this._setRange();\n  };\n  Tone.extend(Tone.Scale, Tone.SignalBase);\n  Tone.Scale.prototype.setMin = function (min) {\n    this._outputMin = min;\n    this._setRange();\n  };\n  Tone.Scale.prototype.setMax = function (max) {\n    this._outputMax = max;\n    this._setRange();\n  };\n  Tone.Scale.prototype._setRange = function () {\n    this._add.setValue(this._outputMin);\n    this._scale.setValue(this._outputMax - this._outputMin);\n  };\n  Tone.Scale.prototype.dispose = function () {\n    Tone.prototype.dispose.call(this);\n    this._add.dispose();\n    this._add = null;\n    this._scale.dispose();\n    this._scale = null;\n  };\n  return Tone.Scale;\n}(Tone_core_Tone, Tone_signal_Add, Tone_signal_Multiply);\nvar signal;\nsignal = function () {\n  'use strict';\n  // Signal is built with the Tone.js signal by Yotam Mann\n  // https://github.com/TONEnoTONE/Tone.js/\n  var Signal = Tone_signal_Signal;\n  var Add = Tone_signal_Add;\n  var Mult = Tone_signal_Multiply;\n  var Scale = Tone_signal_Scale;\n  var Tone = Tone_core_Tone;\n  var p5sound = master;\n  Tone.setContext(p5sound.audiocontext);\n  /**\n   *  <p>p5.Signal is a constant audio-rate signal used by p5.Oscillator\n   *  and p5.Envelope for modulation math.</p>\n   *\n   *  <p>This is necessary because Web Audio is processed on a seprate clock.\n   *  For example, the p5 draw loop runs about 60 times per second. But\n   *  the audio clock must process samples 44100 times per second. If we\n   *  want to add a value to each of those samples, we can't do it in the\n   *  draw loop, but we can do it by adding a constant-rate audio signal.</p.\n   *  \n   *  <p>This class mostly functions behind the scenes in p5.sound, and returns\n   *  a Tone.Signal from the Tone.js library by Yotam Mann.\n   *  If you want to work directly with audio signals for modular\n   *  synthesis, check out\n   *  <a href='http://bit.ly/1oIoEng' target=_'blank'>tone.js.</a></p>\n   *\n   *  @class  p5.Signal\n   *  @constructor\n   *  @return {Tone.Signal} A Signal object from the Tone.js library\n   *  @example\n   *  <div><code>\n   *  function setup() {\n   *    carrier = new p5.Oscillator('sine');\n   *    carrier.amp(1); // set amplitude\n   *    carrier.freq(220); // set frequency\n   *    carrier.start(); // start oscillating\n   *    \n   *    modulator = new p5.Oscillator('sawtooth');\n   *    modulator.disconnect();\n   *    modulator.amp(1);\n   *    modulator.freq(4);\n   *    modulator.start();\n   *\n   *    // Modulator's default amplitude range is -1 to 1.\n   *    // Multiply it by -200, so the range is -200 to 200\n   *    // then add 220 so the range is 20 to 420\n   *    carrier.freq( modulator.mult(-200).add(220) );\n   *  }\n   *  </code></div>\n   */\n  p5.Signal = function (value) {\n    var s = new Signal(value);\n    // p5sound.soundArray.push(s);\n    return s;\n  };\n  /**\n   *  Fade to value, for smooth transitions\n   *\n   *  @method  fade\n   *  @param  {Number} value          Value to set this signal\n   *  @param  {[Number]} secondsFromNow Length of fade, in seconds from now\n   */\n  Signal.prototype.fade = Signal.prototype.linearRampToValueAtTime;\n  Mult.prototype.fade = Signal.prototype.fade;\n  Add.prototype.fade = Signal.prototype.fade;\n  Scale.prototype.fade = Signal.prototype.fade;\n  /**\n   *  Connect a p5.sound object or Web Audio node to this\n   *  p5.Signal so that its amplitude values can be scaled.\n   *  \n   *  @param {Object} input\n   */\n  Signal.prototype.setInput = function (_input) {\n    _input.connect(this);\n  };\n  Mult.prototype.setInput = Signal.prototype.setInput;\n  Add.prototype.setInput = Signal.prototype.setInput;\n  Scale.prototype.setInput = Signal.prototype.setInput;\n  // signals can add / mult / scale themselves\n  /**\n   *  Add a constant value to this audio signal,\n   *  and return the resulting audio signal. Does\n   *  not change the value of the original signal,\n   *  instead it returns a new p5.SignalAdd.\n   *  \n   *  @method  add\n   *  @param {Number} number\n   *  @return {p5.SignalAdd} object\n   */\n  Signal.prototype.add = function (num) {\n    var add = new Add(num);\n    // add.setInput(this);\n    this.connect(add);\n    return add;\n  };\n  Mult.prototype.add = Signal.prototype.add;\n  Add.prototype.add = Signal.prototype.add;\n  Scale.prototype.add = Signal.prototype.add;\n  /**\n   *  Multiply this signal by a constant value,\n   *  and return the resulting audio signal. Does\n   *  not change the value of the original signal,\n   *  instead it returns a new p5.SignalMult.\n   *  \n   *  @method  mult\n   *  @param {Number} number to multiply\n   *  @return {Tone.Multiply} object\n   */\n  Signal.prototype.mult = function (num) {\n    var mult = new Mult(num);\n    // mult.setInput(this);\n    this.connect(mult);\n    return mult;\n  };\n  Mult.prototype.mult = Signal.prototype.mult;\n  Add.prototype.mult = Signal.prototype.mult;\n  Scale.prototype.mult = Signal.prototype.mult;\n  /**\n   *  Scale this signal value to a given range,\n   *  and return the result as an audio signal. Does\n   *  not change the value of the original signal,\n   *  instead it returns a new p5.SignalScale.\n   *  \n   *  @method  scale\n   *  @param {Number} number to multiply\n   *  @param  {Number} inMin  input range minumum\n   *  @param  {Number} inMax  input range maximum\n   *  @param  {Number} outMin input range minumum\n   *  @param  {Number} outMax input range maximum\n   *  @return {p5.SignalScale} object\n   */\n  Signal.prototype.scale = function (inMin, inMax, outMin, outMax) {\n    var mapOutMin, mapOutMax;\n    if (arguments.length === 4) {\n      mapOutMin = p5.prototype.map(outMin, inMin, inMax, 0, 1) - 0.5;\n      mapOutMax = p5.prototype.map(outMax, inMin, inMax, 0, 1) - 0.5;\n    } else {\n      mapOutMin = arguments[0];\n      mapOutMax = arguments[1];\n    }\n    var scale = new Scale(mapOutMin, mapOutMax);\n    this.connect(scale);\n    return scale;\n  };\n  Mult.prototype.scale = Signal.prototype.scale;\n  Add.prototype.scale = Signal.prototype.scale;\n  Scale.prototype.scale = Signal.prototype.scale;\n}(Tone_signal_Signal, Tone_signal_Add, Tone_signal_Multiply, Tone_signal_Scale, Tone_core_Tone, master);\nvar oscillator;\noscillator = function () {\n  'use strict';\n  var p5sound = master;\n  var Signal = Tone_signal_Signal;\n  var Add = Tone_signal_Add;\n  var Mult = Tone_signal_Multiply;\n  var Scale = Tone_signal_Scale;\n  /**\n   *  <p>Creates a signal that oscillates between -1.0 and 1.0.\n   *  By default, the oscillation takes the form of a sinusoidal\n   *  shape ('sine'). Additional types include 'triangle',\n   *  'sawtooth' and 'square'. The frequency defaults to\n   *  440 oscillations per second (440Hz, equal to the pitch of an\n   *  'A' note).</p> \n   *\n   *  <p>Set the type of oscillation with setType(), or by creating a\n   *  specific oscillator.</p> For example:\n   *  <code>new p5.SinOsc(freq)</code>\n   *  <code>new p5.TriOsc(freq)</code>\n   *  <code>new p5.SqrOsc(freq)</code>\n   *  <code>new p5.SawOsc(freq)</code>.\n   *  </p>\n   *  \n   *  @class p5.Oscillator\n   *  @constructor\n   *  @param {Number} [freq] frequency defaults to 440Hz\n   *  @param {String} [type] type of oscillator. Options:\n   *                         'sine' (default), 'triangle',\n   *                         'sawtooth', 'square'\n   *  @return {Object}    Oscillator object\n   */\n  p5.Oscillator = function (freq, type) {\n    if (typeof freq === 'string') {\n      var f = type;\n      type = freq;\n      freq = f;\n    }\n    if (typeof type === 'number') {\n      var f = type;\n      type = freq;\n      freq = f;\n    }\n    this.started = false;\n    // components\n    this.oscillator = p5sound.audiocontext.createOscillator();\n    this.f = freq || 440;\n    // frequency\n    this.oscillator.frequency.setValueAtTime(this.f, p5sound.audiocontext.currentTime);\n    this.oscillator.type = type || 'sine';\n    var o = this.oscillator;\n    // connections\n    this.input = p5sound.audiocontext.createGain();\n    this.output = p5sound.audiocontext.createGain();\n    this._freqMods = [];\n    // modulators connected to this oscillator's frequency\n    // set default output gain to 0.5\n    this.output.gain.value = 0.5;\n    this.output.gain.setValueAtTime(0.5, p5sound.audiocontext.currentTime);\n    this.oscillator.connect(this.output);\n    // stereo panning\n    this.panPosition = 0;\n    this.connection = p5sound.input;\n    // connect to p5sound by default\n    this.panner = new p5.Panner(this.output, this.connection, 1);\n    //array of math operation signal chaining\n    this.mathOps = [this.output];\n    // add to the soundArray so we can dispose of the osc later\n    p5sound.soundArray.push(this);\n  };\n  /**\n   *  Start an oscillator. Accepts an optional parameter to\n   *  determine how long (in seconds from now) until the\n   *  oscillator starts.\n   *\n   *  @method  start\n   *  @param  {Number} [time] startTime in seconds from now.\n   *  @param  {Number} [frequency] frequency in Hz.\n   */\n  p5.Oscillator.prototype.start = function (time, f) {\n    if (this.started) {\n      var now = p5sound.audiocontext.currentTime;\n      this.stop(now);\n    }\n    if (!this.started) {\n      var freq = f || this.f;\n      var type = this.oscillator.type;\n      // var detune = this.oscillator.frequency.value;\n      this.oscillator = p5sound.audiocontext.createOscillator();\n      this.oscillator.frequency.exponentialRampToValueAtTime(Math.abs(freq), p5sound.audiocontext.currentTime);\n      this.oscillator.type = type;\n      // this.oscillator.detune.value = detune;\n      this.oscillator.connect(this.output);\n      time = time || 0;\n      this.oscillator.start(time + p5sound.audiocontext.currentTime);\n      this.freqNode = this.oscillator.frequency;\n      // if other oscillators are already connected to this osc's freq\n      for (var i in this._freqMods) {\n        if (typeof this._freqMods[i].connect !== 'undefined') {\n          this._freqMods[i].connect(this.oscillator.frequency);\n        }\n      }\n      this.started = true;\n    }\n  };\n  /**\n   *  Stop an oscillator. Accepts an optional parameter\n   *  to determine how long (in seconds from now) until the\n   *  oscillator stops.\n   *\n   *  @method  stop\n   *  @param  {Number} secondsFromNow Time, in seconds from now.\n   */\n  p5.Oscillator.prototype.stop = function (time) {\n    if (this.started) {\n      var t = time || 0;\n      var now = p5sound.audiocontext.currentTime;\n      this.oscillator.stop(t + now);\n      this.started = false;\n    }\n  };\n  /**\n   *  Set the amplitude between 0 and 1.0. Or, pass in an object\n   *  such as an oscillator to modulate amplitude with an audio signal.\n   *\n   *  @method  amp\n   *  @param  {Number|Object} vol between 0 and 1.0\n   *                              or a modulating signal/oscillator\n   *  @param {Number} [rampTime] create a fade that lasts rampTime \n   *  @param {Number} [timeFromNow] schedule this event to happen\n   *                                seconds from now\n   *  @return  {AudioParam} gain  If no value is provided,\n   *                              returns the Web Audio API\n   *                              AudioParam that controls\n   *                              this oscillator's\n   *                              gain/amplitude/volume)\n   */\n  p5.Oscillator.prototype.amp = function (vol, rampTime, tFromNow) {\n    var self = this;\n    if (typeof vol === 'number') {\n      var rampTime = rampTime || 0;\n      var tFromNow = tFromNow || 0;\n      var now = p5sound.audiocontext.currentTime;\n      var currentVol = this.output.gain.value;\n      this.output.gain.cancelScheduledValues(now);\n      this.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow);\n      this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime);\n    } else if (vol) {\n      console.log(vol);\n      vol.connect(self.output.gain);\n    } else {\n      // return the Gain Node\n      return this.output.gain;\n    }\n  };\n  // these are now the same thing\n  p5.Oscillator.prototype.fade = p5.Oscillator.prototype.amp;\n  p5.Oscillator.prototype.getAmp = function () {\n    return this.output.gain.value;\n  };\n  /**\n   *  Set frequency of an oscillator to a value. Or, pass in an object\n   *  such as an oscillator to modulate the frequency with an audio signal.\n   *\n   *  @method  freq\n   *  @param  {Number|Object} Frequency Frequency in Hz\n   *                                        or modulating signal/oscillator\n   *  @param  {Number} [rampTime] Ramp time (in seconds)\n   *  @param  {Number} [timeFromNow] Schedule this event to happen\n   *                                   at x seconds from now\n   *  @return  {AudioParam} Frequency If no value is provided,\n   *                                  returns the Web Audio API\n   *                                  AudioParam that controls\n   *                                  this oscillator's frequency\n   *  @example\n   *  <div><code>\n   *  var osc = new p5.Oscillator(300);\n   *  osc.start();\n   *  osc.freq(40, 10);\n   *  </code></div>\n   */\n  p5.Oscillator.prototype.freq = function (val, rampTime, tFromNow) {\n    if (typeof val === 'number' && !isNaN(val)) {\n      this.f = val;\n      var now = p5sound.audiocontext.currentTime;\n      var rampTime = rampTime || 0;\n      var tFromNow = tFromNow || 0;\n      var currentFreq = this.oscillator.frequency.value;\n      this.oscillator.frequency.cancelScheduledValues(now);\n      this.oscillator.frequency.setValueAtTime(currentFreq, now + tFromNow);\n      if (val > 0) {\n        this.oscillator.frequency.exponentialRampToValueAtTime(val, tFromNow + rampTime + now);\n      } else {\n        this.oscillator.frequency.linearRampToValueAtTime(val, tFromNow + rampTime + now);\n      }\n    } else if (val) {\n      if (val.output) {\n        val = val.output;\n      }\n      val.connect(this.oscillator.frequency);\n      // keep track of what is modulating this param\n      // so it can be re-connected if \n      this._freqMods.push(val);\n    } else {\n      // return the Frequency Node\n      return this.oscillator.frequency;\n    }\n  };\n  p5.Oscillator.prototype.getFreq = function () {\n    return this.oscillator.frequency.value;\n  };\n  /**\n   *  Set type to 'sine', 'triangle', 'sawtooth' or 'square'.\n   *\n   *  @method  setType\n   *  @param {String} type 'sine', 'triangle', 'sawtooth' or 'square'.\n   */\n  p5.Oscillator.prototype.setType = function (type) {\n    this.oscillator.type = type;\n  };\n  p5.Oscillator.prototype.getType = function () {\n    return this.oscillator.type;\n  };\n  /**\n   *  Connect to a p5.sound / Web Audio object.\n   *\n   *  @method  connect\n   *  @param  {Object} unit A p5.sound or Web Audio object\n   */\n  p5.Oscillator.prototype.connect = function (unit) {\n    if (!unit) {\n      this.panner.connect(p5sound.input);\n    } else if (unit.hasOwnProperty('input')) {\n      this.panner.connect(unit.input);\n      this.connection = unit.input;\n    } else {\n      this.panner.connect(unit);\n      this.connection = unit;\n    }\n  };\n  /**\n   *  Disconnect all outputs\n   *\n   *  @method  disconnect\n   */\n  p5.Oscillator.prototype.disconnect = function (unit) {\n    this.output.disconnect();\n    this.panner.disconnect();\n    this.output.connect(this.panner);\n    this.oscMods = [];\n  };\n  /**\n   *  Pan between Left (-1) and Right (1)\n   *\n   *  @method  pan\n   *  @param  {Number} panning Number between -1 and 1\n   *  @param  {Number} timeFromNow schedule this event to happen\n   *                                seconds from now\n   */\n  p5.Oscillator.prototype.pan = function (pval, tFromNow) {\n    this.panPosition = pval;\n    this.panner.pan(pval, tFromNow);\n  };\n  p5.Oscillator.prototype.getPan = function () {\n    return this.panPosition;\n  };\n  // get rid of the oscillator\n  p5.Oscillator.prototype.dispose = function () {\n    if (this.oscillator) {\n      var now = p5sound.audiocontext.currentTime;\n      this.stop(now);\n      this.disconnect();\n      this.oscillator.disconnect();\n      this.panner = null;\n      this.oscillator = null;\n    }\n    // if it is a Pulse\n    if (this.osc2) {\n      this.osc2.dispose();\n    }\n  };\n  /**\n   *  Set the phase of an oscillator between 0.0 and 1.0\n   *  \n   *  @method  phase\n   *  @param  {Number} phase float between 0.0 and 1.0\n   */\n  p5.Oscillator.prototype.phase = function (p) {\n    if (!this.dNode) {\n      // create a delay node\n      this.dNode = p5sound.audiocontext.createDelay();\n      // put the delay node in between output and panner\n      this.output.disconnect();\n      this.output.connect(this.dNode);\n      this.dNode.connect(this.panner);\n    }\n    // set delay time based on PWM width\n    var now = p5sound.audiocontext.currentTime;\n    this.dNode.delayTime.linearRampToValueAtTime(p5.prototype.map(p, 0, 1, 0, 1 / this.oscillator.frequency.value), now);\n  };\n  // ========================== //\n  // SIGNAL MATH FOR MODULATION //\n  // ========================== //\n  // return sigChain(this, scale, thisChain, nextChain, Scale);\n  var sigChain = function (o, mathObj, thisChain, nextChain, type) {\n    var chainSource = o.oscillator;\n    // if this type of math already exists in the chain, replace it\n    for (var i in o.mathOps) {\n      if (o.mathOps[i] instanceof type) {\n        chainSource.disconnect();\n        o.mathOps[i].dispose();\n        thisChain = i;\n        // assume nextChain is output gain node unless...\n        if (thisChain < o.mathOps.length - 2) {\n          nextChain = o.mathOps[i + 1];\n        }\n      }\n    }\n    if (thisChain == o.mathOps.length - 1) {\n      o.mathOps.push(nextChain);\n    }\n    // assume source is the oscillator unless i > 0\n    if (i > 0) {\n      chainSource = o.mathOps[i - 1];\n    }\n    chainSource.disconnect();\n    chainSource.connect(mathObj);\n    mathObj.connect(nextChain);\n    o.mathOps[thisChain] = mathObj;\n    return o;\n  };\n  /**\n   *  Add a value to the p5.Oscillator's output amplitude,\n   *  and return the oscillator. Calling this method again\n   *  will override the initial add() with a new value.\n   *  \n   *  @method  add\n   *  @param {Number} number Constant number to add\n   *  @return {p5.Oscillator} Oscillator Returns this oscillator\n   *                                     with scaled output\n   *  \n   */\n  p5.Oscillator.prototype.add = function (num) {\n    var add = new Add(num);\n    var thisChain = this.mathOps.length - 1;\n    var nextChain = this.output;\n    return sigChain(this, add, thisChain, nextChain, Add);\n  };\n  /**\n   *  Multiply the p5.Oscillator's output amplitude\n   *  by a fixed value (i.e. turn it up!). Calling this method\n   *  again will override the initial mult() with a new value.\n   *  \n   *  @method  mult\n   *  @param {Number} number Constant number to multiply\n   *  @return {p5.Oscillator} Oscillator Returns this oscillator\n   *                                     with multiplied output\n   */\n  p5.Oscillator.prototype.mult = function (num) {\n    var mult = new Mult(num);\n    var thisChain = this.mathOps.length - 1;\n    var nextChain = this.output;\n    return sigChain(this, mult, thisChain, nextChain, Mult);\n  };\n  /**\n   *  Scale this oscillator's amplitude values to a given\n   *  range, and return the oscillator. Calling this method\n   *  again will override the initial scale() with new values.\n   *  \n   *  @method  scale\n   *  @param  {Number} inMin  input range minumum\n   *  @param  {Number} inMax  input range maximum\n   *  @param  {Number} outMin input range minumum\n   *  @param  {Number} outMax input range maximum\n   *  @return {p5.Oscillator} Oscillator Returns this oscillator\n   *                                     with scaled output\n   */\n  p5.Oscillator.prototype.scale = function (inMin, inMax, outMin, outMax) {\n    var mapOutMin, mapOutMax;\n    if (arguments.length === 4) {\n      mapOutMin = p5.prototype.map(outMin, inMin, inMax, 0, 1) - 0.5;\n      mapOutMax = p5.prototype.map(outMax, inMin, inMax, 0, 1) - 0.5;\n    } else {\n      mapOutMin = arguments[0];\n      mapOutMax = arguments[1];\n    }\n    var scale = new Scale(mapOutMin, mapOutMax);\n    var thisChain = this.mathOps.length - 1;\n    var nextChain = this.output;\n    return sigChain(this, scale, thisChain, nextChain, Scale);\n  };\n  // ============================== //\n  // SinOsc, TriOsc, SqrOsc, SawOsc //\n  // ============================== //\n  /**\n   *  Constructor: <code>new p5.SinOsc()</code>.\n   *  This creates a Sine Wave Oscillator and is\n   *  equivalent to <code> new p5.Oscillator('sine')\n   *  </code> or creating a p5.Oscillator and then calling\n   *  its method <code>setType('sine')</code>.\n   *  See p5.Oscillator for methods.\n   *\n   *  @method  p5.SinOsc\n   *  @param {[Number]} freq Set the frequency\n   */\n  p5.SinOsc = function (freq) {\n    p5.Oscillator.call(this, freq, 'sine');\n  };\n  p5.SinOsc.prototype = Object.create(p5.Oscillator.prototype);\n  /**\n   *  Constructor: <code>new p5.TriOsc()</code>.\n   *  This creates a Triangle Wave Oscillator and is\n   *  equivalent to <code>new p5.Oscillator('triangle')\n   *  </code> or creating a p5.Oscillator and then calling\n   *  its method <code>setType('triangle')</code>.\n   *  See p5.Oscillator for methods.\n   *\n   *  @method  p5.TriOsc\n   *  @param {[Number]} freq Set the frequency\n   */\n  p5.TriOsc = function (freq) {\n    p5.Oscillator.call(this, freq, 'triangle');\n  };\n  p5.TriOsc.prototype = Object.create(p5.Oscillator.prototype);\n  /**\n   *  Constructor: <code>new p5.SawOsc()</code>.\n   *  This creates a SawTooth Wave Oscillator and is\n   *  equivalent to <code> new p5.Oscillator('sawtooth')\n   *  </code> or creating a p5.Oscillator and then calling\n   *  its method <code>setType('sawtooth')</code>.\n   *  See p5.Oscillator for methods.\n   *\n   *  @method  p5.SawOsc\n   *  @param {[Number]} freq Set the frequency\n   */\n  p5.SawOsc = function (freq) {\n    p5.Oscillator.call(this, freq, 'sawtooth');\n  };\n  p5.SawOsc.prototype = Object.create(p5.Oscillator.prototype);\n  /**\n   *  Constructor: <code>new p5.SqrOsc()</code>.\n   *  This creates a Square Wave Oscillator and is\n   *  equivalent to <code> new p5.Oscillator('square')\n   *  </code> or creating a p5.Oscillator and then calling\n   *  its method <code>setType('square')</code>.\n   *  See p5.Oscillator for methods.\n   *\n   *  @method  p5.SawOsc\n   *  @param {[Number]} freq Set the frequency\n   */\n  p5.SqrOsc = function (freq) {\n    p5.Oscillator.call(this, freq, 'square');\n  };\n  p5.SqrOsc.prototype = Object.create(p5.Oscillator.prototype);\n}(master, Tone_signal_Signal, Tone_signal_Add, Tone_signal_Multiply, Tone_signal_Scale);\nvar env;\nenv = function () {\n  'use strict';\n  var p5sound = master;\n  var Add = Tone_signal_Add;\n  var Mult = Tone_signal_Multiply;\n  var Scale = Tone_signal_Scale;\n  var Tone = Tone_core_Tone;\n  Tone.setContext(p5sound.audiocontext);\n  // oscillator or buffer source to clear on env complete\n  // to save resources if/when it is retriggered\n  var sourceToClear = null;\n  /**\n   *  <p>Envelopes are pre-defined amplitude distribution over time. \n   *  The p5.Env accepts up to four time/level pairs, where time\n   *  determines how long of a ramp before value reaches level.\n   *  Typically, envelopes are used to control the output volume\n   *  of an object, a series of fades referred to as Attack, Decay,\n   *  Sustain and Release (ADSR). But p5.Env can control any\n   *  Web Audio Param, for example it can be passed to an Oscillator\n   *  frequency like osc.freq(env) </p>\n   *  \n   *  @class p5.Env\n   *  @constructor\n   *  @param {Number} aTime     Time (in seconds) before level\n   *                                 reaches attackLevel\n   *  @param {Number} aLevel    Typically an amplitude between\n   *                                 0.0 and 1.0\n   *  @param {Number} dTime      Time\n   *  @param {Number} [dLevel]   Amplitude (In a standard ADSR envelope,\n   *                                 decayLevel = sustainLevel)\n   *  @param {Number} [sTime]   Time (in seconds)\n   *  @param {Number} [sLevel]  Amplitude 0.0 to 1.0\n   *  @param {Number} [rTime]   Time (in seconds)\n   *  @param {Number} [rLevel]  Amplitude 0.0 to 1.0\n   *  @example\n   *  <div><code>\n   *  var aT = 0.1; // attack time in seconds\n   *  var aL = 0.7; // attack level 0.0 to 1.0\n   *  var dT = 0.3; // decay time in seconds\n   *  var dL = 0.1; // decay level  0.0 to 1.0\n   *  var sT = 0.2; // sustain time in seconds\n   *  var sL = dL; // sustain level  0.0 to 1.0\n   *  var rT = 0.5; // release time in seconds\n   *  // release level defaults to zero\n   *\n   *  var env;\n   *  var triOsc;\n   *  \n   *  function setup() {\n   *    env = new p5.Env(aT, aL, dT, dL, sT, sL, rT);\n   *    triOsc = new p5.Oscillator('triangle');\n   *    triOsc.amp(env); // give the env control of the triOsc's amp\n   *    triOsc.start();\n   *    env.play();\n   *  }\n   *  </code></div>\n   */\n  p5.Env = function (t1, l1, t2, l2, t3, l3, t4, l4) {\n    /**\n     * @property attackTime\n     */\n    this.aTime = t1;\n    /**\n     * @property attackLevel\n     */\n    this.aLevel = l1;\n    /**\n     * @property decayTime\n     */\n    this.dTime = t2 || 0;\n    /**\n     * @property decayLevel\n     */\n    this.dLevel = l2 || 0;\n    /**\n     * @property sustainTime\n     */\n    this.sTime = t3 || 0;\n    /**\n     * @property sustainLevel\n     */\n    this.sLevel = l3 || 0;\n    /**\n     * @property releaseTime\n     */\n    this.rTime = t4 || 0;\n    /**\n     * @property releaseLevel\n     */\n    this.rLevel = l4 || 0;\n    this.output = p5sound.audiocontext.createGain();\n    this.control = new p5.Signal();\n    this.control.connect(this.output);\n    this.timeoutID = null;\n    // store clearThing timeouts\n    this.connection = null;\n    // store connection\n    //array of math operation signal chaining\n    this.mathOps = [this.control];\n    // add to the soundArray so we can dispose of the env later\n    p5sound.soundArray.push(this);\n  };\n  /**\n   *  Reset the envelope with a series of time/value pairs.\n   *\n   *  @method  set\n   *  @param {Number} aTime     Time (in seconds) before level\n   *                                 reaches attackLevel\n   *  @param {Number} aLevel    Typically an amplitude between\n   *                                 0.0 and 1.0\n   *  @param {Number} dTime      Time\n   *  @param {Number} [dLevel]   Amplitude (In a standard ADSR envelope,\n   *                                 decayLevel = sustainLevel)\n   *  @param {Number} [sTime]   Time (in seconds)\n   *  @param {Number} [sLevel]  Amplitude 0.0 to 1.0\n   *  @param {Number} [rTime]   Time (in seconds)\n   *  @param {Number} [rLevel]  Amplitude 0.0 to 1.0\n   */\n  p5.Env.prototype.set = function (t1, l1, t2, l2, t3, l3, t4, l4) {\n    this.aTime = t1;\n    this.aLevel = l1;\n    this.dTime = t2 || 0;\n    this.dLevel = l2 || 0;\n    this.sTime = t3 || 0;\n    this.sLevel = l3 || 0;\n    this.rTime = t4 || 0;\n    this.rLevel = l4 || 0;\n  };\n  /**\n   *  \n   *  @param  {Object} input       A p5.sound object or\n   *                                Web Audio Param\n   */\n  p5.Env.prototype.setInput = function (unit) {\n    this.connect(unit);\n  };\n  p5.Env.prototype.ctrl = function (unit) {\n    this.connect(unit);\n  };\n  /**\n   *  Play tells the envelope to start acting on a given input.\n   *  If the input is a p5.sound object (i.e. AudioIn, Oscillator,\n   *  SoundFile), then Env will control its output volume.\n   *  Envelopes can also be used to control any <a href=\"\n   *  http://docs.webplatform.org/wiki/apis/webaudio/AudioParam\">\n   *  Web Audio Audio Param.</a>\n   *\n   *  @method  play\n   *  @param  {Object} unit         A p5.sound object or\n   *                                Web Audio Param.\n   *  @param  {Number} secondsFromNow time from now (in seconds)\n   */\n  p5.Env.prototype.play = function (unit, secondsFromNow) {\n    var now = p5sound.audiocontext.currentTime;\n    var tFromNow = secondsFromNow || 0;\n    var t = now + tFromNow + 0.0001;\n    if (typeof this.timeoutID === 'number') {\n      window.clearTimeout(this.timeoutID);\n    }\n    if (unit) {\n      if (this.connection !== unit) {\n        this.connect(unit);\n      }\n    }\n    this.control.cancelScheduledValues(t - 0.0001);\n    this.control.linearRampToValueAtTime(0, t - 0.00005);\n    // attack\n    this.control.linearRampToValueAtTime(this.aLevel, t + this.aTime);\n    // decay to decay level\n    this.control.linearRampToValueAtTime(this.dLevel, t + this.aTime + this.dTime);\n    // hold sustain level\n    this.control.linearRampToValueAtTime(this.sLevel, t + this.aTime + this.dTime + this.sTime);\n    // release\n    this.control.linearRampToValueAtTime(this.rLevel, t + this.aTime + this.dTime + this.sTime + this.rTime);\n    var clearTime = t + this.aTime + this.dTime + this.sTime + this.rTime;\n  };\n  /**\n   *  Trigger the Attack, Decay, and Sustain of the Envelope.\n   *  Similar to holding down a key on a piano, but it will\n   *  hold the sustain level until you let go. Input can be\n   *  any p5.sound object, or a <a href=\"\n   *  http://docs.webplatform.org/wiki/apis/webaudio/AudioParam\">\n   *  Web Audio Param</a>.\n   *\n   *  @method  triggerAttack\n   *  @param  {Object} unit p5.sound Object or Web Audio Param\n   *  @param  {Number} secondsFromNow time from now (in seconds)\n   */\n  p5.Env.prototype.triggerAttack = function (unit, secondsFromNow) {\n    var now = p5sound.audiocontext.currentTime;\n    var tFromNow = secondsFromNow || 0;\n    var t = now + tFromNow + 0.0001;\n    this.lastAttack = t;\n    if (typeof this.timeoutID === 'number') {\n      window.clearTimeout(this.timeoutID);\n    }\n    var currentVal = this.control.getValue();\n    // not working on Firefox, always returns 0\n    this.control.cancelScheduledValues(t - 0.0001);\n    this.control.linearRampToValueAtTime(currentVal, t - 0.00005);\n    if (unit) {\n      if (this.connection !== unit) {\n        this.connect(unit);\n      }\n    }\n    this.control.linearRampToValueAtTime(this.aLevel, t + this.aTime);\n    // attack\n    this.control.linearRampToValueAtTime(this.aLevel, t + this.aTime);\n    // decay to sustain level\n    this.control.linearRampToValueAtTime(this.dLevel, t + this.aTime + this.dTime);\n    this.control.linearRampToValueAtTime(this.sLevel, t + this.aTime + this.dTime + this.sTime);\n  };\n  /**\n   *  Trigger the Release of the Envelope. This is similar to releasing\n   *  the key on a piano and letting the sound fade according to the\n   *  release level and release time.\n   *\n   *  @method  triggerRelease\n   *  @param  {Object} unit p5.sound Object or Web Audio Param\n   *  @param  {Number} secondsFromNow time to trigger the release\n   */\n  p5.Env.prototype.triggerRelease = function (unit, secondsFromNow) {\n    var now = p5sound.audiocontext.currentTime;\n    var tFromNow = secondsFromNow || 0;\n    var t = now + tFromNow + 0.00001;\n    var relTime;\n    if (unit) {\n      if (this.connection !== unit) {\n        this.connect(unit);\n      }\n    }\n    this.control.cancelScheduledValues(t - 0.00001);\n    // ideally would get & set currentValue here,\n    // but this.control._scalar.gain.value not working in firefox\n    // release based on how much time has passed since this.lastAttack\n    if (now - this.lastAttack < this.aTime) {\n      var a = this.aTime - (t - this.lastAttack);\n      this.control.linearRampToValueAtTime(this.aLevel, t + a);\n      this.control.linearRampToValueAtTime(this.dLevel, t + a + this.dTime);\n      this.control.linearRampToValueAtTime(this.sLevel, t + a + this.dTime + this.sTime);\n      this.control.linearRampToValueAtTime(this.rLevel, t + a + this.dTime + this.sTime + this.rTime);\n      relTime = t + this.dTime + this.sTime + this.rTime;\n    } else if (now - this.lastAttack < this.aTime + this.dTime) {\n      var d = this.aTime + this.dTime - (now - this.lastAttack);\n      this.control.linearRampToValueAtTime(this.dLevel, t + d);\n      // this.control.linearRampToValueAtTime(this.sLevel, t + d + this.sTime);\n      this.control.linearRampToValueAtTime(this.sLevel, t + d + 0.01);\n      this.control.linearRampToValueAtTime(this.rLevel, t + d + 0.01 + this.rTime);\n      relTime = t + this.sTime + this.rTime;\n    } else if (now - this.lastAttack < this.aTime + this.dTime + this.sTime) {\n      var s = this.aTime + this.dTime + this.sTime - (now - this.lastAttack);\n      this.control.linearRampToValueAtTime(this.sLevel, t + s);\n      this.control.linearRampToValueAtTime(this.rLevel, t + s + this.rTime);\n      relTime = t + this.rTime;\n    } else {\n      this.control.linearRampToValueAtTime(this.sLevel, t);\n      this.control.linearRampToValueAtTime(this.rLevel, t + this.rTime);\n      relTime = t + this.dTime + this.sTime + this.rTime;\n    }\n    // clear osc / sources\n    var clearTime = t + this.aTime + this.dTime + this.sTime + this.rTime;\n    // * 1000;\n    if (this.connection && this.connection.hasOwnProperty('oscillator')) {\n      sourceToClear = this.connection.oscillator;\n      sourceToClear.stop(clearTime + 0.01);\n    } else if (this.connect && this.connection.hasOwnProperty('source')) {\n      sourceToClear = this.connection.source;\n      sourceToClear.stop(clearTime + 0.01);\n    }\n  };\n  p5.Env.prototype.connect = function (unit) {\n    this.disconnect();\n    this.connection = unit;\n    // assume we're talking about output gain\n    // unless given a different audio param\n    if (unit instanceof p5.Oscillator || unit instanceof p5.SoundFile || unit instanceof p5.AudioIn || unit instanceof p5.Reverb || unit instanceof p5.Noise || unit instanceof p5.Filter || unit instanceof p5.Delay) {\n      unit = unit.output.gain;\n    }\n    if (unit instanceof AudioParam) {\n      //set the initial value\n      unit.setValueAtTime(0, p5sound.audiocontext.currentTime);\n    }\n    if (unit instanceof p5.Signal) {\n      unit.setValue(0);\n    }\n    this.output.connect(unit);\n  };\n  p5.Env.prototype.disconnect = function (unit) {\n    this.output.disconnect();\n  };\n  // Signal Math\n  /**\n   *  Add a value to the p5.Oscillator's output amplitude,\n   *  and return the oscillator. Calling this method\n   *  again will override the initial add() with new values.\n   *  \n   *  @method  add\n   *  @param {Number} number Constant number to add\n   *  @return {p5.Env} Envelope Returns this envelope\n   *                                     with scaled output\n   */\n  p5.Env.prototype.add = function (num) {\n    var add = new Add(num);\n    var thisChain = this.mathOps.length;\n    var nextChain = this.output;\n    return p5.prototype._mathChain(this, add, thisChain, nextChain, Add);\n  };\n  /**\n   *  Multiply the p5.Env's output amplitude\n   *  by a fixed value. Calling this method\n   *  again will override the initial mult() with new values.\n   *  \n   *  @method  mult\n   *  @param {Number} number Constant number to multiply\n   *  @return {p5.Env} Envelope Returns this envelope\n   *                                     with scaled output\n   */\n  p5.Env.prototype.mult = function (num) {\n    var mult = new Mult(num);\n    var thisChain = this.mathOps.length;\n    var nextChain = this.output;\n    return p5.prototype._mathChain(this, mult, thisChain, nextChain, Mult);\n  };\n  /**\n   *  Scale this envelope's amplitude values to a given\n   *  range, and return the envelope. Calling this method\n   *  again will override the initial scale() with new values.\n   *  \n   *  @method  scale\n   *  @param  {Number} inMin  input range minumum\n   *  @param  {Number} inMax  input range maximum\n   *  @param  {Number} outMin input range minumum\n   *  @param  {Number} outMax input range maximum\n   *  @return {p5.Env} Envelope Returns this envelope\n   *                                     with scaled output\n   */\n  p5.Env.prototype.scale = function (inMin, inMax, outMin, outMax) {\n    var scale = new Scale(inMin, inMax, outMin, outMax);\n    var thisChain = this.mathOps.length;\n    var nextChain = this.output;\n    return p5.prototype._mathChain(this, scale, thisChain, nextChain, Scale);\n  };\n  // get rid of the oscillator\n  p5.Env.prototype.dispose = function () {\n    var now = p5sound.audiocontext.currentTime;\n    this.disconnect();\n    this.control.dispose();\n    this.control = null;\n    for (var i = 1; i < this.mathOps.length; i++) {\n      mathOps[i].dispose();\n    }\n  };\n}(master, Tone_signal_Add, Tone_signal_Multiply, Tone_signal_Scale, Tone_core_Tone);\nvar pulse;\npulse = function () {\n  'use strict';\n  var p5sound = master;\n  /**\n   *  Creates a Pulse object, an oscillator that implements\n   *  Pulse Width Modulation.\n   *  The pulse is created with two oscillators.\n   *  Accepts a parameter for frequency, and to set the\n   *  width between the pulses. See <a href=\"\n   *  http://p5js.org/reference/#/p5.Oscillator\">\n   *  <code>p5.Oscillator</code> for a full list of methods.\n   *  \n   *  @class p5.Pulse\n   *  @constructor\n   *  @param {Number} [freq] Frequency in oscillations per second (Hz)\n   *  @param {Number} [w]    Width between the pulses (0 to 1.0,\n   *                         defaults to 0)\n   *  @example\n   *  <div><code>\n   *  var pulse;\n   *  function setup() {\n   *    background(0);\n   *    \n   *    // Create and start the pulse wave oscillator\n   *    pulse = new p5.Pulse();\n   *    pulse.amp(0.5);\n   *    pulse.freq(220);\n   *    pulse.start();\n   *  }\n   *\n   *  function draw() {\n   *    var w = map(mouseX, 0, width, 0, 1);\n   *    w = constrain(w, 0, 1);\n   *    pulse.width(w)\n   *  }\n   *  </code></div>\n   */\n  p5.Pulse = function (freq, w) {\n    p5.Oscillator.call(this, freq, 'sawtooth');\n    // width of PWM, should be betw 0 to 1.0\n    this.w = w || 0;\n    // create a second oscillator with inverse frequency\n    this.osc2 = new p5.SawOsc(freq);\n    // create a delay node\n    this.dNode = p5sound.audiocontext.createDelay();\n    // dc offset\n    this.dcOffset = createDCOffset();\n    this.dcGain = p5sound.audiocontext.createGain();\n    this.dcOffset.connect(this.dcGain);\n    this.dcGain.connect(this.output);\n    // set delay time based on PWM width\n    this.f = freq || 440;\n    var mW = this.w / this.oscillator.frequency.value;\n    this.dNode.delayTime.value = mW;\n    this.dcGain.gain.value = 1.7 * (0.5 - this.w);\n    // disconnect osc2 and connect it to delay, which is connected to output\n    this.osc2.disconnect();\n    this.osc2.output.gain.minValue = -10;\n    this.osc2.output.gain.maxValue = 10;\n    this.osc2.panner.disconnect();\n    this.osc2.amp(-1);\n    // inverted amplitude\n    this.osc2.output.connect(this.dNode);\n    this.dNode.connect(this.output);\n    this.output.gain.value = 1;\n    this.output.connect(this.panner);\n  };\n  p5.Pulse.prototype = Object.create(p5.Oscillator.prototype);\n  /**\n   *  Set the width of a Pulse object (an oscillator that implements\n   *  Pulse Width Modulation).\n   *\n   *  @method  width\n   *  @param {Number} [width]    Width between the pulses (0 to 1.0,\n   *                         defaults to 0)\n   */\n  p5.Pulse.prototype.width = function (w) {\n    if (typeof w === 'number') {\n      if (w <= 1 && w >= 0) {\n        this.w = w;\n        // set delay time based on PWM width\n        // var mW = map(this.w, 0, 1.0, 0, 1/this.f);\n        var mW = this.w / this.oscillator.frequency.value;\n        this.dNode.delayTime.value = mW;\n      }\n      this.dcGain.gain.value = 1.7 * (0.5 - this.w);\n    } else {\n      w.connect(this.dNode.delayTime);\n      var sig = new p5.SignalAdd(-0.5);\n      sig.setInput(w);\n      sig = sig.mult(-1);\n      sig = sig.mult(1.7);\n      sig.connect(this.dcGain.gain);\n    }\n  };\n  p5.Pulse.prototype.start = function (f, time) {\n    var now = p5sound.audiocontext.currentTime;\n    var t = time || 0;\n    if (!this.started) {\n      var freq = f || this.f;\n      var type = this.oscillator.type;\n      this.oscillator = p5sound.audiocontext.createOscillator();\n      this.oscillator.frequency.setValueAtTime(freq, now);\n      this.oscillator.type = type;\n      this.oscillator.connect(this.output);\n      this.oscillator.start(t + now);\n      // set up osc2\n      this.osc2.oscillator = p5sound.audiocontext.createOscillator();\n      this.osc2.oscillator.frequency.setValueAtTime(freq, t + now);\n      this.osc2.oscillator.type = type;\n      this.osc2.oscillator.connect(this.osc2.output);\n      this.osc2.start(t + now);\n      this.freqNode = [\n        this.oscillator.frequency,\n        this.osc2.oscillator.frequency\n      ];\n      // start dcOffset, too\n      this.dcOffset = createDCOffset();\n      this.dcOffset.connect(this.dcGain);\n      this.dcOffset.start(t + now);\n      // if LFO connections depend on these oscillators\n      if (this.mods !== undefined && this.mods.frequency !== undefined) {\n        this.mods.frequency.connect(this.freqNode[0]);\n        this.mods.frequency.connect(this.freqNode[1]);\n      }\n      this.started = true;\n      this.osc2.started = true;\n    }\n  };\n  p5.Pulse.prototype.stop = function (time) {\n    if (this.started) {\n      var t = time || 0;\n      var now = p5sound.audiocontext.currentTime;\n      this.oscillator.stop(t + now);\n      this.osc2.oscillator.stop(t + now);\n      this.dcOffset.stop(t + now);\n      this.started = false;\n      this.osc2.started = false;\n    }\n  };\n  p5.Pulse.prototype.freq = function (val, rampTime, tFromNow) {\n    if (typeof val === 'number') {\n      this.f = val;\n      var now = p5sound.audiocontext.currentTime;\n      var rampTime = rampTime || 0;\n      var tFromNow = tFromNow || 0;\n      var currentFreq = this.oscillator.frequency.value;\n      this.oscillator.frequency.cancelScheduledValues(now);\n      this.oscillator.frequency.setValueAtTime(currentFreq, now + tFromNow);\n      this.oscillator.frequency.exponentialRampToValueAtTime(val, tFromNow + rampTime + now);\n      this.osc2.oscillator.frequency.cancelScheduledValues(now);\n      this.osc2.oscillator.frequency.setValueAtTime(currentFreq, now + tFromNow);\n      this.osc2.oscillator.frequency.exponentialRampToValueAtTime(val, tFromNow + rampTime + now);\n      if (this.freqMod) {\n        this.freqMod.output.disconnect();\n        this.freqMod = null;\n      }\n    } else if (val.output) {\n      val.output.disconnect();\n      val.output.connect(this.oscillator.frequency);\n      val.output.connect(this.osc2.oscillator.frequency);\n      this.freqMod = val;\n    }\n  };\n  // inspiration: http://webaudiodemos.appspot.com/oscilloscope/\n  function createDCOffset() {\n    var ac = p5sound.audiocontext;\n    var buffer = ac.createBuffer(1, 2048, ac.sampleRate);\n    var data = buffer.getChannelData(0);\n    for (var i = 0; i < 2048; i++)\n      data[i] = 1;\n    var bufferSource = ac.createBufferSource();\n    bufferSource.buffer = buffer;\n    bufferSource.loop = true;\n    return bufferSource;\n  }\n}(master, oscillator);\nvar noise;\nnoise = function () {\n  'use strict';\n  var p5sound = master;\n  /**\n   *  Noise is a type of oscillator that generates a buffer with random values.\n   *\n   *  @class p5.Noise\n   *  @constructor\n   *  @param {String} type Type of noise can be 'white' (default),\n   *                       'brown' or 'pink'.\n   *  @return {Object}    Noise Object\n   */\n  p5.Noise = function (type) {\n    p5.Oscillator.call(this);\n    delete this.f;\n    delete this.freq;\n    delete this.oscillator;\n    this.buffer = _whiteNoise;\n  };\n  p5.Noise.prototype = Object.create(p5.Oscillator.prototype);\n  // generate noise buffers\n  var _whiteNoise = function () {\n    var bufferSize = 2 * p5sound.audiocontext.sampleRate;\n    var whiteBuffer = p5sound.audiocontext.createBuffer(1, bufferSize, p5sound.audiocontext.sampleRate);\n    var noiseData = whiteBuffer.getChannelData(0);\n    for (var i = 0; i < bufferSize; i++) {\n      noiseData[i] = Math.random() * 2 - 1;\n    }\n    whiteBuffer.type = 'white';\n    return whiteBuffer;\n  }();\n  var _pinkNoise = function () {\n    var bufferSize = 2 * p5sound.audiocontext.sampleRate;\n    var pinkBuffer = p5sound.audiocontext.createBuffer(1, bufferSize, p5sound.audiocontext.sampleRate);\n    var noiseData = pinkBuffer.getChannelData(0);\n    var b0, b1, b2, b3, b4, b5, b6;\n    b0 = b1 = b2 = b3 = b4 = b5 = b6 = 0;\n    for (var i = 0; i < bufferSize; i++) {\n      var white = Math.random() * 2 - 1;\n      b0 = 0.99886 * b0 + white * 0.0555179;\n      b1 = 0.99332 * b1 + white * 0.0750759;\n      b2 = 0.969 * b2 + white * 0.153852;\n      b3 = 0.8665 * b3 + white * 0.3104856;\n      b4 = 0.55 * b4 + white * 0.5329522;\n      b5 = -0.7616 * b5 - white * 0.016898;\n      noiseData[i] = b0 + b1 + b2 + b3 + b4 + b5 + b6 + white * 0.5362;\n      noiseData[i] *= 0.11;\n      // (roughly) compensate for gain\n      b6 = white * 0.115926;\n    }\n    pinkBuffer.type = 'pink';\n    return pinkBuffer;\n  }();\n  var _brownNoise = function () {\n    var bufferSize = 2 * p5sound.audiocontext.sampleRate;\n    var brownBuffer = p5sound.audiocontext.createBuffer(1, bufferSize, p5sound.audiocontext.sampleRate);\n    var noiseData = brownBuffer.getChannelData(0);\n    var lastOut = 0;\n    for (var i = 0; i < bufferSize; i++) {\n      var white = Math.random() * 2 - 1;\n      noiseData[i] = (lastOut + 0.02 * white) / 1.02;\n      lastOut = noiseData[i];\n      noiseData[i] *= 3.5;\n    }\n    brownBuffer.type = 'brown';\n    return brownBuffer;\n  }();\n  /**\n   *  Set type of noise to 'white', 'pink' or 'brown'.\n   *  White is the default.\n   *\n   *  @method setType\n   *  @param {String} [type] 'white', 'pink' or 'brown'\n   */\n  p5.Noise.prototype.setType = function (type) {\n    switch (type) {\n    case 'white':\n      this.buffer = _whiteNoise;\n      break;\n    case 'pink':\n      this.buffer = _pinkNoise;\n      break;\n    case 'brown':\n      this.buffer = _brownNoise;\n      break;\n    default:\n      this.buffer = _whiteNoise;\n    }\n    if (this.started) {\n      var now = p5sound.audiocontext.currentTime;\n      this.stop(now);\n      this.start(now + 0.01);\n    }\n  };\n  p5.Noise.prototype.getType = function () {\n    return this.buffer.type;\n  };\n  /**\n   *  Start the noise\n   *\n   *  @method start\n   */\n  p5.Noise.prototype.start = function () {\n    if (this.started) {\n      this.stop();\n    }\n    this.noise = p5sound.audiocontext.createBufferSource();\n    this.noise.buffer = this.buffer;\n    this.noise.loop = true;\n    this.noise.connect(this.output);\n    var now = p5sound.audiocontext.currentTime;\n    this.noise.start(now);\n    this.started = true;\n  };\n  /**\n   *  Stop the noise.\n   *\n   *  @method  stop\n   */\n  p5.Noise.prototype.stop = function () {\n    var now = p5sound.audiocontext.currentTime;\n    if (this.noise) {\n      this.noise.stop(now);\n      this.started = false;\n    }\n  };\n  /**\n   *  Pan the noise.\n   *\n   *  @method  pan\n   *  @param  {Number} panning Number between -1 (left)\n   *                           and 1 (right)\n   *  @param  {Number} timeFromNow schedule this event to happen\n   *                                seconds from now\n   */\n  /**\n   *  Set the amplitude of the noise between 0 and 1.0. Or,\n   *  modulate amplitude with an audio signal such as an oscillator.\n   *  \n   *  @param  {Number|Object} volume amplitude between 0 and 1.0\n   *                                     or modulating signal/oscillator\n   *  @param {Number} [rampTime] create a fade that lasts rampTime \n   *  @param {Number} [timeFromNow] schedule this event to happen\n   *                                seconds from now\n   */\n  /**\n   *  Send output to a p5.sound or web audio object\n   *  \n   *  @method  connect\n   *  @param  {Object} unit\n   */\n  /**\n   *  Disconnect all output.\n   *  \n   *  @method disconnect\n   */\n  p5.Noise.prototype.dispose = function () {\n    var now = p5sound.audiocontext.currentTime;\n    if (this.noise) {\n      this.noise.disconnect();\n      this.stop(now);\n    }\n    if (this.output) {\n      this.output.disconnect();\n    }\n    if (this.panner) {\n      this.panner.disconnect();\n    }\n    this.output = null;\n    this.panner = null;\n    this.buffer = null;\n    this.noise = null;\n  };\n}(master);\nvar audioin;\naudioin = function () {\n  'use strict';\n  var p5sound = master;\n  /**\n   *  <p>Get audio from an input, i.e. your computer's microphone.</p>\n   *\n   *  <p>Turn the mic on/off with the start() and stop() methods. When the mic\n   *  is on, its volume can be measured with getLevel or by connecting an\n   *  FFT object.</p>\n   *  \n   *  <p>If you want to hear the AudioIn, use the .connect() method. \n   *  AudioIn does not connect to p5.sound output by default to prevent\n   *  feedback.</p> \n   *\n   *  <p><em>Note: This uses the <a href=\"http://caniuse.com/stream\">getUserMedia/\n   *  Stream</a> API, which is not supported by certain browsers.</em></p>\n   *\n   *  @class p5.AudioIn\n   *  @constructor\n   *  @return {Object} AudioIn\n   *  @example\n   *  <div><code>\n   *  var mic;\n   *  function setup(){\n   *    mic = new p5.AudioIn()\n   *    mic.start();\n   *  }\n   *  function draw(){\n   *    background(0);\n   *    micLevel = mic.getLevel();\n   *    ellipse(width/2, constrain(height-micLevel*height*5, 0, height), 10, 10);\n   *  }\n   *  </code></div>\n   */\n  p5.AudioIn = function () {\n    // set up audio input\n    this.input = p5sound.audiocontext.createGain();\n    this.output = p5sound.audiocontext.createGain();\n    this.stream = null;\n    this.mediaStream = null;\n    this.currentSource = 0;\n    /**\n     *  Client must allow browser to access their microphone / audioin source.\n     *  Default: false. Will become true when the client enables acces.\n     *\n     *  @property {Boolean} enabled\n     */\n    this.enabled = false;\n    // create an amplitude, connect to it by default but not to master out\n    this.amplitude = new p5.Amplitude();\n    this.output.connect(this.amplitude.input);\n    // Some browsers let developer determine their input sources\n    if (typeof window.MediaStreamTrack === 'undefined') {\n      window.alert('This browser does not support MediaStreamTrack');\n    } else if (typeof window.MediaStreamTrack.getSources !== 'undefined') {\n      // Chrome supports getSources to list inputs. Dev picks default\n      window.MediaStreamTrack.getSources(this._gotSources);\n    } else {\n    }\n    // add to soundArray so we can dispose on close\n    p5sound.soundArray.push(this);\n  };\n  /**\n   *  Start processing audio input. This enables the use of other\n   *  AudioIn methods like getLevel(). Note that by default, AudioIn\n   *  is not connected to p5.sound's output. So you won't hear\n   *  anything unless you use the connect() method.<br/>\n   *\n   *  @method start\n   */\n  p5.AudioIn.prototype.start = function () {\n    var self = this;\n    // if _gotSources() i.e. developers determine which source to use\n    if (p5sound.inputSources[self.currentSource]) {\n      // set the audio source\n      var audioSource = p5sound.inputSources[self.currentSource].id;\n      var constraints = { audio: { optional: [{ sourceId: audioSource }] } };\n      navigator.getUserMedia(constraints, this._onStream = function (stream) {\n        self.stream = stream;\n        self.enabled = true;\n        // Wrap a MediaStreamSourceNode around the live input\n        self.mediaStream = p5sound.audiocontext.createMediaStreamSource(stream);\n        self.mediaStream.connect(self.output);\n        // only send to the Amplitude reader, so we can see it but not hear it.\n        self.amplitude.setInput(self.output);\n      }, this._onStreamError = function (stream) {\n        console.error(stream);\n      });\n    } else {\n      // if Firefox where users select their source via browser\n      // if (typeof MediaStreamTrack.getSources === 'undefined') {\n      // Only get the audio stream.\n      window.navigator.getUserMedia({ 'audio': true }, this._onStream = function (stream) {\n        self.stream = stream;\n        self.enabled = true;\n        // Wrap a MediaStreamSourceNode around the live input\n        self.mediaStream = p5sound.audiocontext.createMediaStreamSource(stream);\n        self.mediaStream.connect(self.output);\n        // only send to the Amplitude reader, so we can see it but not hear it.\n        self.amplitude.setInput(self.output);\n      }, this._onStreamError = function (stream) {\n        console.error(stream);\n      });\n    }\n  };\n  /**\n   *  Turn the AudioIn off. If the AudioIn is stopped, it cannot getLevel().<br/>\n   *\n   *  @method stop\n   */\n  p5.AudioIn.prototype.stop = function () {\n    if (this.stream) {\n      this.stream.stop();\n    }\n  };\n  /**\n   *  Connect to an audio unit. If no parameter is provided, will\n   *  connect to the master output (i.e. your speakers).<br/>\n   *  \n   *  @method  connect\n   *  @param  {Object} [unit] An object that accepts audio input,\n   *                          such as an FFT\n   */\n  p5.AudioIn.prototype.connect = function (unit) {\n    if (unit) {\n      if (unit.hasOwnProperty('input')) {\n        this.output.connect(unit.input);\n      } else if (unit.hasOwnProperty('analyser')) {\n        this.output.connect(unit.analyser);\n      } else {\n        this.output.connect(unit);\n      }\n    } else {\n      this.output.connect(p5sound.input);\n    }\n  };\n  /**\n   *  Disconnect the AudioIn from all audio units. For example, if\n   *  connect() had been called, disconnect() will stop sending \n   *  signal to your speakers.<br/>\n   *\n   *  @method  disconnect\n   */\n  p5.AudioIn.prototype.disconnect = function (unit) {\n    this.output.disconnect(unit);\n    // stay connected to amplitude even if not outputting to p5\n    this.output.connect(this.amplitude.input);\n  };\n  /**\n   *  Read the Amplitude (volume level) of an AudioIn. The AudioIn\n   *  class contains its own instance of the Amplitude class to help\n   *  make it easy to get a microphone's volume level. Accepts an\n   *  optional smoothing value (0.0 < 1.0). <em>NOTE: AudioIn must\n   *  .start() before using .getLevel().</em><br/>\n   *  \n   *  @method  getLevel\n   *  @param  {Number} [smoothing] Smoothing is 0.0 by default.\n   *                               Smooths values based on previous values.\n   *  @return {Number}           Volume level (between 0.0 and 1.0)\n   */\n  p5.AudioIn.prototype.getLevel = function (smoothing) {\n    if (smoothing) {\n      this.amplitude.smoothing = smoothing;\n    }\n    return this.amplitude.getLevel();\n  };\n  /**\n   *  Add input sources to the list of available sources.\n   *  \n   *  @private\n   */\n  p5.AudioIn.prototype._gotSources = function (sourceInfos) {\n    for (var i = 0; i !== sourceInfos.length; i++) {\n      var sourceInfo = sourceInfos[i];\n      if (sourceInfo.kind === 'audio') {\n        // add the inputs to inputSources\n        p5sound.inputSources.push(sourceInfo);\n      }\n    }\n  };\n  /**\n   *  Set amplitude (volume) of a mic input between 0 and 1.0. <br/>\n   *\n   *  @method  amp\n   *  @param  {Number} vol between 0 and 1.0\n   *  @param {Number} [time] ramp time (optional)\n   */\n  p5.AudioIn.prototype.amp = function (vol, t) {\n    if (t) {\n      var rampTime = t || 0;\n      var currentVol = this.output.gain.value;\n      this.output.gain.cancelScheduledValues(p5sound.audiocontext.currentTime);\n      this.output.gain.setValueAtTime(currentVol, p5sound.audiocontext.currentTime);\n      this.output.gain.linearRampToValueAtTime(vol, rampTime + p5sound.audiocontext.currentTime);\n    } else {\n      this.output.gain.cancelScheduledValues(p5sound.audiocontext.currentTime);\n      this.output.gain.setValueAtTime(vol, p5sound.audiocontext.currentTime);\n    }\n  };\n  /**\n   *  Returns a list of available input sources. Some browsers\n   *  give the client the option to set their own media source.\n   *  Others allow JavaScript to determine which source,\n   *  and for this we have listSources() and setSource().<br/>\n   *\n   *  @method  listSources\n   *  @return {Array}\n   */\n  p5.AudioIn.prototype.listSources = function () {\n    console.log('input sources: ');\n    console.log(p5sound.inputSources);\n    if (p5sound.inputSources.length > 0) {\n      return p5sound.inputSources;\n    } else {\n      return 'This browser does not support MediaStreamTrack.getSources()';\n    }\n  };\n  /**\n   *  Set the input source. Accepts a number representing a\n   *  position in the array returned by listSources().\n   *  This is only available in browsers that support \n   *  MediaStreamTrack.getSources(). Instead, some browsers\n   *  give users the option to set their own media source.<br/>\n   *  \n   *  @method setSource\n   *  @param {number} num position of input source in the array\n   */\n  p5.AudioIn.prototype.setSource = function (num) {\n    // TO DO - set input by string or # (array position)\n    var self = this;\n    if (p5sound.inputSources.length > 0 && num < p5sound.inputSources.length) {\n      // set the current source\n      self.currentSource = num;\n      console.log('set source to ' + p5sound.inputSources[self.currentSource].id);\n    } else {\n      console.log('unable to set input source');\n    }\n  };\n  // private method\n  p5.AudioIn.prototype.dispose = function () {\n    this.stop();\n    if (this.output) {\n      this.output.disconnect();\n    }\n    if (this.amplitude) {\n      this.amplitude.disconnect();\n    }\n    this.amplitude = null;\n    this.output = null;\n  };\n}(master);\nvar filter;\nfilter = function () {\n  'use strict';\n  var p5sound = master;\n  /**\n   *  A p5.Filter uses a Web Audio Biquad Filter to filter\n   *  the frequency response of an input source. Inheriting\n   *  classes include:<br/>\n   *  * <code>p5.LowPass</code> - allows frequencies below\n   *  the cutoff frequency to pass through, and attenuates\n   *  frequencies above the cutoff.<br/>\n   *  * <code>p5.HighPass</code> - the opposite of a lowpass\n   *  filter. <br/>\n   *  * <code>p5.BandPass</code> -  allows a range of\n   *  frequencies to pass through and attenuates the frequencies\n   *  below and above this frequency range.<br/>\n   *\n   *  The <code>.res()</code> method controls either width of the\n   *  bandpass, or resonance of the low/highpass cutoff frequency.\n   *\n   *  @class p5.Filter\n   *  @constructor\n   *  @param {[String]} type 'lowpass' (default), 'highpass', 'bandpass'\n   *  @return {Object} p5.Filter\n   *  @example\n   *  <div><code>\n   *  var fft, noise, filter;\n   *\n   *  function setup() {\n   *    fill(255, 40, 255);\n   *\n   *    filter = new p5.BandPass();\n   *\n   *    noise = new p5.Noise();\n   *    // disconnect unfiltered noise,\n   *    // and connect to filter\n   *    noise.disconnect();\n   *    noise.connect(filter);\n   *    noise.start();\n   *\n   *    fft = new p5.FFT();\n   *  }\n   *\n   *  function draw() {\n   *    background(30);\n   *\n   *    // set the BandPass frequency based on mouseX\n   *    var freq = map(mouseX, 0, width, 20, 10000);\n   *    filter.freq(freq);\n   *    // give the filter a narrow band (lower res = wider bandpass)\n   *    filter.res(50);\n   *\n   *    // draw filtered spectrum\n   *    var spectrum = fft.analyze();\n   *    noStroke();\n   *    for (var i = 0; i < spectrum.length; i++) {\n   *      var x = map(i, 0, spectrum.length, 0, width);\n   *      var h = -height + map(spectrum[i], 0, 255, height, 0);\n   *      rect(x, height, width/spectrum.length, h);\n   *    }\n   *  }\n   *  </code></div>\n   */\n  p5.Filter = function (type) {\n    this.ac = p5sound.audiocontext;\n    this.input = this.ac.createGain();\n    this.output = this.ac.createGain();\n    /**\n     *  The p5.Filter is built with a\n     *  <a href=\"http://www.w3.org/TR/webaudio/#BiquadFilterNode\">\n     *  Web Audio BiquadFilter Node</a>.\n     *  \n     *  @property biquadFilter\n     *  @type {Object}  Web Audio Delay Node\n     */\n    this.biquad = this.ac.createBiquadFilter();\n    this.input.connect(this.biquad);\n    this.biquad.connect(this.output);\n    this.connect();\n    if (type) {\n      this.setType(type);\n    }\n  };\n  /**\n   *  Filter an audio signal according to a set\n   *  of filter parameters.\n   *  \n   *  @method  process\n   *  @param  {Object} Signal  An object that outputs audio\n   *  @param {[Number]} freq Frequency in Hz, from 10 to 22050\n   *  @param {[Number]} res Resonance/Width of the filter frequency\n   *                        from 0.001 to 1000\n   */\n  p5.Filter.prototype.process = function (src, freq, res) {\n    src.connect(this.input);\n    this.set(freq, res);\n  };\n  /**\n   *  Set the frequency and the resonance of the filter.\n   *\n   *  @method  set\n   *  @param {Number} freq Frequency in Hz, from 10 to 22050\n   *  @param {Number} res  Resonance (Q) from 0.001 to 1000\n   *  @param {Number} [timeFromNow] schedule this event to happen\n   *                                seconds from now\n   */\n  p5.Filter.prototype.set = function (freq, res, time) {\n    if (freq) {\n      this.freq(freq, time);\n    }\n    if (res) {\n      this.res(res, time);\n    }\n  };\n  /**\n   *  Set the filter frequency, in Hz, from 10 to 22050 (the range of\n   *  human hearing, although in reality most people hear in a narrower\n   *  range).\n   *\n   *  @method  freq\n   *  @param  {Number} freq Filter Frequency\n   *  @param {Number} [timeFromNow] schedule this event to happen\n   *                                seconds from now\n   *  @return {Number} value  Returns the current frequency value\n   */\n  p5.Filter.prototype.freq = function (freq, time) {\n    var self = this;\n    var t = time || 0;\n    if (freq <= 0) {\n      freq = 1;\n    }\n    if (typeof freq === 'number') {\n      self.biquad.frequency.value = freq;\n      self.biquad.frequency.cancelScheduledValues(this.ac.currentTime + 0.01 + t);\n      self.biquad.frequency.exponentialRampToValueAtTime(freq, this.ac.currentTime + 0.02 + t);\n    } else if (freq) {\n      freq.connect(this.biquad.frequency);\n    }\n    return self.biquad.frequency.value;\n  };\n  /**\n   *  Controls either width of a bandpass frequency,\n   *  or the resonance of a low/highpass cutoff frequency.\n   *\n   *  @method  res\n   *  @param {Number} res  Resonance/Width of filter freq\n   *                       from 0.001 to 1000\n   *  @param {Number} [timeFromNow] schedule this event to happen\n   *                                seconds from now\n   *  @return {Number} value Returns the current res value\n   */\n  p5.Filter.prototype.res = function (res, time) {\n    var self = this;\n    var t = time || 0;\n    if (typeof res == 'number') {\n      self.biquad.Q.value = res;\n      self.biquad.Q.cancelScheduledValues(self.ac.currentTime + 0.01 + t);\n      self.biquad.Q.linearRampToValueAtTime(res, self.ac.currentTime + 0.02 + t);\n    } else if (res) {\n      freq.connect(this.biquad.Q);\n    }\n    return self.biquad.Q.value;\n  };\n  /**\n   *  Set the type of a p5.Filter. Possible types include: \n   *  \"lowpass\" (default), \"highpass\", \"bandpass\", \n   *  \"lowshelf\", \"highshelf\", \"peaking\", \"notch\",\n   *  \"allpass\". \n   *  \n   *  @method  setType\n   *  @param {String}\n   */\n  p5.Filter.prototype.setType = function (t) {\n    this.biquad.type = t;\n  };\n  /**\n   *  Set the output level of the filter.\n   *  \n   *  @method  amp\n   *  @param {Number} volume amplitude between 0 and 1.0\n   *  @param {Number} [rampTime] create a fade that lasts rampTime \n   *  @param {Number} [timeFromNow] schedule this event to happen\n   *                                seconds from now\n   */\n  p5.Filter.prototype.amp = function (vol, rampTime, tFromNow) {\n    var rampTime = rampTime || 0;\n    var tFromNow = tFromNow || 0;\n    var now = p5sound.audiocontext.currentTime;\n    var currentVol = this.output.gain.value;\n    this.output.gain.cancelScheduledValues(now);\n    this.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow + 0.001);\n    this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime + 0.001);\n  };\n  /**\n   *  Send output to a p5.sound or web audio object\n   *  \n   *  @method connect\n   *  @param  {Object} unit\n   */\n  p5.Filter.prototype.connect = function (unit) {\n    var u = unit || p5.soundOut.input;\n    this.output.connect(u);\n  };\n  /**\n   *  Disconnect all output.\n   *  \n   *  @method disconnect\n   */\n  p5.Filter.prototype.disconnect = function () {\n    this.output.disconnect();\n  };\n  /**\n   *  Constructor: <code>new p5.LowPass()</code> Filter.\n   *  This is the same as creating a p5.Filter and then calling\n   *  its method <code>setType('lowpass')</code>.\n   *  See p5.Filter for methods.\n   *  \n   *  @method p5.LowPass\n   */\n  p5.LowPass = function () {\n    p5.Filter.call(this, 'lowpass');\n  };\n  p5.LowPass.prototype = Object.create(p5.Filter.prototype);\n  /**\n   *  Constructor: <code>new p5.HighPass()</code> Filter.\n   *  This is the same as creating a p5.Filter and then calling\n   *  its method <code>setType('highpass')</code>.\n   *  See p5.Filter for methods.\n   *  \n   *  @method p5.HighPass\n   */\n  p5.HighPass = function () {\n    p5.Filter.call(this, 'highpass');\n  };\n  p5.HighPass.prototype = Object.create(p5.Filter.prototype);\n  /**\n   *  Constructor: <code>new p5.BandPass()</code> Filter.\n   *  This is the same as creating a p5.Filter and then calling\n   *  its method <code>setType('bandpass')</code>.\n   *  See p5.Filter for methods. \n   *  \n   *  @method p5.BandPass\n   */\n  p5.BandPass = function () {\n    p5.Filter.call(this, 'bandpass');\n  };\n  p5.BandPass.prototype = Object.create(p5.Filter.prototype);\n}(master);\nvar delay;\ndelay = function () {\n  'use strict';\n  var p5sound = master;\n  var Filter = filter;\n  /**\n   *  Delay is an echo effect. It processes an existing sound source,\n   *  and outputs a delayed version of that sound. The p5.Delay can\n   *  produce different effects depending on the delayTime, feedback,\n   *  filter, and type. In the example below, a feedback of 0.5 will\n   *  produce a looping delay that decreases in volume by\n   *  50% each repeat. A filter will cut out the high frequencies so\n   *  that the delay does not sound as piercing as the original source.\n   *  \n   *  @class p5.Delay\n   *  @constructor\n   *  @return {Object} Returns a p5.Delay object\n   *  @example\n   *  <div><code>\n   *  var noise, env, delay;\n   *  \n   *  function setup() {\n   *    noise = new p5.Noise('brown');\n   *    noise.start();\n   *    \n   *    delay = new p5.Delay();\n   *\n   *    // delay.process() accepts 4 parameters:\n   *    // source, delayTime, feedback, filter frequency\n   *    // play with these numbers!!\n   *    delay.process(noise, .12, .7, 2300);\n   *    \n   *    // play the noise with an envelope,\n   *    // a series of fades ( time / value pairs )\n   *    env = new p5.Env(.01, 1, .2, .1);\n   *    env.play(noise);\n   *  }\n   *  </code></div>\n   */\n  p5.Delay = function () {\n    this.ac = p5sound.audiocontext;\n    this.input = this.ac.createGain();\n    this.output = this.ac.createGain();\n    this._split = this.ac.createChannelSplitter(2);\n    this._merge = this.ac.createChannelMerger(2);\n    this._leftGain = this.ac.createGain();\n    this._rightGain = this.ac.createGain();\n    /**\n     *  The p5.Delay is built with two\n     *  <a href=\"http://www.w3.org/TR/webaudio/#DelayNode\">\n     *  Web Audio Delay Nodes</a>, one for each stereo channel.\n     *  \n     *  @property leftDelay\n     *  @type {Object}  Web Audio Delay Node\n     */\n    this.leftDelay = this.ac.createDelay();\n    /**\n     *  The p5.Delay is built with two\n     *  <a href=\"http://www.w3.org/TR/webaudio/#DelayNode\">\n     *  Web Audio Delay Nodes</a>, one for each stereo channel.\n     *  \n     *  @property rightDelay\n     *  @type {Object}  Web Audio Delay Node\n     */\n    this.rightDelay = this.ac.createDelay();\n    this._leftFilter = new p5.Filter();\n    this._rightFilter = new p5.Filter();\n    this._leftFilter.disconnect();\n    this._rightFilter.disconnect();\n    /**\n     *  Internal filter. Set to lowPass by default, but can be accessed directly.\n     *  See p5.Filter for methods. Or use the p5.Delay.filter() method to change\n     *  frequency and q.\n     *\n     *  @property lowPass\n     *  @type {p5.Filter}\n     */\n    this.lowPass = this._leftFilter;\n    this._leftFilter.biquad.frequency.setValueAtTime(1200, this.ac.currentTime);\n    this._rightFilter.biquad.frequency.setValueAtTime(1200, this.ac.currentTime);\n    this._leftFilter.biquad.Q.setValueAtTime(0.3, this.ac.currentTime);\n    this._rightFilter.biquad.Q.setValueAtTime(0.3, this.ac.currentTime);\n    // graph routing\n    this.input.connect(this._split);\n    this.leftDelay.connect(this._leftGain);\n    this.rightDelay.connect(this._rightGain);\n    this._leftGain.connect(this._leftFilter.input);\n    this._rightGain.connect(this._rightFilter.input);\n    this._merge.connect(this.output);\n    this.output.connect(p5.soundOut.input);\n    this._leftFilter.biquad.gain.setValueAtTime(1, this.ac.currentTime);\n    this._rightFilter.biquad.gain.setValueAtTime(1, this.ac.currentTime);\n    // default routing\n    this.setType(0);\n    this._maxDelay = this.leftDelay.delayTime.maxValue;\n  };\n  /**\n   *  Add delay to an audio signal according to a set\n   *  of delay parameters.\n   *  \n   *  @method  process\n   *  @param  {Object} Signal  An object that outputs audio\n   *  @param  {Number} [delayTime] Time (in seconds) of the delay/echo.\n   *                               Some browsers limit delayTime to\n   *                               1 second.\n   *  @param  {Number} [feedback]  sends the delay back through itself\n   *                               in a loop that decreases in volume\n   *                               each time.\n   *  @param  {Number} [lowPass]   Cutoff frequency. Only frequencies\n   *                               below the lowPass will be part of the\n   *                               delay.\n   */\n  p5.Delay.prototype.process = function (src, _delayTime, _feedback, _filter) {\n    var feedback = _feedback || 0;\n    var delayTime = _delayTime || 0;\n    if (feedback >= 1) {\n      throw new Error('Feedback value will force a positive feedback loop.');\n    }\n    if (delayTime >= this._maxDelay) {\n      throw new Error('Delay Time exceeds maximum delay time of ' + this._maxDelay + ' second.');\n    }\n    src.connect(this.input);\n    this.leftDelay.delayTime.setValueAtTime(delayTime, this.ac.currentTime);\n    this.rightDelay.delayTime.setValueAtTime(delayTime, this.ac.currentTime);\n    this._leftGain.gain.setValueAtTime(feedback, this.ac.currentTime);\n    this._rightGain.gain.setValueAtTime(feedback, this.ac.currentTime);\n    if (_filter) {\n      this._leftFilter.freq(_filter);\n      this._rightFilter.freq(_filter);\n    }\n  };\n  /**\n   *  Set the delay (echo) time, in seconds. Usually this value will be\n   *  a floating point number between 0.0 and 1.0.\n   *\n   *  @method  delayTime\n   *  @param {Number} delayTime Time (in seconds) of the delay\n   */\n  p5.Delay.prototype.delayTime = function (t) {\n    // if t is an audio node...\n    if (typeof t !== 'number') {\n      t.connect(this.leftDelay.delayTime);\n      t.connect(this.rightDelay.delayTime);\n    } else {\n      this.leftDelay.delayTime.cancelScheduledValues(this.ac.currentTime);\n      this.rightDelay.delayTime.cancelScheduledValues(this.ac.currentTime);\n      this.leftDelay.delayTime.linearRampToValueAtTime(t, this.ac.currentTime);\n      this.rightDelay.delayTime.linearRampToValueAtTime(t, this.ac.currentTime);\n    }\n  };\n  /**\n   *  Feedback occurs when Delay sends its signal back through its input\n   *  in a loop. The feedback amount determines how much signal to send each\n   *  time through the loop. A feedback greater than 1.0 is not desirable because\n   *  it will increase the overall output each time through the loop,\n   *  creating an infinite feedback loop.\n   *  \n   *  @method  feedback\n   *  @param {Number|Object} feedback 0.0 to 1.0, or an object such as an\n   *                                  Oscillator that can be used to\n   *                                  modulate this param\n   */\n  p5.Delay.prototype.feedback = function (f) {\n    // if f is an audio node...\n    if (typeof f !== 'number') {\n      f.connect(this._leftGain.gain);\n      f.connect(this._rightGain.gain);\n    } else if (f >= 1) {\n      throw new Error('Feedback value will force a positive feedback loop.');\n    } else {\n      this._leftGain.gain.exponentialRampToValueAtTime(f, this.ac.currentTime);\n      this._rightGain.gain.exponentialRampToValueAtTime(f, this.ac.currentTime);\n    }\n  };\n  /**\n   *  Set a lowpass filter frequency for the delay. A lowpass filter\n   *  will cut off any frequencies higher than the filter frequency.\n   *   \n   *  @method  filter\n   *  @param {Number|Object} cutoffFreq  A lowpass filter will cut off any \n   *                              frequencies higher than the filter frequency.\n   *  @param {Number|Object} res  Resonance of the filter frequency\n   *                              cutoff, or an object (i.e. a p5.Oscillator)\n   *                              that can be used to modulate this parameter.\n   *                              High numbers (i.e. 15) will produce a resonance,\n   *                              low numbers (i.e. .2) will produce a slope.\n   */\n  p5.Delay.prototype.filter = function (freq, q) {\n    this._leftFilter.set(freq, q);\n    this._rightFilter.set(freq, q);\n  };\n  /**\n   *  Choose a preset type of delay. 'pingPong' bounces the signal\n   *  from the left to the right channel to produce a stereo effect.\n   *  Any other parameter will revert to the default delay setting.\n   *  \n   *  @method  setType\n   *  @param {String|Number} type 'pingPong' (1) or 'default' (0)\n   */\n  p5.Delay.prototype.setType = function (t) {\n    if (t === 1) {\n      t = 'pingPong';\n    }\n    this._split.disconnect();\n    this._leftFilter.disconnect();\n    this._rightFilter.disconnect();\n    this._split.connect(this.leftDelay, 0);\n    this._split.connect(this.rightDelay, 1);\n    switch (t) {\n    case 'pingPong':\n      this._rightFilter.setType(this._leftFilter.biquad.type);\n      this._leftFilter.output.connect(this._merge, 0, 0);\n      this._rightFilter.output.connect(this._merge, 0, 1);\n      this._leftFilter.output.connect(this.rightDelay);\n      this._rightFilter.output.connect(this.leftDelay);\n      break;\n    default:\n      this._leftFilter.output.connect(this._merge, 0, 0);\n      this._leftFilter.output.connect(this._merge, 0, 1);\n      this._leftFilter.output.connect(this.leftDelay);\n      this._leftFilter.output.connect(this.rightDelay);\n    }\n  };\n  /**\n   *  Set the output level of the delay effect.\n   *  \n   *  @method  amp\n   *  @param  {Number} volume amplitude between 0 and 1.0\n   *  @param {Number} [rampTime] create a fade that lasts rampTime \n   *  @param {Number} [timeFromNow] schedule this event to happen\n   *                                seconds from now\n   */\n  p5.Delay.prototype.amp = function (vol, rampTime, tFromNow) {\n    var rampTime = rampTime || 0;\n    var tFromNow = tFromNow || 0;\n    var now = p5sound.audiocontext.currentTime;\n    var currentVol = this.output.gain.value;\n    this.output.gain.cancelScheduledValues(now);\n    this.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow + 0.001);\n    this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime + 0.001);\n  };\n  /**\n   *  Send output to a p5.sound or web audio object\n   *  \n   *  @method  connect\n   *  @param  {Object} unit\n   */\n  p5.Delay.prototype.connect = function (unit) {\n    var u = unit || p5.soundOut.input;\n    this.output.connect(u);\n  };\n  /**\n   *  Disconnect all output.\n   *  \n   *  @method disconnect\n   */\n  p5.Delay.prototype.disconnect = function () {\n    this.output.disconnect();\n  };\n}(master, filter);\nvar reverb;\nreverb = function () {\n  'use strict';\n  var p5sound = master;\n  /**\n   *  Reverb adds depth to a sound through a large number of decaying\n   *  echoes. It creates the perception that sound is occurring in a\n   *  physical space. The p5.Reverb has paramters for Time (how long does the\n   *  reverb last) and decayRate (how much the sound decays with each echo)\n   *  that can be set with the .set() or .process() methods. The p5.Convolver\n   *  extends p5.Reverb allowing you to recreate the sound of actual physical\n   *  spaces through convolution.\n   *  \n   *  @class p5.Reverb\n   *  @constructor\n   *  @example\n   *  <div><code>\n   *  var soundFile, reverb;\n   *  function preload() {\n   *    soundFile = loadSound('assets/Damscray_DancingTiger.mp3');\n   *  }\n   *\n   *  function setup() {\n   *    reverb = new p5.Reverb();\n   *    soundFile.disconnect(); // so we'll only hear reverb...\n   *\n   *    // connect soundFile to reverb, process w/\n   *    // 3 second reverbTime, decayRate of 2%\n   *    reverb.process(soundFile, 3, 2);\n   *    soundFile.play();\n   *  }\n   *  </code></div>\n   */\n  p5.Reverb = function () {\n    this.ac = p5sound.audiocontext;\n    this.convolverNode = this.ac.createConvolver();\n    this.input = this.ac.createGain();\n    this.output = this.ac.createGain();\n    // otherwise, Safari distorts\n    this.input.gain.value = 0.5;\n    this.input.connect(this.convolverNode);\n    this.convolverNode.connect(this.output);\n    // default params\n    this._seconds = 3;\n    this._decay = 2;\n    this._reverse = false;\n    this._buildImpulse();\n    this.connect();\n    p5sound.soundArray.push(this);\n  };\n  /**\n   *  Connect a source to the reverb, and assign reverb parameters.\n   *  \n   *  @method  process\n   *  @param  {Object} src     p5.sound / Web Audio object with a sound\n   *                           output.\n   *  @param  {[Number]} seconds Duration of the reverb, in seconds.\n   *                           Min: 0, Max: 10. Defaults to 3.\n   *  @param  {[Number]} decayRate Percentage of decay with each echo.\n   *                            Min: 0, Max: 100. Defaults to 2.\n   *  @param  {[Boolean]} reverse Play the reverb backwards or forwards.\n   */\n  p5.Reverb.prototype.process = function (src, seconds, decayRate, reverse) {\n    src.connect(this.input);\n    var rebuild = false;\n    if (seconds) {\n      this._seconds = seconds;\n      rebuild = true;\n    }\n    if (decayRate) {\n      this._decay = decayRate;\n    }\n    if (reverse) {\n      this._reverse = reverse;\n    }\n    if (rebuild) {\n      this._buildImpulse();\n    }\n  };\n  /**\n   *  Set the reverb settings. Similar to .process(), but without\n   *  assigning a new input.\n   *  \n   *  @method  set\n   *  @param  {[Number]} seconds Duration of the reverb, in seconds.\n   *                           Min: 0, Max: 10. Defaults to 3.\n   *  @param  {[Number]} decayRate Percentage of decay with each echo.\n   *                            Min: 0, Max: 100. Defaults to 2.\n   *  @param  {[Boolean]} reverse Play the reverb backwards or forwards.\n   */\n  p5.Reverb.prototype.set = function (seconds, decayRate, reverse) {\n    var rebuild = false;\n    if (seconds) {\n      this._seconds = seconds;\n      rebuild = true;\n    }\n    if (decayRate) {\n      this._decay = decayRate;\n    }\n    if (reverse) {\n      this._reverse = reverse;\n    }\n    if (rebuild) {\n      this._buildImpulse();\n    }\n  };\n  /**\n   *  Set the output level of the delay effect.\n   *  \n   *  @method  amp\n   *  @param  {Number} volume amplitude between 0 and 1.0\n   *  @param  {Number} [rampTime] create a fade that lasts rampTime \n   *  @param  {Number} [timeFromNow] schedule this event to happen\n   *                                seconds from now\n   */\n  p5.Reverb.prototype.amp = function (vol, rampTime, tFromNow) {\n    var rampTime = rampTime || 0;\n    var tFromNow = tFromNow || 0;\n    var now = p5sound.audiocontext.currentTime;\n    var currentVol = this.output.gain.value;\n    this.output.gain.cancelScheduledValues(now);\n    this.output.gain.linearRampToValueAtTime(currentVol, now + tFromNow + 0.001);\n    this.output.gain.linearRampToValueAtTime(vol, now + tFromNow + rampTime + 0.001);\n  };\n  /**\n   *  Send output to a p5.sound or web audio object\n   *  \n   *  @method  connect\n   *  @param  {Object} unit\n   */\n  p5.Reverb.prototype.connect = function (unit) {\n    var u = unit || p5.soundOut.input;\n    this.output.connect(u.input ? u.input : u);\n  };\n  /**\n   *  Disconnect all output.\n   *  \n   *  @method disconnect\n   */\n  p5.Reverb.prototype.disconnect = function () {\n    this.output.disconnect();\n  };\n  /**\n   *  Inspired by Simple Reverb by Jordan Santell\n   *  https://github.com/web-audio-components/simple-reverb/blob/master/index.js\n   * \n   *  Utility function for building an impulse response\n   *  based on the module parameters.\n   *\n   *  @private\n   */\n  p5.Reverb.prototype._buildImpulse = function () {\n    var rate = this.ac.sampleRate;\n    var length = rate * this._seconds;\n    var decay = this._decay;\n    var impulse = this.ac.createBuffer(2, length, rate);\n    var impulseL = impulse.getChannelData(0);\n    var impulseR = impulse.getChannelData(1);\n    var n, i;\n    for (i = 0; i < length; i++) {\n      n = this.reverse ? length - i : i;\n      impulseL[i] = (Math.random() * 2 - 1) * Math.pow(1 - n / length, decay);\n      impulseR[i] = (Math.random() * 2 - 1) * Math.pow(1 - n / length, decay);\n    }\n    this.convolverNode.buffer = impulse;\n  };\n  p5.Reverb.prototype.dispose = function () {\n    this.convolverNode.buffer = null;\n    this.convolverNode = null;\n    if (typeof this.output !== 'undefined') {\n      this.output.disconnect();\n      this.output = null;\n    }\n    if (typeof this.panner !== 'undefined') {\n      this.panner.disconnect();\n      this.panner = null;\n    }\n  };\n  // =======================================================================\n  //                          *** p5.Convolver ***\n  // =======================================================================\n  /**\n   *  <p>p5.Convolver extends p5.Reverb. It can emulate the sound of real\n   *  physical spaces through a process called <a href=\"\n   *  https://en.wikipedia.org/wiki/Convolution_reverb#Real_space_simulation\">\n   *  convolution</a>.</p>\n   *  \n   *  <p>Convolution multiplies any audio input by an \"impulse response\"\n   *  to simulate the dispersion of sound over time. The impulse response is\n   *  generated from an audio file that you provide. One way to\n   *  generate an impulse response is to pop a balloon in a reverberant space\n   *  and record the echo. Convolution can also be used to experiment with\n   *  sound.</p>\n   *\n   *  <p>Use the method <code>createConvolution(path)</code> to instantiate a\n   *  p5.Convolver with a path to your impulse response audio file.</p>\n   *  \n   *  @class p5.Convolver\n   *  @constructor\n   *  @param  {String}   path     path to a sound file\n   *  @param  {[Function]} callback function (optional)\n   *  @example\n   *  <div><code>\n   *  var cVerb, sound;\n   *  function preload() {\n   *    // We have both MP3 and OGG versions of all sound assets\n   *    soundFormats('ogg', 'mp3');\n   *    \n   *    // Try replacing 'bx-spring' with other soundfiles like\n   *    // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n   *    cVerb = createConvolver('assets/bx-spring.mp3');\n   *\n   *    // Try replacing 'Damscray_DancingTiger' with\n   *    // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n   *    sound = loadSound('assets/Damscray_DancingTiger.mp3');\n   *  }\n   *  \n   *  function setup() {\n   *    // disconnect from master output...\n   *    sound.disconnect();\n   *    \n   *    // ...and process with cVerb\n   *    // so that we only hear the convolution\n   *    cVerb.process(sound);\n   *    \n   *    sound.play();\n   *  }\n   *  </code></div>\n   */\n  p5.Convolver = function (path, callback) {\n    this.ac = p5sound.audiocontext;\n    /**\n     *  Internally, the p5.Convolver uses the a\n     *  <a href=\"http://www.w3.org/TR/webaudio/#ConvolverNode\">\n     *  Web Audio Convolver Node</a>.\n     *  \n     *  @property convolverNode\n     *  @type {Object}  Web Audio Convolver Node\n     */\n    this.convolverNode = this.ac.createConvolver();\n    this.input = this.ac.createGain();\n    this.output = this.ac.createGain();\n    // otherwise, Safari distorts\n    this.input.gain.value = 0.5;\n    this.input.connect(this.convolverNode);\n    this.convolverNode.connect(this.output);\n    if (path) {\n      this.impulses = [];\n      this._loadBuffer(path, callback);\n    } else {\n      // parameters\n      this._seconds = 3;\n      this._decay = 2;\n      this._reverse = false;\n      this._buildImpulse();\n    }\n    this.connect();\n    p5sound.soundArray.push(this);\n  };\n  p5.Convolver.prototype = Object.create(p5.Reverb.prototype);\n  p5.prototype.registerPreloadMethod('createConvolver');\n  /**\n   *  Create a p5.Convolver. Accepts a path to a soundfile \n   *  that will be used to generate an impulse response.\n   *\n   *  @method  createConvolver\n   *  @param  {String}   path     path to a sound file\n   *  @param  {[Function]} callback function (optional)\n   *  @return {p5.Convolver}\n   *  @example\n   *  <div><code>\n   *  var cVerb, sound;\n   *  function preload() {\n   *    // We have both MP3 and OGG versions of all sound assets\n   *    soundFormats('ogg', 'mp3');\n   *    \n   *    // Try replacing 'bx-spring' with other soundfiles like\n   *    // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n   *    cVerb = createConvolver('assets/bx-spring.mp3');\n   *\n   *    // Try replacing 'Damscray_DancingTiger' with\n   *    // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n   *    sound = loadSound('assets/Damscray_DancingTiger.mp3');\n   *  }\n   *  \n   *  function setup() {\n   *    // disconnect from master output...\n   *    sound.disconnect();\n   *    \n   *    // ...and process with cVerb\n   *    // so that we only hear the convolution\n   *    cVerb.process(sound);\n   *    \n   *    sound.play();\n   *  }\n   *  </code></div>\n   */\n  p5.prototype.createConvolver = function (path, callback) {\n    // if loading locally without a server\n    if (window.location.origin.indexOf('file://') > -1) {\n      alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');\n    }\n    var cReverb = new p5.Convolver(path, callback);\n    cReverb.impulses = [];\n    return cReverb;\n  };\n  /**\n   *  Private method to load a buffer as an Impulse Response,\n   *  assign it to the convolverNode, and add to the Array of .impulses.\n   *  \n   *  @param   {String}   path\n   *  @param   {Function} callback\n   *  @private\n   */\n  p5.Convolver.prototype._loadBuffer = function (path, callback) {\n    path = p5.prototype._checkFileFormats(path);\n    var request = new XMLHttpRequest();\n    request.open('GET', path, true);\n    request.responseType = 'arraybuffer';\n    // decode asyncrohonously\n    var self = this;\n    request.onload = function () {\n      var ac = p5.prototype.getAudioContext();\n      ac.decodeAudioData(request.response, function (buff) {\n        var buffer = {};\n        var chunks = path.split('/');\n        buffer.name = chunks[chunks.length - 1];\n        buffer.audioBuffer = buff;\n        self.impulses.push(buffer);\n        self.convolverNode.buffer = buffer.audioBuffer;\n        if (callback) {\n          callback(buffer);\n        }\n      });\n    };\n    request.send();\n  };\n  p5.Convolver.prototype.set = null;\n  /**\n   *  Connect a source to the reverb, and assign reverb parameters.\n   *  \n   *  @method  process\n   *  @param  {Object} src     p5.sound / Web Audio object with a sound\n   *                           output.\n   *  @example\n   *  <div><code>\n   *  var cVerb, sound;\n   *  function preload() {\n   *    soundFormats('ogg', 'mp3');\n   *    \n   *    cVerb = createConvolver('assets/concrete-tunnel.mp3');\n   *\n   *    sound = loadSound('assets/beat.mp3');\n   *  }\n   *  \n   *  function setup() {\n   *    // disconnect from master output...\n   *    sound.disconnect();\n   *    \n   *    // ...and process with (i.e. connect to) cVerb\n   *    // so that we only hear the convolution\n   *    cVerb.process(sound);\n   *    \n   *    sound.play();\n   *  }\n   *  </code></div>\n   */\n  p5.Convolver.prototype.process = function (src) {\n    src.connect(this.input);\n  };\n  /**\n   *  If you load multiple impulse files using the .addImpulse method,\n   *  they will be stored as Objects in this Array. Toggle between them\n   *  with the <code>toggleImpulse(id)</code> method.\n   *  \n   *  @property impulses\n   *  @type {Array} Array of Web Audio Buffers\n   */\n  p5.Convolver.prototype.impulses = [];\n  /**\n   *  Load and assign a new Impulse Response to the p5.Convolver.\n   *  The impulse is added to the <code>.impulses</code> array. Previous\n   *  impulses can be accessed with the <code>.toggleImpulse(id)</code>\n   *  method.\n   *  \n   *  @method  addImpulse\n   *  @param  {String}   path     path to a sound file\n   *  @param  {[Function]} callback function (optional)\n   */\n  p5.Convolver.prototype.addImpulse = function (path, callback) {\n    // if loading locally without a server\n    if (window.location.origin.indexOf('file://') > -1) {\n      alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');\n    }\n    this._loadBuffer(path, callback);\n  };\n  /**\n   *  Similar to .addImpulse, except that the <code>.impulses</code>\n   *  Array is reset to save memory. A new <code>.impulses</code>\n   *  array is created with this impulse as the only item. \n   *\n   *  @method  resetImpulse\n   *  @param  {String}   path     path to a sound file\n   *  @param  {[Function]} callback function (optional)\n   */\n  p5.Convolver.prototype.resetImpulse = function (path, callback) {\n    // if loading locally without a server\n    if (window.location.origin.indexOf('file://') > -1) {\n      alert('This sketch may require a server to load external files. Please see http://bit.ly/1qcInwS');\n    }\n    this.impulses = [];\n    this._loadBuffer(path, callback);\n  };\n  /**\n   *  If you have used <code>.addImpulse()</code> to add multiple impulses\n   *  to a p5.Convolver, then you can use this method to toggle between\n   *  the items in the <code>.impulses</code> Array. Accepts a parameter\n   *  to identify which impulse you wish to use, identified either by its\n   *  original filename (String) or by its position in the <code>.impulses\n   *  </code> Array (Number).<br/>\n   *  You can access the objects in the .impulses Array directly. Each\n   *  Object has two attributes: an <code>.audioBuffer</code> (type:\n   *  Web Audio <a href=\"\n   *  http://webaudio.github.io/web-audio-api/#the-audiobuffer-interface\">\n   *  AudioBuffer)</a> and a <code>.name</code>, a String that corresponds\n   *  with the original filename. \n   *  \n   *  @method toggleImpulse\n   *  @param {String|Number} id Identify the impulse by its original filename\n   *                            (String), or by its position in the\n   *                            <code>.impulses</code> Array (Number).\n   */\n  p5.Convolver.prototype.toggleImpulse = function (id) {\n    if (typeof id === 'number' && id < this.impulses.length) {\n      this.convolverNode.buffer = this.impulses[id].audioBuffer;\n    }\n    if (typeof id === 'string') {\n      for (var i = 0; i < this.impulses.length; i++) {\n        if (this.impulses[i].name === id) {\n          this.convolverNode.buffer = this.impulses[i].audioBuffer;\n          break;\n        }\n      }\n    }\n  };\n  p5.Convolver.prototype.dispose = function () {\n    // remove all the Impulse Response buffers\n    for (var i in this.impulses) {\n      this.impulses[i] = null;\n    }\n    this.convolverNode.disconnect();\n    this.concolverNode = null;\n    if (typeof this.output !== 'undefined') {\n      this.output.disconnect();\n      this.output = null;\n    }\n    if (typeof this.panner !== 'undefined') {\n      this.panner.disconnect();\n      this.panner = null;\n    }\n  };\n}(master, sndcore);\n/** Tone.js module by Yotam Mann, MIT License 2014  http://opensource.org/licenses/MIT **/\nvar Tone_core_Clock;\nTone_core_Clock = function (Tone) {\n  'use strict';\n  Tone.Clock = function (rate, callback) {\n    this._oscillator = null;\n    this._jsNode = this.context.createScriptProcessor(this.bufferSize, 1, 1);\n    this._jsNode.onaudioprocess = this._processBuffer.bind(this);\n    this._controlSignal = new Tone.Signal(1);\n    this._upTick = false;\n    this.tick = this.defaultArg(callback, function () {\n    });\n    this._jsNode.noGC();\n    this.setRate(rate);\n  };\n  Tone.extend(Tone.Clock);\n  Tone.Clock.prototype.setRate = function (rate, rampTime) {\n    var freqVal = this.secondsToFrequency(this.toSeconds(rate));\n    if (!rampTime) {\n      this._controlSignal.cancelScheduledValues(0);\n      this._controlSignal.setValue(freqVal);\n    } else {\n      this._controlSignal.exponentialRampToValueNow(freqVal, rampTime);\n    }\n  };\n  Tone.Clock.prototype.getRate = function () {\n    return this._controlSignal.getValue();\n  };\n  Tone.Clock.prototype.start = function (time) {\n    this._oscillator = this.context.createOscillator();\n    this._oscillator.type = 'square';\n    this._oscillator.connect(this._jsNode);\n    this._controlSignal.connect(this._oscillator.frequency);\n    this._upTick = false;\n    var startTime = this.toSeconds(time);\n    this._oscillator.start(startTime);\n    this._oscillator.onended = function () {\n    };\n  };\n  Tone.Clock.prototype.stop = function (time, onend) {\n    var stopTime = this.toSeconds(time);\n    this._oscillator.onended = onend;\n    this._oscillator.stop(stopTime);\n  };\n  Tone.Clock.prototype._processBuffer = function (event) {\n    var now = this.defaultArg(event.playbackTime, this.now());\n    var bufferSize = this._jsNode.bufferSize;\n    var incomingBuffer = event.inputBuffer.getChannelData(0);\n    var upTick = this._upTick;\n    var self = this;\n    for (var i = 0; i < bufferSize; i++) {\n      var sample = incomingBuffer[i];\n      if (sample > 0 && !upTick) {\n        upTick = true;\n        setTimeout(function () {\n          var tickTime = now + self.samplesToSeconds(i + bufferSize * 2);\n          return function () {\n            self.tick(tickTime);\n          };\n        }(), 0);\n      } else if (sample < 0 && upTick) {\n        upTick = false;\n      }\n    }\n    this._upTick = upTick;\n  };\n  Tone.Clock.prototype.dispose = function () {\n    this._jsNode.disconnect();\n    this._controlSignal.dispose();\n    if (this._oscillator) {\n      this._oscillator.onended();\n      this._oscillator.disconnect();\n    }\n    this._jsNode.onaudioprocess = function () {\n    };\n    this._jsNode = null;\n    this._controlSignal = null;\n    this._oscillator = null;\n  };\n  return Tone.Clock;\n}(Tone_core_Tone);\nvar metro;\nmetro = function () {\n  'use strict';\n  var p5sound = master;\n  // requires the Tone.js library's Clock (MIT license, Yotam Mann)\n  // https://github.com/TONEnoTONE/Tone.js/\n  var Clock = Tone_core_Clock;\n  var ac = p5sound.audiocontext;\n  // var upTick = false;\n  p5.Metro = function () {\n    this.clock = new Clock(ac.sampleRate, this.ontick.bind(this));\n    this.syncedParts = [];\n    this.bpm = 120;\n    // gets overridden by p5.Part\n    this._init();\n    this.tickCallback = function () {\n    };\n  };\n  var prevTick = 0;\n  var tatumTime = 0;\n  p5.Metro.prototype.ontick = function (tickTime) {\n    var elapsedTime = tickTime - prevTick;\n    var secondsFromNow = tickTime - p5sound.audiocontext.currentTime;\n    if (elapsedTime - tatumTime <= -0.02) {\n      return;\n    } else {\n      prevTick = tickTime;\n      // for all of the active things on the metro:\n      for (var i in this.syncedParts) {\n        var thisPart = this.syncedParts[i];\n        thisPart.incrementStep(secondsFromNow);\n        // each synced source keeps track of its own beat number\n        for (var j in thisPart.phrases) {\n          var thisPhrase = thisPart.phrases[j];\n          var phraseArray = thisPhrase.sequence;\n          var bNum = this.metroTicks % phraseArray.length;\n          if (phraseArray[bNum] !== 0 && (this.metroTicks < phraseArray.length || !thisPhrase.looping)) {\n            thisPhrase.callback(phraseArray[bNum], secondsFromNow);\n          }\n        }\n      }\n      this.metroTicks += 1;\n      this.tickCallback(secondsFromNow);\n    }\n  };\n  p5.Metro.prototype.setBPM = function (bpm, rampTime) {\n    var beatTime = 60 / (bpm * this.tatums);\n    tatumTime = beatTime;\n    var ramp = rampTime || 0;\n    this.clock.setRate(beatTime, rampTime + p5sound.audiocontext.currentTime);\n    this.bpm = bpm;\n  };\n  p5.Metro.prototype.getBPM = function (tempo) {\n    return this.clock.getRate() / this.tatums * 60;\n  };\n  p5.Metro.prototype._init = function () {\n    this.metroTicks = 0;\n  };\n  // clear existing synced parts, add only this one\n  p5.Metro.prototype.resetSync = function (part) {\n    this.syncedParts = [part];\n  };\n  // push a new synced part to the array\n  p5.Metro.prototype.pushSync = function (part) {\n    this.syncedParts.push(part);\n  };\n  p5.Metro.prototype.start = function (time) {\n    var t = time || 0;\n    this.clock.start(t);\n    this.setBPM(this.bpm);\n  };\n  p5.Metro.prototype.stop = function (time) {\n    var t = time || 0;\n    if (this.clock._oscillator) {\n      this.clock.stop(t);\n    }\n  };\n  p5.Metro.prototype.beatLength = function (tatums) {\n    this.tatums = 1 / tatums / 4;\n  };\n}(master, Tone_core_Clock);\nvar looper;\nlooper = function () {\n  'use strict';\n  var p5sound = master;\n  var bpm = 120;\n  /**\n   *  Set the global tempo, in beats per minute, for all\n   *  p5.Parts. This method will impact all active p5.Parts.\n   *  \n   *  @param {Number} BPM      Beats Per Minute\n   *  @param {Number} rampTime Seconds from now\n   */\n  p5.prototype.setBPM = function (BPM, rampTime) {\n    bpm = BPM;\n    for (var i in p5sound.parts) {\n      p5sound.parts[i].setBPM(bpm, rampTime);\n    }\n  };\n  /**\n   *  <p>A phrase is a pattern of musical events over time, i.e.\n   *  a series of notes and rests.</p>\n   *  \n   *  <p>Phrases must be added to a p5.Part for playback, and\n   *  each part can play multiple phrases at the same time.\n   *  For example, one Phrase might be a kick drum, another\n   *  could be a snare, and another could be the bassline.</p>\n   *  \n   *  <p>The first parameter is a name so that the phrase can be\n   *  modified or deleted later. The callback is a a function that\n   *  this phrase will call at every step—for example it might be\n   *  called <code>playNote(value){}</code>. The array determines\n   *  which value is passed into the callback at each step of the\n   *  phrase. It can be numbers, an object with multiple numbers,\n   *  or a zero (0) indicates a rest so the callback won't be called).</p>\n   * \n   *  @class p5.Phrase\n   *  @constructor\n   *  @param {String}   name     Name so that you can access the Phrase.\n   *  @param {Function} callback The name of a function that this phrase\n   *                             will call. Typically it will play a sound,\n   *                             and accept two parameters: a value from the\n   *                             sequence array, followed by a time at which\n   *                             to play the sound.\n   *  @param {Array}   sequence    Array of values to pass into the callback\n   *                            at each step of the phrase.\n   *  @example\n   *  <div><code>\n   *  var mySound;\n   *  var pattern = [1,0,0,2,0,2,0,0];\n   *  \n   *  function preload() {\n   *    mySound = loadSound('assets/beatbox.mp3');\n   *  }\n   *  \n   *  function setup() {\n   *    var myPhrase = new p5.Phrase('bbox', makeSound, pattern);\n   *    var myPart = new p5.Part();\n   *    myPart.addPhrase(myPhrase);\n   *    myPart.setBPM(60);\n   *    myPart.start();\n   *  }\n   *\n   *  function makeSound(time, playbackRate) {\n   *    mySound.rate(playbackRate);\n   *    mySound.play(time);\n   *  }\n   *  </code></div>\n   */\n  p5.Phrase = function (name, callback, sequence) {\n    this.phraseStep = 0;\n    this.name = name;\n    this.callback = callback;\n    /**\n     * Array of values to pass into the callback\n     * at each step of the phrase. Depending on the callback\n     * function's requirements, these values may be numbers,\n     * strings, or an object with multiple parameters.\n     * Zero (0) indicates a rest.\n     * \n     * @property sequence\n     * @type {Array}\n     */\n    this.sequence = sequence;\n  };\n  /**\n   *  A p5.Part plays back one or more p5.Phrases. Instantiate a part\n   *  with steps and tatums. By default, each step represents 1/16th note.\n   *  \n   *  @class p5.Part\n   *  @constructor\n   *  @param {Number} [steps]   Steps in the part\n   *  @param {Number} [tatums] Divisions of a beat (default is 1/16, a quarter note)\n   *  @example\n   *  <div><code>\n   *  var box, drum;\n   *  var boxPat = [1,0,0,2,0,2,0,0];\n   *  var drumPat = [0,1,1,0,2,0,1,0];\n   *  \n   *  function preload() {\n   *    box = loadSound('assets/beatbox.mp3');\n   *    drum = loadSound('assets/drum.mp3');\n   *  }\n   *  \n   *  function setup() {\n   *    var boxPhrase = new p5.Phrase('box', playBox, boxPat);\n   *    var drumPhrase = new p5.Phrase('drum', playDrum, drumPat);\n   *    var myPart = new p5.Part();\n   *    myPart.addPhrase(boxPhrase);\n   *    myPart.addPhrase(drumPhrase);\n   *    myPart.setBPM(60);\n   *    myPart.start();\n   *  }\n   *\n   *  function playBox(playbackRate, time) {\n   *    box.rate(playbackRate);\n   *    box.play(time);\n   *  }\n   *  \n   *  function playDrum(playbackRate, time) {\n   *    drum.rate(playbackRate);\n   *    drum.play(time);\n   *  }\n   *  </code></div>\n   */\n  p5.Part = function (steps, bLength) {\n    this.length = steps || 0;\n    // how many beats\n    this.partStep = 0;\n    this.phrases = [];\n    this.looping = false;\n    this.isPlaying = false;\n    // what does this looper do when it gets to the last step?\n    this.onended = function () {\n      this.stop();\n    };\n    this.tatums = bLength || 0.0625;\n    // defaults to quarter note\n    this.metro = new p5.Metro();\n    this.metro._init();\n    this.metro.beatLength(this.tatums);\n    this.metro.setBPM(bpm);\n    p5sound.parts.push(this);\n    this.callback = function () {\n    };\n  };\n  /**\n   *  Set the tempo of this part, in Beats Per Minute. \n   *  \n   *  @method  setBPM\n   *  @param {Number} BPM      Beats Per Minute\n   *  @param {Number} [rampTime] Seconds from now\n   */\n  p5.Part.prototype.setBPM = function (tempo, rampTime) {\n    this.metro.setBPM(tempo, rampTime);\n  };\n  /**\n   *  Returns the Beats Per Minute of this currently part.\n   *  \n   *  @method getBPM\n   *  @return {Number} \n   */\n  p5.Part.prototype.getBPM = function () {\n    return this.metro.getBPM();\n  };\n  /**\n   *  Start playback of this part. It will play\n   *  through all of its phrases at a speed\n   *  determined by setBPM.\n   *  \n   *  @method  start\n   *  @param  {Number} [time] seconds from now\n   */\n  p5.Part.prototype.start = function (time) {\n    if (!this.isPlaying) {\n      this.isPlaying = true;\n      this.metro.resetSync(this);\n      var t = time || 0;\n      this.metro.start(t);\n    }\n  };\n  /**\n   *  Loop playback of this part. It will begin\n   *  looping through all of its phrases at a speed\n   *  determined by setBPM.\n   *  \n   *  @method  loop\n   *  @param  {Number} [time] seconds from now\n   */\n  p5.Part.prototype.loop = function (time) {\n    this.looping = true;\n    // rest onended function\n    this.onended = function () {\n      this.partStep = 0;\n    };\n    var t = time || 0;\n    this.start(t);\n  };\n  /**\n   *  Tell the part to stop looping.\n   *\n   *  @method  noLoop\n   */\n  p5.Part.prototype.noLoop = function () {\n    this.looping = false;\n    // rest onended function\n    this.onended = function () {\n      this.stop();\n    };\n  };\n  /**\n   *  Stop the part and cue it to step 0.\n   *  \n   *  @method  stop\n   *  @param  {Number} [time] seconds from now\n   */\n  p5.Part.prototype.stop = function (time) {\n    this.partStep = 0;\n    this.pause(time);\n  };\n  /**\n   *  Pause the part. Playback will resume\n   *  from the current step.\n   *  \n   *  @method  pause\n   *  @param  {Number} time seconds from now\n   */\n  p5.Part.prototype.pause = function (time) {\n    this.isPlaying = false;\n    var t = time || 0;\n    this.metro.stop(t);\n  };\n  /**\n   *  Add a p5.Phrase to this Part.\n   *\n   *  @method  addPhrase\n   *  @param {p5.Phrase}   phrase   reference to a p5.Phrase\n   */\n  p5.Part.prototype.addPhrase = function (name, callback, array) {\n    var p;\n    if (arguments.length === 3) {\n      p = new p5.Phrase(name, callback, array);\n    } else if (arguments[0] instanceof p5.Phrase) {\n      p = arguments[0];\n    } else {\n      throw 'invalid input. addPhrase accepts name, callback, array or a p5.Phrase';\n    }\n    this.phrases.push(p);\n    // reset the length if phrase is longer than part's existing length\n    if (p.sequence.length > this.length) {\n      this.length = p.sequence.length;\n    }\n  };\n  /**\n   *  Remove a phrase from this part, based on the name it was\n   *  given when it was created.\n   *  \n   *  @method  removePhrase\n   *  @param  {String} phraseName\n   */\n  p5.Part.prototype.removePhrase = function (name) {\n    for (var i in this.phrases) {\n      if (this.phrases[i].name === name) {\n        this.phrases.split(i, 1);\n      }\n    }\n  };\n  /**\n   *  Get a phrase from this part, based on the name it was\n   *  given when it was created. Now you can modify its array.\n   *  \n   *  @method  getPhrase\n   *  @param  {String} phraseName\n   */\n  p5.Part.prototype.getPhrase = function (name) {\n    for (var i in this.phrases) {\n      if (this.phrases[i].name === name) {\n        return this.phrases[i];\n      }\n    }\n  };\n  /**\n   *  Get a phrase from this part, based on the name it was\n   *  given when it was created. Now you can modify its array.\n   *  \n   *  @method  replaceSequence\n   *  @param  {String} phraseName\n   *  @param  {Array} sequence  Array of values to pass into the callback\n   *                            at each step of the phrase.\n   */\n  p5.Part.prototype.replaceSequence = function (name, array) {\n    for (var i in this.phrases) {\n      if (this.phrases[i].name === name) {\n        this.phrases[i].sequence = array;\n      }\n    }\n  };\n  p5.Part.prototype.incrementStep = function (time) {\n    if (this.partStep < this.length - 1) {\n      this.callback(time);\n      this.partStep += 1;\n    } else {\n      if (this.looping) {\n        this.callback(time);\n      }\n      this.onended();\n      this.partStep = 0;\n    }\n  };\n  /**\n   *  Fire a callback function at every step.\n   *\n   *  @method onStep\n   *  @param  {Function} callback The name of the callback\n   *                              you want to fire\n   *                              on every beat/tatum.\n   */\n  p5.Part.prototype.onStep = function (callback) {\n    this.callback = callback;\n  };\n  // ===============\n  // p5.Score\n  // ===============\n  /**\n   *  A Score consists of a series of Parts. The parts will\n   *  be played back in order. For example, you could have an\n   *  A part, a B part, and a C part, and play them back in this order\n   *  <code>new p5.Score(a, a, b, a, c)</code>\n   *\n   *  @class p5.Score\n   *  @constructor\n   *  @param {p5.Part} part(s) Parts to add to the score.\n   *  @example\n   *  <div><code>\n   *  var box, drum;\n   *  var boxPat = [1,0,0,2,0,2,0,0];\n   *  var drumPat = [0,1,1,0,2,0,1,0];\n   *  var osc, env;\n   *  \n   *  function preload() {\n   *    box = loadSound('assets/beatbox.mp3');\n   *    drum = loadSound('assets/drum.mp3');\n   *  }\n   *  \n   *  function setup() {\n   *    var myPart = new p5.Part();\n   *    myPart.addPhrase('box', playBox, boxPat);\n   *    myPart.addPhrase('drum', playDrum, drumPat);\n   *    myPart.setBPM(60);\n   *    myPart.start();\n   *\n   *    osc = new p5.Oscillator();\n   *    env = new p5.Env(0.01, 1, 0.2, 0);\n   *  }\n   *\n   *  function playBox(playbackRate, time) {\n   *    box.rate(playbackRate);\n   *    box.play(time);\n   *  }\n   *  \n   *  function playDrum(playbackRate, time) {\n   *    drum.rate(playbackRate)\n   *    drum.play(time);\n   *  }\n   *  </code></div>\n   */\n  p5.Score = function () {\n    // for all of the arguments\n    this.parts = [];\n    this.currentPart = 0;\n    var thisScore = this;\n    for (var i in arguments) {\n      this.parts[i] = arguments[i];\n      this.parts[i].nextPart = this.parts[i + 1];\n      this.parts[i].onended = function () {\n        thisScore.resetPart(i);\n        playNextPart(thisScore);\n      };\n    }\n    this.looping = false;\n  };\n  p5.Score.prototype.onended = function () {\n    if (this.looping) {\n      // this.resetParts();\n      this.parts[0].start();\n    } else {\n      this.parts[this.parts.length - 1].onended = function () {\n        this.stop();\n        this.resetParts();\n      };\n    }\n    this.currentPart = 0;\n  };\n  /**\n   *  Start playback of the score.\n   *  \n   *  @method  start\n   */\n  p5.Score.prototype.start = function () {\n    this.parts[this.currentPart].start();\n    this.scoreStep = 0;\n  };\n  /**\n   *  Stop playback of the score.\n   *  \n   *  @method  stop\n   */\n  p5.Score.prototype.stop = function () {\n    this.parts[this.currentPart].stop();\n    this.currentPart = 0;\n    this.scoreStep = 0;\n  };\n  /**\n   *  Pause playback of the score.\n   *  \n   *  @method  pause\n   */\n  p5.Score.prototype.pause = function () {\n    this.parts[this.currentPart].stop();\n  };\n  /**\n   *  Loop playback of the score.\n   *  \n   *  @method  loop\n   */\n  p5.Score.prototype.loop = function () {\n    this.looping = true;\n    this.start();\n  };\n  /**\n   *  Stop looping playback of the score. If it\n   *  is currently playing, this will go into effect\n   *  after the current round of playback completes.\n   *  \n   *  @method  noLoop\n   */\n  p5.Score.prototype.noLoop = function () {\n    this.looping = false;\n  };\n  p5.Score.prototype.resetParts = function () {\n    for (var i in this.parts) {\n      this.resetPart(i);\n    }\n  };\n  p5.Score.prototype.resetPart = function (i) {\n    this.parts[i].stop();\n    this.parts[i].partStep = 0;\n    for (var p in this.parts[i].phrases) {\n      this.parts[i].phrases[p].phraseStep = 0;\n    }\n  };\n  /**\n   *  Set the tempo for all parts in the score\n   *  \n   *  @param {Number} BPM      Beats Per Minute\n   *  @param {Number} rampTime Seconds from now\n   */\n  p5.Score.prototype.setBPM = function (bpm, rampTime) {\n    for (var i in this.parts) {\n      this.parts[i].setBPM(bpm, rampTime);\n    }\n  };\n  function playNextPart(aScore) {\n    aScore.currentPart++;\n    if (aScore.currentPart >= aScore.parts.length) {\n      aScore.scoreStep = 0;\n      aScore.onended();\n    } else {\n      aScore.scoreStep = 0;\n      aScore.parts[aScore.currentPart - 1].stop();\n      aScore.parts[aScore.currentPart].start();\n    }\n  }\n}(master);\nvar soundRecorder;\nsoundRecorder = function () {\n  'use strict';\n  var p5sound = master;\n  var ac = p5sound.audiocontext;\n  /**\n   *  <p>Record sounds for playback and/or to save as a .wav file.\n   *  The p5.SoundRecorder records all sound output from your sketch,\n   *  or can be assigned a specific source with setInput().</p>\n   *  <p>The record() method accepts a p5.SoundFile as a parameter.\n   *  When playback is stopped (either after the given amount of time,\n   *  or with the stop() method), the p5.SoundRecorder will send its\n   *  recording to that p5.SoundFile for playback.</p>\n   *  \n   *  @class p5.SoundRecorder\n   *  @constructor\n   *  @example\n   *  <div><code>\n   *  var mic, recorder, soundFile;\n   *  var state = 0;\n   *  \n   *  function setup() {\n   *    background(200);\n   *    // create an audio in\n   *    mic = new p5.AudioIn();\n   *    \n   *    // prompts user to enable their browser mic\n   *    mic.start();\n   *    \n   *    // create a sound recorder\n   *    recorder = new p5.SoundRecorder();\n   *    \n   *    // connect the mic to the recorder\n   *    recorder.setInput(mic);\n   *    \n   *    // this sound file will be used to\n   *    // playback & save the recording\n   *    soundFile = new p5.SoundFile();\n   *\n   *    text('keyPress to record', 20, 20);\n   *  }\n   *\n   *  function keyPressed() {\n   *    // make sure user enabled the mic\n   *    if (state === 0 && mic.enabled) {\n   *    \n   *      // record to our p5.SoundFile\n   *      recorder.record(soundFile);\n   *      \n   *      background(255,0,0);\n   *      text('Recording!', 20, 20);\n   *      state++;\n   *    }\n   *    else if (state === 1) {\n   *      background(0,255,0);\n   *\n   *      // stop recorder and\n   *      // send result to soundFile\n   *      recorder.stop(); \n   *      \n   *      text('Stopped', 20, 20);\n   *      state++;\n   *    }\n   *    \n   *    else if (state === 2) {\n   *      soundFile.play(); // play the result!\n   *      save(soundFile, 'mySound.wav');\n   *      state++;\n   *    }\n   *  }\n   *  </div></code>\n   */\n  p5.SoundRecorder = function () {\n    this.input = ac.createGain();\n    this.output = ac.createGain();\n    this.recording = false;\n    this.bufferSize = 1024;\n    this._channels = 2;\n    // stereo (default)\n    this._clear();\n    // initialize variables\n    this._jsNode = ac.createScriptProcessor(this.bufferSize, this._channels, 2);\n    this._jsNode.onaudioprocess = this._audioprocess.bind(this);\n    /** \n     *  callback invoked when the recording is over\n     *  @private\n     *  @type {function(Float32Array)}\n     */\n    this._callback = function () {\n    };\n    // connections\n    this._jsNode.connect(p5.soundOut._silentNode);\n    this.setInput();\n    // add this p5.SoundFile to the soundArray\n    p5sound.soundArray.push(this);\n  };\n  /**\n   *  Connect a specific device to the p5.SoundRecorder.\n   *  If no parameter is given, p5.SoundRecorer will record\n   *  all audible p5.sound from your sketch.\n   *  \n   *  @method  setInput\n   *  @param {Object} [unit] p5.sound object or a web audio unit\n   *                         that outputs sound\n   */\n  p5.SoundRecorder.prototype.setInput = function (unit) {\n    this.input.disconnect();\n    this.input = null;\n    this.input = ac.createGain();\n    this.input.connect(this._jsNode);\n    this.input.connect(this.output);\n    if (unit) {\n      unit.connect(this.input);\n    } else {\n      p5.soundOut.output.connect(this.input);\n    }\n  };\n  /**\n   *  Start recording. To access the recording, provide\n   *  a p5.SoundFile as the first parameter. The p5.SoundRecorder\n   *  will send its recording to that p5.SoundFile for playback once\n   *  recording is complete. Optional parameters include duration\n   *  (in seconds) of the recording, and a callback function that\n   *  will be called once the complete recording has been\n   *  transfered to the p5.SoundFile.\n   *  \n   *  @method  record\n   *  @param  {p5.SoundFile}   soundFile    p5.SoundFile\n   *  @param  {Number}   [duration] Time (in seconds)\n   *  @param  {Function} [callback] The name of a function that will be\n   *                                called once the recording completes\n   */\n  p5.SoundRecorder.prototype.record = function (sFile, duration, callback) {\n    this.recording = true;\n    if (duration) {\n      this.sampleLimit = Math.round(duration * ac.sampleRate);\n    }\n    if (sFile && callback) {\n      this._callback = function () {\n        this.buffer = this._getBuffer();\n        sFile.setBuffer(this.buffer);\n        callback();\n      };\n    } else if (sFile) {\n      this._callback = function () {\n        this.buffer = this._getBuffer();\n        sFile.setBuffer(this.buffer);\n      };\n    }\n  };\n  /**\n   *  Stop the recording. Once the recording is stopped,\n   *  the results will be sent to the p5.SoundFile that\n   *  was given on .record(), and if a callback function\n   *  was provided on record, that function will be called.\n   *  \n   *  @method  stop\n   */\n  p5.SoundRecorder.prototype.stop = function () {\n    this.recording = false;\n    this._callback();\n    this._clear();\n  };\n  p5.SoundRecorder.prototype._clear = function () {\n    this._leftBuffers = [];\n    this._rightBuffers = [];\n    this.recordedSamples = 0;\n    this.sampleLimit = null;\n  };\n  /**\n   *  internal method called on audio process\n   *  \n   *  @private\n   *  @param   {AudioProcessorEvent} event \n   */\n  p5.SoundRecorder.prototype._audioprocess = function (event) {\n    if (this.recording === false) {\n      return;\n    } else if (this.recording === true) {\n      // if we are past the duration, then stop... else:\n      if (this.sampleLimit && this.recordedSamples >= this.sampleLimit) {\n        this.stop();\n      } else {\n        // get channel data\n        var left = event.inputBuffer.getChannelData(0);\n        var right = event.inputBuffer.getChannelData(1);\n        // clone the samples\n        this._leftBuffers.push(new Float32Array(left));\n        this._rightBuffers.push(new Float32Array(right));\n        this.recordedSamples += this.bufferSize;\n      }\n    }\n  };\n  p5.SoundRecorder.prototype._getBuffer = function () {\n    var buffers = [];\n    buffers.push(this._mergeBuffers(this._leftBuffers));\n    buffers.push(this._mergeBuffers(this._rightBuffers));\n    return buffers;\n  };\n  p5.SoundRecorder.prototype._mergeBuffers = function (channelBuffer) {\n    var result = new Float32Array(this.recordedSamples);\n    var offset = 0;\n    var lng = channelBuffer.length;\n    for (var i = 0; i < lng; i++) {\n      var buffer = channelBuffer[i];\n      result.set(buffer, offset);\n      offset += buffer.length;\n    }\n    return result;\n  };\n  p5.SoundRecorder.prototype.dispose = function () {\n    this._clear();\n    this._callback = function () {\n    };\n    if (this.input) {\n      this.input.disconnect();\n    }\n    this.input = null;\n    this._jsNode = null;\n  };\n  /**\n   *  Save a p5.SoundFile as a .wav audio file.\n   *  \n   *  @method saveSound\n   *  @param  {p5.SoundFile} soundFile p5.SoundFile that you wish to save\n   *  @param  {String} name      name of the resulting .wav file.\n   */\n  p5.prototype.saveSound = function (soundFile, name) {\n    var leftChannel = soundFile.buffer.getChannelData(0);\n    var rightChannel = soundFile.buffer.getChannelData(1);\n    var interleaved = interleave(leftChannel, rightChannel);\n    // create the buffer and view to create the .WAV file\n    var buffer = new ArrayBuffer(44 + interleaved.length * 2);\n    var view = new DataView(buffer);\n    // write the WAV container,\n    // check spec at: https://ccrma.stanford.edu/courses/422/projects/WaveFormat/\n    // RIFF chunk descriptor\n    writeUTFBytes(view, 0, 'RIFF');\n    view.setUint32(4, 44 + interleaved.length * 2, true);\n    writeUTFBytes(view, 8, 'WAVE');\n    // FMT sub-chunk\n    writeUTFBytes(view, 12, 'fmt ');\n    view.setUint32(16, 16, true);\n    view.setUint16(20, 1, true);\n    // stereo (2 channels)\n    view.setUint16(22, 2, true);\n    view.setUint32(24, 44100, true);\n    view.setUint32(28, 44100 * 4, true);\n    view.setUint16(32, 4, true);\n    view.setUint16(34, 16, true);\n    // data sub-chunk\n    writeUTFBytes(view, 36, 'data');\n    view.setUint32(40, interleaved.length * 2, true);\n    // write the PCM samples\n    var lng = interleaved.length;\n    var index = 44;\n    var volume = 1;\n    for (var i = 0; i < lng; i++) {\n      view.setInt16(index, interleaved[i] * (32767 * volume), true);\n      index += 2;\n    }\n    p5.prototype.writeFile([view], name, 'wav');\n  };\n  // helper methods to save waves\n  function interleave(leftChannel, rightChannel) {\n    var length = leftChannel.length + rightChannel.length;\n    var result = new Float32Array(length);\n    var inputIndex = 0;\n    for (var index = 0; index < length;) {\n      result[index++] = leftChannel[inputIndex];\n      result[index++] = rightChannel[inputIndex];\n      inputIndex++;\n    }\n    return result;\n  }\n  function writeUTFBytes(view, offset, string) {\n    var lng = string.length;\n    for (var i = 0; i < lng; i++) {\n      view.setUint8(offset + i, string.charCodeAt(i));\n    }\n  }\n}(sndcore, master);\nvar src_app;\nsrc_app = function () {\n  'use strict';\n  var p5SOUND = sndcore;\n  return p5SOUND;\n}(sndcore, master, helpers, panner, soundfile, amplitude, fft, signal, oscillator, env, pulse, noise, audioin, filter, delay, reverb, metro, looper, soundRecorder);\n}));"
  },
  {
    "path": "pro/index.html",
    "content": "<!DOCTYPE HTML>\n<html lang=\"en-US\">\n    <head>\n        <meta charset=\"UTF-8\">\n        <meta http-equiv=\"refresh\" content=\"1;url=http://example.com\">\n        <script type=\"text/javascript\">\n            window.location.href = \"../pro.html\";\n        </script>\n        <title>Neural Slime Volleyball Pro Redirection</title>\n    </head>\n    <body>\n        <!-- Note: don't tell people to `click` the link, just tell them that it is a link. -->\n        If you are not redirected automatically, follow the <a href='../pro.html'>link</a> to pro version.\n    </body>\n<script>\n  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){\n  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),\n  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)\n  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');\n\n  ga('create', 'UA-61361005-1', 'auto');\n  ga('send', 'pageview');\n\n</script>\n</html>"
  },
  {
    "path": "pro.html",
    "content": "<html>\n<head>\n  <title>neural slime volleyball</title>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=320, initial-scale=1.0, maximum-scale=1.0, user-scalable=0\"/>\n    <meta name=\"apple-mobile-web-app-capable\" content=\"yes\" />\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"mobile-web-app-capable\" content=\"yes\">\n    <meta name=\"description\" content=\"ōtoro.net\">\n    <meta name=\"author\" content=\"hardmaru\">\n\n    <!-- Bootstrap Core CSS - Uses Bootswatch Flatly Theme: http://bootswatch.com/flatly/ -->\n    <link rel=\"stylesheet\" href=\"http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css\">\n\n    <!-- extra styles -->\n    <style>\n    a {\n        font-family: \"Helvetica Neue\",Helvetica,Arial,sans-serif;\n        font-size: 2.0em;\n        font-weight: 150;\n        font-style: inherit;\n        color: orange;\n    }\n\n    head {\n      margin: 0;\n      padding: 0;\n    }\n    body {\n      margin: 0;\n      padding: 0;\n      font-family: \"Helvetica Neue\",Helvetica,Arial,sans-serif;\n      font-weight: 100;\n      display: none;\n    }\n    p {\n      padding: 10px;\n      font-family: Courier, \"Helvetica Neue\",Helvetica,Arial,sans-serif;\n      font-weight: 100;\n      font-size: 2.0em;\n    }\n    textarea {\n      padding: 5;\n      font-family: Courier, \"Helvetica Neue\",Helvetica,Arial,sans-serif;\n      font-weight: 100;\n      font-size: 0.5em;\n    }\n    #nn_weights { white-space: pre; }\n    </style>\n\n\n</head>\n<body>\n\n<a href=\"http://blog.otoro.net/2015/03/28/neural-slime-volleyball/\" id=\"initTitle\" target=\"_blank\">neural slime volleyball</a>\n<a href=\"http://blog.otoro.net/2015/03/28/neural-slime-volleyball/\" id=\"finalTitle\" target=\"_blank\">&copy; <ruby>ōtoro</ruby>.net</a>\n<p id=\"theHand\"><span class=\"glyphicon glyphicon-hand-up\"></span></p>\n\n\n\n    <div id=\"p5Container\">\n    </div>\n\n<script>\n  var trainingVersion = true;\n</script>\n\n  <img src=\"img/neural_slime_volleyball.png\" class=\"img-responsive\" alt=\"\" id=\"pageImage\">\n  <p id=\"nn_gene\"></p>\n  <!-- jQuery -->\n  <script src=\"http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js\"></script>\n  <!-- Bootstrap Core JavaScript -->\n  <script src=\"http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js\"></script>\n  <script src=\"http://cdn.jsdelivr.net/mobile-detect.js/0.4.1/mobile-detect.min.js\"></script>\n  <script src=\"./lib/convnetjs/convnet.js\"></script>\n  <script src=\"./lib/convnetjs/ga.js\"></script>\n\n<script>\nif (!trainingVersion) {\n  $(\"#nn_gene\").hide();\n}\n$(\"#pageImage\").hide();\n\n$(\"#initTitle\").hide();\n$(\"#theHand\").hide();\n$(\"#initTitle\").css({ \n    \"position\": \"absolute\",\n    \"top\": 8 + \"px\",\n    \"left\": 24 + \"px\",\n    });\n\n\n$(\"#finalTitle\").hide();\n$(\"#finalTitle\").css({ \n    \"position\": \"absolute\",\n    \"top\": 8 + \"px\",\n    \"right\": 24 + \"px\",\n    \"font-size\": 1.5 +\"em\"\n    });\n\nsetTimeout(function(){\n  $(\"body\").fadeIn(500);\n  $(\"#theHand\").fadeIn(500);\n  $(\"#initTitle\").fadeIn(500);\n},0);\n\n/*\nsetTimeout(function(){\n  $(\"#theHand\").fadeIn(1000);\n},2000);\n*/\nsetTimeout(function(){\n    $(\"#initTitle\").fadeOut(500);\n    $(\"#finalTitle\").fadeIn(500);\n},10000);\n\nsetTimeout(function(){\n    $(\"#theHand\").fadeOut(1000);\n},4000);\n\n/*\nsetTimeout(function(){\n    $(\"#mainNavBar\").fadeOut(1000);\n},4000);\n*/\n\n</script>\n\n<script language=\"javascript\" type=\"text/javascript\" src=\"./lib/p5.js\"></script>\n<script language=\"javascript\" type=\"text/javascript\" src=\"./lib/p5.dom.js\"></script>\n<script language=\"javascript\" type=\"text/javascript\" src=\"useful.js\"></script>\n<script language=\"javascript\" type=\"text/javascript\" src=\"slimevolley_pro.js\"></script>\n\n<script>\n  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){\n  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),\n  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)\n  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');\n\n  ga('create', 'UA-61361005-1', 'auto');\n  ga('send', 'pageview');\n\n</script>\n</body>\n</html>"
  },
  {
    "path": "slimevolley.js",
    "content": "\n\n/*    \n\np5.js implementation of slime volleyball, with evolved neural networks to be the ai.\n\n@licstart  The following is the entire license notice for the \nJavaScript code in this page.\n\nCopyright (C) 2015 david ha, otoro.net, otoro labs\n\nThe JavaScript code in this page is free software: you can\nredistribute it and/or modify it under the terms of the GNU\nGeneral Public License (GNU GPL) as published by the Free Software\nFoundation, either version 3 of the License, or (at your option)\nany later version.  The code is distributed WITHOUT ANY WARRANTY;\nwithout even the implied warranty of MERCHANTABILITY or FITNESS\nFOR A PARTICULAR PURPOSE.  See the GNU GPL for more details.\n\nAs additional permission under GNU GPL version 3 section 7, you\nmay distribute non-source (e.g., minimized or compacted) forms of\nthat code without the copy of the GNU GPL normally required by\nsection 4, provided you include this license notice and a URL\nthrough which recipients can access the Corresponding Source.   \n\n\n@licend  The above is the entire license notice\nfor the JavaScript code in this page.\n*/\n\n// game settings:\nvar showArrowKeys = true;\nvar ref_w = 24;\nvar ref_h = ref_w;\nvar ref_u = 1.5; // ground height\nvar ref_wallwidth = 1.0; // wall width\nvar ref_wallheight = 3.5;\nvar factor = 1;\nvar playerSpeedX = 10;\nvar playerSpeedY = 10;\nvar maxBallSpeed = 15;\nvar gravity;\nvar timeStep = 1/30;\nvar theFrameRate = 60*1;\nvar nudge = 0.1;\nvar friction = 1.0; // 1 means no friction, less means friction\nvar windDrag = 1.0;\nvar initDelayFrames = 30*2*1;\nvar trainingFrames = 30*20; // assume each match is 7 seconds. (vs 30fps)\nvar theGravity = -9.8*2;\nvar trainingMode = false;\nvar human1 = false; // if this is true, then player 1 is controlled by keyboard\nvar human2 = false; // same as above\nvar humanHasControlled = false;\nvar trainer = null;\nvar generationCounter = 0;\nvar baseScoreFontSize = 64;\nvar traningVersion = false;\n\nvar initGeneJSON1 = '{\"fitness\":1.5,\"nTrial\":0,\"gene\":{\"0\":5.8365,\"1\":1.4432,\"2\":3.1023,\"3\":0.2617,\"4\":-3.5896,\"5\":-1.0675,\"6\":-5.3384,\"7\":0.8505,\"8\":-3.1851,\"9\":-5.6325,\"10\":-3.2459,\"11\":0.7676,\"12\":1.321,\"13\":-1.4931,\"14\":-1.1353,\"15\":-0.2911,\"16\":1.164,\"17\":0.8755,\"18\":-1.1329,\"19\":0.3585,\"20\":-3.9182,\"21\":0.325,\"22\":-0.3397,\"23\":-0.2513,\"24\":0.5678,\"25\":1.9984,\"26\":0.7691,\"27\":2.6176,\"28\":1.791,\"29\":-0.9755,\"30\":1.8437,\"31\":0.4196,\"32\":0.5471,\"33\":-2.6769,\"34\":1.6382,\"35\":1.1442,\"36\":7.1792,\"37\":2.4046,\"38\":0.5512,\"39\":2.8792,\"40\":0.6744,\"41\":3.8023,\"42\":-2.704,\"43\":2.872,\"44\":-3.7659,\"45\":-1.7561,\"46\":-1.5691,\"47\":-5.0168,\"48\":-3.1482,\"49\":0.4531,\"50\":6.3125,\"51\":0.2956,\"52\":2.5486,\"53\":-0.3944,\"54\":-2.7155,\"55\":-5.5154,\"56\":-1.1787,\"57\":-3.8094,\"58\":-2.0738,\"59\":-4.0264,\"60\":3.3217,\"61\":11.0153,\"62\":2.8341,\"63\":-0.2914,\"64\":4.8417,\"65\":-0.9244,\"66\":-3.2621,\"67\":-0.2639,\"68\":-1.3825,\"69\":-1.1969,\"70\":0.7021,\"71\":-4.1637,\"72\":-1.5203,\"73\":-3.1297,\"74\":-1.7193,\"75\":-2.1526,\"76\":4.2902,\"77\":1.4272,\"78\":-0.6137,\"79\":1.1164,\"80\":-0.0067,\"81\":1.0377,\"82\":-0.2344,\"83\":-0.3008,\"84\":-2.3273,\"85\":2.4405,\"86\":-2.3012,\"87\":-1.9193,\"88\":-3.7453,\"89\":1.44,\"90\":-4.5812,\"91\":-1.9701,\"92\":2.3101,\"93\":-4.2018,\"94\":-3.0907,\"95\":1.7332,\"96\":-3.311,\"97\":-2.2417,\"98\":-1.9073,\"99\":5.5644,\"100\":2.5601,\"101\":3.2058,\"102\":0.7374,\"103\":-3.6406,\"104\":-0.6569,\"105\":2.5963,\"106\":3.074,\"107\":-4.7564,\"108\":1.0644,\"109\":-0.7439,\"110\":-0.2318,\"111\":1.1902,\"112\":-2.2391,\"113\":1.5935,\"114\":-4.6269,\"115\":-2.0589,\"116\":-2.2949,\"117\":-0.4391,\"118\":7.0848,\"119\":4.902,\"120\":-0.929,\"121\":3.1709,\"122\":0.163,\"123\":-1.6548,\"124\":-0.0521,\"125\":0.3726,\"126\":-1.3681,\"127\":-0.2623,\"128\":-1.4581,\"129\":0.3422,\"130\":1.1412,\"131\":-0.2376,\"132\":0.7743,\"133\":3.0866,\"134\":-3.6638,\"135\":-0.9372,\"136\":2.5364,\"137\":-1.3026,\"138\":-1.7666,\"139\":-0.1401}}';\n\nvar initGeneJSON2 = '{\"fitness\":1.2,\"nTrial\":0,\"gene\":{\"0\":6.5097,\"1\":2.3385,\"2\":0.1029,\"3\":0.5598,\"4\":-6.3998,\"5\":-1.2678,\"6\":-4.4426,\"7\":0.8709,\"8\":-4.4122,\"9\":-7.7086,\"10\":0.769,\"11\":2.1251,\"12\":0.8503,\"13\":-0.8715,\"14\":-0.9924,\"15\":0.0656,\"16\":1.0124,\"17\":0.1899,\"18\":-2.8846,\"19\":0.3021,\"20\":-6.7481,\"21\":0.3985,\"22\":-4.174,\"23\":1.1515,\"24\":-1.4622,\"25\":-0.5959,\"26\":0.5139,\"27\":2.9706,\"28\":2.043,\"29\":0.189,\"30\":1.3854,\"31\":-4.0551,\"32\":-2.7276,\"33\":-5.0728,\"34\":4.6398,\"35\":4.0611,\"36\":9.7766,\"37\":0.7044,\"38\":0.8835,\"39\":4.2447,\"40\":0.4375,\"41\":1.0766,\"42\":-1.8893,\"43\":-0.6249,\"44\":-3.2812,\"45\":-0.7335,\"46\":-3.1081,\"47\":-4.3488,\"48\":-2.7436,\"49\":0.7618,\"50\":8.131,\"51\":-0.967,\"52\":3.6646,\"53\":2.5841,\"54\":-2.7902,\"55\":-6.0235,\"56\":-3.595,\"57\":-1.7922,\"58\":-3.8774,\"59\":-2.701,\"60\":3.674,\"61\":13.4126,\"62\":3.4967,\"63\":-0.7306,\"64\":2.8581,\"65\":-1.6179,\"66\":-5.6636,\"67\":-0.8102,\"68\":-2.6126,\"69\":-1.5072,\"70\":1.3759,\"71\":-4.8595,\"72\":0.3855,\"73\":-3.3951,\"74\":-3.4629,\"75\":1.0211,\"76\":3.0887,\"77\":-1.372,\"78\":0.7817,\"79\":-1.4717,\"80\":1.3833,\"81\":1.4233,\"82\":-1.5142,\"83\":-1.7674,\"84\":-2.4652,\"85\":1.913,\"86\":-2.3676,\"87\":-1.0603,\"88\":-6.4953,\"89\":0.4749,\"90\":-5.6628,\"91\":-1.6198,\"92\":-0.4882,\"93\":-4.4501,\"94\":-5.0181,\"95\":1.9535,\"96\":-3.4906,\"97\":0.1522,\"98\":-0.4891,\"99\":6.3273,\"100\":2.2241,\"101\":2.1854,\"102\":6.0501,\"103\":-0.2328,\"104\":-0.542,\"105\":4.1188,\"106\":2.343,\"107\":-4.705,\"108\":1.4819,\"109\":-2.1852,\"110\":-0.2348,\"111\":-0.6274,\"112\":0.7755,\"113\":3.2003,\"114\":-6.7855,\"115\":-3.9196,\"116\":-3.1513,\"117\":-1.4553,\"118\":6.7805,\"119\":5.0117,\"120\":-0.4204,\"121\":2.3323,\"122\":-2.7064,\"123\":-1.9625,\"124\":-3.5944,\"125\":2.7761,\"126\":-1.4873,\"127\":-0.477,\"128\":-1.4658,\"129\":0.2057,\"130\":0.4323,\"131\":-0.8676,\"132\":-0.9874,\"133\":2.4903,\"134\":-3.1455,\"135\":-2.6227,\"136\":5.2044,\"137\":-0.6598,\"138\":1.6745,\"139\":1.5329}}';\n\nvar initGeneRaw = JSON.parse(initGeneJSON2);\n\nvar initGene = convnetjs.zeros(Object.keys(initGeneRaw.gene).length); // Float64 faster.\nfor (var i = 0; i < initGene.length; i++) {\n  initGene[i] = initGeneRaw.gene[i];\n}\n\n//initGene = null;\n\n// html elements\nvar myCanvas;\n\nvar handSymbolDisplayed = true;\nfunction moveHandSymbol(x, y) {\n  $(\"#theHand\").css({ \n      \"position\": \"absolute\",\n      \"top\": (y) + \"px\",\n      \"left\": (x-32) + \"px\",\n      \"font-size\": 3.5 +\"em\",\n      \"color\": \"#459AD3\"\n      });\n}\n\nfunction hideHandSymbol() {\n  if (handSymbolDisplayed) {\n    $(\"#theHand\").hide();\n  }\n  handSymbolDisplayed = false;\n}\n\nfunction showHandSymbol() {\n  $(\"#theHand\").fadeIn(500);\n}\n/*\nvar intro = {\n  text: null,\n};\n*/\n\n// declare objects\nvar game = {\n  ball: null,\n  deadball: null,\n  ground: null,\n  fence: null,\n  fenceStub: null,\n  agent1: null,\n  agent2: null\n};\n\n// deal with mobile device nuances\nvar mobileMode = false;\nvar md = null;\n\n// conversion to pixels\nfunction toX(x) {\n  return (x+ref_w/2)*factor;\n}\nfunction toP(x) {\n  return (x)*factor;\n}\nfunction toY(y) {\n  return height-y*factor;\n}\n\nvar delayScreen = {\n  life: initDelayFrames,\n  init: function(life) {\n    this.life = life;\n  },\n  status: function() {\n    if (this.life === 0) {\n      return true;\n    }\n    this.life -= 1;\n    return false;\n  }\n};\n\n// objects\nfunction Particle(loc, v, r, c) { // location p5.Vector, velocity p5.Vector, r float, color\n  \"use strict\";\n  this.loc = loc || createVector(random(-ref_w*1/4, ref_w*1/4), random(ref_w/4, ref_w*3/4));\n  //console.log(this.loc);\n  this.prevLoc = this.loc.copy();\n  this.v = v || createVector(random(-20, 20), random(10, 25));\n  this.r = r || random(0.5, 1.5);\n  this.c = c || getRandomColor(128);\n}\nParticle.prototype.move = function() {\n  this.prevLoc = this.loc.copy();\n  this.loc.add(p5.Vector.mult(this.v, timeStep));\n  this.v.mult(1-(1-windDrag)*timeStep);\n};\nParticle.prototype.applyAcceleration = function(acceleration) {\n  this.v.add(p5.Vector.mult(acceleration, timeStep));\n};\nParticle.prototype.checkEdges = function() {\n  if (this.loc.x<=this.r-ref_w/2) {\n    this.v.x *= -friction;\n    this.loc.x = this.r-ref_w/2+nudge*timeStep;\n  }\n  if (this.loc.x >= (ref_w/2-this.r)) {\n    this.v.x *= -friction;\n    this.loc.x = ref_w/2-this.r-nudge*timeStep;\n  }\n  if (this.loc.y<=this.r+ref_u) {\n    this.v.y *= -friction;\n    this.loc.y = this.r+ref_u+nudge*timeStep;\n    if (this.loc.x <= 0) {\n      return -1;\n    } else {\n      return 1;\n    }\n  }\n  if (this.loc.y >= (ref_h-this.r)) {\n    this.v.y *= -friction;\n    this.loc.y = ref_h-this.r-nudge*timeStep;\n  }\n  // fence:\n  if ((this.loc.x <= (ref_wallwidth/2+this.r)) && (this.prevLoc.x > (ref_wallwidth/2+this.r)) && (this.loc.y <= ref_wallheight)) {\n    this.v.x *= -friction;\n    this.loc.x = ref_wallwidth/2+this.r+nudge*timeStep;\n  }\n  if ((this.loc.x >= (-ref_wallwidth/2-this.r)) && (this.prevLoc.x < (-ref_wallwidth/2-this.r)) && (this.loc.y <= ref_wallheight)) {\n    this.v.x *= -friction;\n    this.loc.x = -ref_wallwidth/2-this.r-nudge*timeStep;\n  }\n  return 0;\n};\nParticle.prototype.getDist2 = function(p) { // returns distance squared from p\n  var dy = p.loc.y - this.loc.y;\n  var dx = p.loc.x - this.loc.x;\n  return (dx*dx+dy*dy);\n};\nParticle.prototype.isColliding = function(p) { // returns true if it is colliding w/ p\n  var r = this.r + p.r;\n  return (r*r > this.getDist2(p)); // if distance is less than total radius, then colliding.\n};\nParticle.prototype.bounce = function(p) { // bounce two balls that have collided (this and that)\n  var ab = createVector();\n  //debugger;\n  ab.set(this.loc);\n  ab.sub(p.loc);\n  ab.normalize();\n  ab.mult(nudge);\n  while(this.isColliding(p)) {\n    this.loc.add(ab);\n  }\n  var n = p5.Vector.sub(this.loc, p.loc);\n  n.normalize();\n  var u = p5.Vector.sub(this.v, p.v);\n  var un = p5.Vector.mult(n, u.dot(n)*2); // added factor of 2\n  u.sub(un);\n  //u.mult(0.5);\n  this.v = p5.Vector.add(u, p.v);\n\n  //p.v = p5.Vector.add(un, p.v); // don't move the agent.\n};\nParticle.prototype.limitSpeed = function(minSpeed, maxSpeed) {\n  var mag2 = this.v.magSq();\n  if (mag2 > (maxSpeed*maxSpeed) ) {\n    this.v.normalize();\n    this.v.mult(maxSpeed);\n  }\n  if (mag2 < (minSpeed*minSpeed) ) {\n    this.v.normalize();\n    this.v.mult(minSpeed);\n  }\n  return;\n};\nParticle.prototype.display = function() {\n  \"use strict\";\n  noStroke();\n  fill(this.c);\n  ellipse(toX(this.loc.x), toY(this.loc.y), toP(this.r)*2, toP(this.r)*2);\n};\n\n// design agent's brain using neural network\nfunction Brain() {\n  \"use strict\";\n  this.nGameInput = 12; // 8 states for agent, plus 4 state for opponent\n  this.nGameOutput = 3; // 3 buttons (forward, backward, jump)\n  this.nRecurrentState = 4; // extra recurrent states for feedback.\n  this.nOutput = this.nGameOutput+this.nRecurrentState;\n  this.nInput = this.nGameInput+this.nOutput;\n\n  // store current inputs and outputs\n  this.inputState = convnetjs.zeros(this.nInput);\n  this.convInputState = new convnetjs.Vol(1, 1, this.nInput); // compatible with convnetjs lib input.\n  this.outputState = convnetjs.zeros(this.nOutput);\n  this.prevOutputState = convnetjs.zeros(this.nOutput);\n\n  // setup neural network:\n  this.layer_defs = [];\n  this.layer_defs.push({\n    type: 'input',\n    out_sx: 1,\n    out_sy: 1,\n    out_depth: this.nInput\n  });\n  this.layer_defs.push({\n    type: 'fc',\n    num_neurons: this.nOutput,\n    activation: 'tanh'\n  });\n\n  this.net = new convnetjs.Net();\n  this.net.makeLayers(this.layer_defs);\n\n  var chromosome = new convnetjs.Chromosome(initGene);\n\n  chromosome.pushToNetwork(this.net);\n\n  //convnetjs.randomizeNetwork(this.net); // set init settings to be random.\n}\nBrain.prototype.populate = function (chromosome) { // populate network with a given chromosome.\n  chromosome.pushToNetwork(this.net);\n};\nBrain.prototype.arrayToString = function(x, precision) {\n  \"use strict\";\n  var result = \"[\";\n  for (var i = 0; i < x.length; i++) {\n    result += Math.round(precision*x[i])/precision;\n    if (i < x.length-1) {\n      result += \",\";\n    }\n  }\n  result += \"]\";\n  return result;\n};\nBrain.prototype.getInputStateString = function() {\n  \"use strict\";\n  return this.arrayToString(this.inputState, 100);\n};\nBrain.prototype.getOutputStateString = function() {\n  \"use strict\";\n  return this.arrayToString(this.outputState, 100);\n};\n// get current input for nn\nBrain.prototype.setCurrentInputState = function (agent, opponent) {\n  \"use strict\";\n  var i;\n  var scaleFactor = 10; // scale inputs to be in the order of magnitude of 10.\n  var scaleFeedback = 1; // to scale back up the feedback.\n  this.inputState[0] = agent.state.x/scaleFactor;\n  this.inputState[1] = agent.state.y/scaleFactor;\n  this.inputState[2] = agent.state.vx/scaleFactor;\n  this.inputState[3] = agent.state.vy/scaleFactor;\n  this.inputState[4] = agent.state.bx/scaleFactor;\n  this.inputState[5] = agent.state.by/scaleFactor;\n  this.inputState[6] = agent.state.bvx/scaleFactor;\n  this.inputState[7] = agent.state.bvy/scaleFactor;\n  this.inputState[8] = 0*opponent.state.x/scaleFactor;\n  this.inputState[9] = 0*opponent.state.y/scaleFactor;\n  this.inputState[10] = 0*opponent.state.vx/scaleFactor;\n  this.inputState[11] = 0*opponent.state.vy/scaleFactor;\n  for (i = 0; i < this.nOutput; i++) { // feeds back output to input\n    this.inputState[i+this.nGameInput] = this.outputState[i]*scaleFeedback;\n  }\n\n  for (i = 0; i < this.nInput; i++) { // copies input state into convnet cube object format to be used later.\n    this.convInputState.w[i] = this.inputState[i];\n  }\n\n};\nBrain.prototype.forward = function () {\n  \"use strict\";\n  // get output from neural network:\n  var a = this.net.forward(this.convInputState);\n  for (var i = 0; i < this.nOutput; i++) {\n    this.prevOutputState[i] = this.outputState[i]; // backs up previous value.\n    this.outputState[i] = a.w[i];\n  }\n};\n\nfunction matchFunction(chromosome1, chromosome2) { // this function is passed to trainer.\n  var result = 0;\n  var oldInitDelayFrames = initDelayFrames;\n  initDelayFrames = 1;\n  trainingMode = true;\n  initGame();\n  // put chromosomes into brains before getting them to duel it out.\n  game.agent1.brain.populate(chromosome1);\n  game.agent2.brain.populate(chromosome2);\n  result = update(trainingFrames); // the dual\n  trainingMode = false;\n  initDelayFrames = oldInitDelayFrames;\n  return result; // -1 means chromosome1 beat chromosome2, 1 means vice versa, 0 means tie.\n}\n\nfunction Trainer(brain, initialGene) {\n  // trainer for neural network interface.  must pass in an initial brain so it knows the net topology.\n  // the constructor won't modify the brain object passed in.\n\n  this.net = new convnetjs.Net();\n  this.net.makeLayers(brain.layer_defs);\n\n  this.trainer = new convnetjs.GATrainer(this.net, {\n      population_size: 50*1,\n      mutation_size: 0.1,\n      mutation_rate: 0.05,\n      num_match: 4*2,\n      elite_percentage: 0.20\n    }, initialGene);\n\n}\nTrainer.prototype.train = function() {\n  this.trainer.matchTrain(matchFunction);\n};\nTrainer.prototype.getChromosome = function(n) {\n  // returns a copy of the nth best chromosome (if not provided, returns first one, which is the best one)\n  n = n || 0;\n  return this.trainer.chromosomes[n].clone();\n};\n\nfunction Agent(dir, loc, c) {\n  \"use strict\";\n  this.dir = dir; // -1 means left, 1 means right player for symmetry.\n  this.loc = loc || createVector(ref_w/4, 1.5);\n  this.v = createVector(0, 0);\n  this.desiredVelocity = createVector(0, 0);\n  this.r = 1.5;\n  this.c = c;\n  this.opponent = null;\n  this.score = 0;\n  this.emotion = \"happy\"; // hehe...\n  this.scoreSize = baseScoreFontSize; // font size for score.\n  this.action = { // the current set of actions the agent wants to take \n    forward : false, // this set of actions can be set either by neural net, or keyboard\n    backward : false,\n    jump : false\n  };\n  this.actionIntensity = [0, 0, 0];\n  this.state = { // complete game state for this agent.  used by neural network.\n    x: 0, // normalized to side, appears different for each agent's perspective\n    y: 0,\n    vx: 0,\n    vy: 0,\n    bx: 0, \n    by: 0,\n    bvx: 0,\n    bvy: 0\n  };\n  this.brain = new Brain();\n}\nAgent.prototype.setOpponent = function(opponent) { // sets the opponent into this agent\n  \"use strict\";\n  this.opponent = opponent;\n};\nAgent.prototype.setAction = function(forward, backward, jump) {\n  \"use strict\";\n  this.action.forward = forward;\n  this.action.backward = backward;\n  this.action.jump = jump;\n};\nAgent.prototype.setBrainAction = function() {\n  \"use strict\"; // this function converts the brain's output layer into actions to move forward, backward, or jump\n  var forward = this.brain.outputState[0] > 0.75; // sigmoid decision.\n  var backward = this.brain.outputState[1] > 0.75; // sigmoid decision.\n  var jump = this.brain.outputState[2] > 0.75; // sigmoid decision.\n  this.setAction(forward, backward, jump);\n};\nAgent.prototype.processAction = function() { // convert action into real movement\n  \"use strict\";\n  var forward = this.action.forward;\n  var backward = this.action.backward;\n  var jump = this.action.jump;\n  this.desiredVelocity.x = 0;\n  this.desiredVelocity.y = 0;\n\n  if (forward && !backward) {\n    this.desiredVelocity.x = -playerSpeedX;\n  }\n  if (backward && !forward) {\n    this.desiredVelocity.x = playerSpeedX;\n  }\n\n  if (jump) {\n    this.desiredVelocity.y = playerSpeedY;\n  }\n};\nAgent.prototype.move = function() {\n  \"use strict\";\n  this.loc.add(p5.Vector.mult(this.v, timeStep));\n};\nAgent.prototype.getState = function() { // returns game state for this agent\n  \"use strict\";\n  this.state = { // complete game state for this agent.  used by neural network.\n    x: this.loc.x*this.dir, // normalized to side, appears different for each agent's perspective\n    y: this.loc.y,\n    vx: this.v.x*this.dir,\n    vy: this.v.y,\n    bx: game.ball.loc.x*this.dir, \n    by: game.ball.loc.y,\n    bvx: game.ball.v.x*this.dir,\n    bvy: game.ball.v.y\n  };\n  return this.state;\n};\nAgent.prototype.printState = function() {\n  // prints the state of the agent on the side of the screen the agent is on\n  // uses p5.js text functions\n  \"use strict\";\n  // print fps\n  var r = 10;\n  var stateText = '';\n  var state = this.getState();\n  stateText += 'X: '+Math.round(state.x*r)/r+'\\n';\n  stateText += 'Y: '+Math.round(state.y*r)/r+'\\n';\n  stateText += 'vx: '+Math.round(state.vx*r)/r+'\\n';\n  stateText += 'vy: '+Math.round(state.vy*r)/r+'\\n';\n  stateText += 'bx: '+Math.round(state.bx*r)/r+'\\n';\n  stateText += 'by: '+Math.round(state.by*r)/r+'\\n';\n  stateText += 'bvx: '+Math.round(state.bvx*r)/r+'\\n';\n  stateText += 'bvy: '+Math.round(state.bvy*r)/r+'\\n';\n  fill(this.c);\n  stroke(this.c);\n  textFont(\"Courier New\");\n  textSize(16);\n  text(stateText, toX(this.dir*ref_w/4), toP(ref_u));\n};\nAgent.prototype.drawState = function(human) { // illustrates inputState and output actions on p5 canvas\n  \"use strict\";\n  var brain = this.brain;\n  var r = red(this.c);\n  var g = green(this.c);\n  var b = blue(this.c);\n  var i, j = 0;\n  var temp;\n  var radius = ref_w/2/((brain.nGameInput-4)+4);\n  var factor = 3/4;\n  var startX = ref_w/4 - radius*((brain.nGameInput-4)/2);\n  var ballFactor = 1.0;\n  var startX2 = ref_w/4 - ballFactor*radius*(brain.nGameOutput/2);\n  var secondLayerY = Math.max(height*1/8+toP(radius)+0.5*toP(radius), height*3/16);\n\n  this.actionIntensity[0] += (this.action.forward ? 16 : 0);\n  this.actionIntensity[1] += (this.action.jump ? 16 : 0);\n  this.actionIntensity[2] += (this.action.backward ? 16 : 0);\n\n  if (!human) {\n    for (i = 0; i < (brain.nGameInput-4); i++) {\n\n      noStroke();\n      fill(r, g, b, brain.inputState[i]*32+8);\n      ellipse(toX((startX+i*radius)*this.dir), height*1/8+toP(radius), toP(radius*factor), toP(radius*factor));\n\n      for (j = 0; j < brain.nGameOutput; j++) {\n\n        if (this.actionIntensity[j] > 64) {\n          stroke(r, g, b, brain.inputState[i]*32);\n          line(toX((startX+i*radius)*this.dir), height*1/8+toP(radius), toX((startX2+ballFactor*j*radius)*this.dir), secondLayerY+(ballFactor+0)*toP(radius));\n        }\n      }\n\n    }\n  }\n\n  for (j = 0; j < brain.nGameOutput; j++) {\n\n      this.actionIntensity[j] -= 4;\n      this.actionIntensity[j] = Math.min(this.actionIntensity[j], 128);\n      this.actionIntensity[j] = Math.max(this.actionIntensity[j], 16);\n\n      noStroke();\n      fill(r, g, b, (this.actionIntensity[j]));\n      ellipse(toX((startX2+ballFactor*j*radius)*this.dir), secondLayerY+(ballFactor+0)*toP(radius), toP(radius*factor)*ballFactor, toP(radius*factor)*ballFactor);\n\n  }\n\n\n};\nAgent.prototype.update = function() {\n  \"use strict\";\n  this.v.add(p5.Vector.mult(gravity, timeStep));\n  if (this.loc.y <= ref_u + nudge*timeStep) {\n    this.v.y = this.desiredVelocity.y;\n  }\n  this.v.x = this.desiredVelocity.x*this.dir;\n  this.move();\n  if (this.loc.y <= ref_u) {\n    this.loc.y = ref_u;\n    this.v.y = 0;\n  }\n\n  // stay in their own half:\n  if (this.loc.x*this.dir <= (ref_wallwidth/2+this.r) ) {\n    this.v.x = 0;\n    this.loc.x = this.dir*(ref_wallwidth/2+this.r);\n  }\n  if (this.loc.x*this.dir >= (ref_w/2-this.r) ) {\n    this.v.x = 0;\n    this.loc.x = this.dir*(ref_w/2-this.r);\n  }\n};\nAgent.prototype.display = function() {\n  \"use strict\";\n  var x = this.loc.x;\n  var y = this.loc.y;\n  var r = this.r;\n  var angle = 60;\n  var eyeX = 0;\n  var eyeY = 0;\n\n  if (this.dir === 1) angle = 135;\n  noStroke();\n  fill(this.c);\n  //ellipse(toX(x), toY(y), toP(r)*2, toP(r)*2);\n  arc(toX(x), toY(y), toP(r)*2, toP(r)*2, Math.PI, 2*Math.PI);\n  /*\n  fill(255);\n  rect(toX(x-r), toY(y), 2*r*factor, r*factor);\n  */\n\n  // track ball with eyes (replace with observed info later):\n  var ballX = game.ball.loc.x-(x+(0.6)*r*fastCos(angle));\n  var ballY = game.ball.loc.y-(y+(0.6)*r*fastSin(angle));\n  if (this.emotion === \"sad\") {\n    ballX = -this.dir;\n    ballY = -2;\n  }\n  var dist = Math.sqrt(ballX*ballX+ballY*ballY);\n  eyeX = ballX/dist;\n  eyeY = ballY/dist;\n\n  fill(255);\n  ellipse(toX(x+(0.6)*r*fastCos(angle)), toY(y+(0.6)*r*fastSin(angle)), toP(r)*0.6, toP(r)*0.6);\n  fill(0);\n  ellipse(toX(x+(0.6)*r*fastCos(angle)+eyeX*0.15*r), toY(y+(0.6)*r*fastSin(angle)+eyeY*0.15*r), toP(r)*0.2, toP(r)*0.2);\n\n};\nAgent.prototype.drawScore = function() {\n  \"use strict\";\n  var r = red(this.c);\n  var g = green(this.c);\n  var b = blue(this.c);\n  var size = this.scoreSize;\n  var factor = 0.95;\n  this.scoreSize = baseScoreFontSize + (this.scoreSize-baseScoreFontSize) * factor;\n\n  if (this.score > 0) {\n    textFont(\"Courier New\");\n    textSize(size);\n    //stroke(255);\n    stroke(r, g, b, 128*(baseScoreFontSize/this.scoreSize));\n    fill(r, g, b, 64*(baseScoreFontSize/this.scoreSize));\n    textAlign(this.dir === -1? LEFT:RIGHT);\n    text(this.score, this.dir === -1? size*3/4 : width-size/4, size/2+height/3);\n  }\n\n};\n\nfunction Wall(x, y, w, h) {\n  \"use strict\";\n  this.x = x;\n  this.y = y;\n  this.w = w;\n  this.h = h;\n  this.c = color(0, 200, 50, 128);\n}\n\nWall.prototype.display = function() {\n  \"use strict\";\n  noStroke();\n  fill(255);\n  rect(toX(this.x-this.w/2), toY(this.y+this.h/2), toP(this.w), toP(this.h));\n  fill(this.c);\n  rect(toX(this.x-this.w/2), toY(this.y+this.h/2), toP(this.w), toP(this.h));\n};\n\nfunction initGame() {\n  game.ball = new Particle(createVector(0, ref_w/4));\n  game.ball.r = 0.25;\n\n  game.agent1 = game.agent1 || new Agent(-1, createVector(-ref_w/4, 1.5), color(240, 75, 0, 255));\n  game.agent2 = game.agent2 || new Agent(1, createVector(ref_w/4, 1.5), color(0, 150, 255, 255));\n\n  game.agent1.setOpponent(game.agent2); // point agent to the other agent as an opponent.\n  game.agent2.setOpponent(game.agent1);\n\n  human1 = false;\n  human2 = false;\n\n  delayScreen.init(initDelayFrames);\n}\n\nfunction setup() {\n  \"use strict\";\n\n  // deal with mobile device nuances\n  md = new MobileDetect(window.navigator.userAgent);\n  if (md.mobile()) {\n      mobileMode = true;\n      console.log('mobile: '+md.mobile());\n  } else {\n      theFrameRate /= 2;\n      console.log('not mobile');\n  }\n\n  myCanvas = createCanvas(windowWidth,windowHeight);\n  factor = windowWidth / ref_w;\n  ref_h = ref_w;\n  myCanvas.parent('p5Container');\n  frameRate(theFrameRate);\n\n  // create html elements\n  //http://otoro.net/slimevolley/\n\n  //intro.text = createA(\"http://blog.otoro.net/2015/03/28/neural-slime-volleyball/\", \"neural slime volleyball\", \"_blank\");\n  //intro.text.position(32+width/32, height/32);\n\n  gravity = createVector(0, theGravity);\n\n  // setup game objects\n  game.ground = new Wall(0, 0.75, ref_w, ref_u);\n  game.fence = new Wall(0, 0.75 + ref_wallheight/2, ref_wallwidth, (ref_wallheight-1.5));\n  game.fence.c = color(240, 210, 130, 255);\n  game.fenceStub = new Particle(createVector(0, ref_wallheight), createVector(0, 0), ref_wallwidth/2, color(240, 210, 130, 255));\n\n  initGame();\n\n  trainer = new Trainer(game.agent1.brain, initGene);\n  game.agent1.brain.populate(trainer.getChromosome()); // best one\n  game.agent2.brain.populate(trainer.getChromosome()); // best one\n}\n\n// updates game element according to physics\nfunction update(nStep) {\n  \"use strict\";\n\n  var result = 0;\n\n  for (var step = 0; step < nStep; step++) {\n\n    // ai here\n    // update internal states\n    game.agent1.getState();\n    game.agent2.getState();\n    // push states to brain\n    game.agent1.brain.setCurrentInputState(game.agent1, game.agent2);\n    game.agent2.brain.setCurrentInputState(game.agent2, game.agent1);\n    // make a decision\n    game.agent1.brain.forward();\n    game.agent2.brain.forward();\n    // convert brain's output signals into game actions\n    game.agent1.setBrainAction();\n    game.agent2.setBrainAction();\n\n    // get human keyboard control\n    if (!trainingMode) {\n      keyboardControl(); // may want to disable this for speed.\n      touchControl(); // mobile device\n      betweenGameControl();\n    }\n\n    // process actions\n    game.agent1.processAction();\n    game.agent2.processAction();\n    game.agent1.update();\n    game.agent2.update();\n\n    if (delayScreen.status() === true) {\n      game.ball.applyAcceleration(gravity);\n      game.ball.limitSpeed(0, maxBallSpeed);\n      game.ball.move();\n    }\n\n    if (game.ball.isColliding(game.agent1)) {\n      game.ball.bounce(game.agent1);\n    }\n    if (game.ball.isColliding(game.agent2)) {\n      game.ball.bounce(game.agent2);\n    }\n    if (game.ball.isColliding(game.fenceStub)) {\n      game.ball.bounce(game.fenceStub);\n    }\n\n    result = game.ball.checkEdges();\n    if (Math.abs(result) > 0) {\n      // make graphics for dead ball\n      if (!trainingMode) {\n        game.deadball = new Particle(game.ball.loc.copy());\n        game.deadball.r = 0.25;\n        game.deadball.life = initDelayFrames;\n      }\n      initGame();\n      if (!trainingMode) {\n        console.log('player '+(result > 0? '1' : '2')+' won.');\n        if (result > 0) {\n          game.agent1.score += 1;\n          game.agent1.scoreSize *= 4;\n          game.agent1.emotion = \"happy\";\n          game.agent2.emotion = \"sad\";\n        } else {\n          game.agent2.score += 1;\n          game.agent2.scoreSize *= 4;\n          game.agent2.emotion = \"happy\";\n          game.agent1.emotion = \"sad\";\n        }\n      }\n      return result;\n    }\n\n  }\n\n  return result; // 0 means tie, -1 means landed on left side, 1 means landed on right side.\n}\n\nfunction drawScenery() {\n  // draws the scenery\n  for (var i = 0; i < 24; i++) {\n    noStroke();\n    fill(50, 100, 240, 16*(24-i)/24);\n    rect(0, i*height/24/3, width, height/24/3);\n  }\n  fill(255, 240, 0, 64);\n  noStroke();\n  ellipse(toX(-ref_w/4), 1*height/2, 2*factor, 2*factor);\n  fill(50, 255, 50, 16);\n  ellipse(toX(ref_w/8), toY(-1.5), 12*factor, 20*factor);\n  fill(50, 255, 50, 16);\n  ellipse(toX(-ref_w/8), toY(-1.5), 8*factor, 12*factor);\n  fill(50, 255, 50, 16);\n  ellipse(toX(ref_w/3), toY(-1.5), 6*factor, 24*factor);\n}\n\nfunction keyboardControl() {\n  // player 1:\n  var a1_forward = 68; // 'd' key\n  var a1_backward = 65; // 'a' key\n  var a1_jump = 87; // 'w' key\n  // player 2:\n  var a2_forward = LEFT_ARROW;\n  var a2_backward = RIGHT_ARROW;\n  var a2_jump = UP_ARROW;\n\n  if (keyIsDown(a1_forward) || keyIsDown(a1_backward) || keyIsDown(a1_jump)) {\n    human1 = true;\n    humanHasControlled = true;\n  }\n  if (human1) {\n    game.agent1.setAction(keyIsDown(a1_forward), keyIsDown(a1_backward), keyIsDown(a1_jump));\n  }\n\n  if (keyIsDown(a2_forward) || keyIsDown(a2_backward) || keyIsDown(a2_jump)) {\n    human2 = true;\n    humanHasControlled = true;\n  }\n  if (human2) {\n    game.agent2.setAction(keyIsDown(a2_forward), keyIsDown(a2_backward), keyIsDown(a2_jump));\n  }\n\n}\n\nfunction touchControl() {\n  \"use strict\";\n  var paddingY = height/64;\n  var paddingX = width/64;\n  var dx = 0;\n  var dy = 0;\n  var x = 0;\n  var y = 0;\n  var agentX = toX(game.agent2.loc.x);\n  var agentY = toY(game.agent2.loc.y);\n  var jumpY = toY(ref_wallheight*2);\n  var gestureEvent = false;\n\n  if (touchIsDown) {\n    x = touchX;\n    y = touchY;\n    dx = touchX-ptouchX;\n    dy = touchY-ptouchY;\n    gestureEvent = true;\n  }\n\n  if (mouseIsPressed) {\n    x = mouseX;\n    y = mouseY;\n    dx = mouseX-pmouseX;\n    dy = mouseY-pmouseY;\n    gestureEvent = true;\n  }\n\n  if (gestureEvent) {\n    human2 = true;\n    humanHasControlled = true;\n    game.agent2.setAction((x - agentX) < -paddingX, (x - agentX) > paddingX, dy < -paddingY);\n  }\n\n}\n\n// between end of this match to the next match.  guy wins jumps, guy who loses regrets...\nfunction betweenGameControl() {\n  \"use strict\";\n  var agent = [game.agent1, game.agent2];\n  if (delayScreen.life > 0) {\n    for (var i = 0; i < 2; i++) {\n      if (agent[i].emotion === \"happy\") {\n        agent[i].action.jump = true;\n      } else {\n        agent[i].action.jump = false;\n      }\n    }\n  } else {\n    agent[0].emotion = \"happy\";\n    agent[1].emotion = \"happy\";\n  }\n}\n\nfunction getNNDebugString() {\n  \"use strict\";\n  var result = \"\";\n  result += \"agent1:\\n\";\n  result += \"input1: \"+JSON.stringify(game.agent1.brain.getInputStateString())+\"\\n\";\n  result += \"output1: \"+JSON.stringify(game.agent1.brain.getOutputStateString())+\"\\n\";\n  result += \"agent2:\\n\";\n  result += \"input2: \"+JSON.stringify(game.agent2.brain.getInputStateString())+\"\\n\";\n  result += \"output2: \"+JSON.stringify(game.agent2.brain.getOutputStateString())+\"\\n\";\n  return result;\n}\n\nfunction arrayToString(x, precision) {\n  \"use strict\";\n  precision = precision || 1000;\n  var result = \"[\";\n  for (var i = 0; i < x.length; i++) {\n    result += Math.round(precision*x[i])/precision;\n    if (i < x.length-1) {\n      result += \",\";\n    }\n  }\n  result += \"]\";\n  return result;\n}\n\n// cool p5.js functions to draw p-noise bouncy keyboard control graphics.\nvar pNoiseSeed = 0;\nfunction drawArrowKeyboard(x, y, s1, c, intensity, theColor) {\n  \"use strict\";\n\n  var rc = red(theColor);\n  var gc = green(theColor);\n  var bc = blue(theColor);\n\n  function nextNoise() {\n    var pFactor = 10;\n    var f = 5;\n    pNoiseSeed = pNoiseSeed || 0;\n    pNoiseSeed += 1;\n    return (noise(pNoiseSeed / pFactor)-0.5)*f;\n  }\n\n  function drawArrowKey(x, y, s, r) {\n\n\n    var f = 5;\n    //console.log(nextNoise());\n    stroke(rc, gc, bc, intensity);\n    noFill();\n    beginShape();\n    var x1offset = nextNoise();\n    var y1offset = nextNoise();\n    var x2offset = nextNoise();\n    var y2offset = nextNoise();\n    var x3offset = nextNoise();\n    var y3offset = nextNoise();\n    curveVertex(x-s+x1offset, y+s-r+y1offset);\n    curveVertex(x-s+x2offset, y-s+r+y2offset);\n    curveVertex(x-s+r+x3offset, y-s+y3offset);\n    curveVertex(x+s-r+nextNoise(), y-s+nextNoise());\n    curveVertex(x+s+nextNoise(), y-s+r+nextNoise());\n    curveVertex(x+s+nextNoise(), y+s-r+nextNoise());\n    curveVertex(x+s-r+nextNoise(), y+s+nextNoise());\n    curveVertex(x-s+r+nextNoise(), y+s+nextNoise());\n    curveVertex(x-s+x1offset, y+s-r+y1offset);\n    curveVertex(x-s+x2offset, y-s+r+y2offset);\n    curveVertex(x-s+r+x3offset, y-s+y3offset);\n    endShape();\n    noStroke();\n  }\n\n  var s2 = s1 * 0.8;\n  var r1 = s1 * 0.2;\n  var r2 = s2 * 0.2;\n  var fontSize = 32;\n\n  function drawFullKey(x, y, c) {\n    drawArrowKey(x, y, s1/2, r1);\n    drawArrowKey(x, y, s2/2, r2);\n\n    stroke(rc, gc, bc, intensity);\n    fill(rc, gc, bc, intensity);\n\n    text(c, x+nextNoise()/1-fontSize/2, y+nextNoise()/1+fontSize/4);\n  }\n\n  textFont(\"monospace\");\n  textSize(fontSize);\n  drawFullKey(x-s1, y, c[0]);\n  drawFullKey(x, y-s1, c[1]);\n  drawFullKey(x+s1, y, c[2]);\n\n}\n\n// n = 1, first agent, n = 2, second agent.\nfunction drawAgentKeyboard(x, y, s, n, intensity, theColor) {\n  var c = ['ａ', 'ｗ', 'ｄ'];\n  if (n == 2) c = ['◀', '▲', '▶'];\n  drawArrowKeyboard(x, y, s, c, intensity, theColor);\n}\n\nfunction draw() {\n  \"use strict\";\n  var result = 0;\n\n  background(255);\n\n  // draw box around frame\n\n  result = update(1);\n\n  if (result !== 0 && traningVersion) { // someone has lost\n    var genStep = 50;\n    console.log('training generation #'+(generationCounter+genStep));\n    for (var i = 0; i < genStep; i++) {\n      trainer.train();\n    }\n    // print results\n    for (i = 0; i < 4; i++) {\n      console.log('#'+i+':'+Math.round(100*trainer.getChromosome(i).fitness)/100);\n    }\n    var N = trainer.trainer.population_size;\n    for (i = N-4; i < N; i++) {\n      console.log('#'+i+':'+Math.round(100*trainer.getChromosome(i).fitness)/100);\n    }\n    if (traningVersion) {\n      $(\"#nn_gene\").text(JSON.stringify(trainer.getChromosome()));\n    }\n    generationCounter += genStep;\n    initGame();\n    game.agent1.brain.populate(trainer.getChromosome(0)); // best one\n    game.agent2.brain.populate(trainer.getChromosome(1)); // second best one\n  }\n\n  // draw the game objects\n  drawScenery();\n  game.agent1.display();\n  game.agent2.display();\n\n  if (!mobileMode && showArrowKeys & !humanHasControlled) {\n    var intensity = 64*Math.min(16*(delayScreen.life/initDelayFrames)*(initDelayFrames-delayScreen.life)/initDelayFrames, 64);\n    drawAgentKeyboard(width/4, toY(ref_wallheight*1), width/12, 1, intensity, game.agent1.c);\n    drawAgentKeyboard(3*width/4, toY(ref_wallheight*1), width/12, 2, intensity, game.agent2.c);\n  }\n  if (!humanHasControlled && handSymbolDisplayed ) {\n    moveHandSymbol(toX(game.agent2.loc.x), toY(game.agent2.loc.y)-height/2.5);\n  } else {\n    hideHandSymbol();\n  }\n\n  game.ball.c = color(255, 200, 20, 255*Math.max((initDelayFrames-delayScreen.life)/initDelayFrames, 0));\n  game.ball.display();\n  game.ground.display();\n  game.fence.display();\n  game.fenceStub.display();\n\n  // prints agent states (used for nn input)\n  //game.agent1.printState();\n  //game.agent2.printState();\n\n  game.agent1.drawState(human1);\n  game.agent2.drawState(human2);\n\n  game.agent1.drawScore();\n  game.agent2.drawScore();\n\n  // draw dead ball\n  if (game.deadball) {\n    game.deadball.life -= 1;\n    game.deadball.c = color(250, 0, 0, 128*(game.deadball.life/initDelayFrames));\n    game.deadball.display();\n    if (game.deadball.life <= 0) {\n      game.deadball = null;\n    }\n  }\n\n  //$(\"#nn_weights\").text(getNNDebugString());\n\n}\n\nfunction windowResized() {\n  \"use strict\";\n  resizeCanvas(windowWidth, windowHeight);\n  myCanvas.size(windowWidth, windowHeight);\n  factor = windowWidth / ref_w;\n}\n\n// When the mouse is released \nvar deviceReleased = function() {\n  \"use strict\";\n};\n\n// When the mouse is pressed we. . .\nvar devicePressed = function(x, y) {\n  \"use strict\";\n};\n\nvar deviceDragged = function(x, y) {\n  \"use strict\";\n};\n\nvar mousePressed = function() {\n  \"use strict\";\n  devicePressed(mouseX, mouseY);\n  return false;\n};\n\nvar touchStarted = function() {\n  \"use strict\";\n  devicePressed(touchX, touchY);\n  return false;\n};\n\n// interaction with touchpad and mosue:\n\nvar mouseDragged = function() {\n  \"use strict\";\n  deviceDragged(mouseX, mouseY);\n  return false;\n};\n\nvar touchMoved = function() {\n  \"use strict\";\n  return false;\n};\n\nvar mouseReleased = function() {\n  \"use strict\";\n  return false;\n};\n\nvar touchEnded = function() {\n  \"use strict\";\n  return false;\n};\n\n\n\n"
  },
  {
    "path": "slimevolley_pro.js",
    "content": "\n\n/*    \n\np5.js implementation of slime volleyball, with evolved neural networks to be the ai.\n\n@licstart  The following is the entire license notice for the \nJavaScript code in this page.\n\nCopyright (C) 2015 david ha, otoro.net, otoro labs\n\nThe JavaScript code in this page is free software: you can\nredistribute it and/or modify it under the terms of the GNU\nGeneral Public License (GNU GPL) as published by the Free Software\nFoundation, either version 3 of the License, or (at your option)\nany later version.  The code is distributed WITHOUT ANY WARRANTY;\nwithout even the implied warranty of MERCHANTABILITY or FITNESS\nFOR A PARTICULAR PURPOSE.  See the GNU GPL for more details.\n\nAs additional permission under GNU GPL version 3 section 7, you\nmay distribute non-source (e.g., minimized or compacted) forms of\nthat code without the copy of the GNU GPL normally required by\nsection 4, provided you include this license notice and a URL\nthrough which recipients can access the Corresponding Source.   \n\n\n@licend  The above is the entire license notice\nfor the JavaScript code in this page.\n*/\n\n// game settings:\nvar showArrowKeys = true;\nvar ref_w = 24*2;\nvar ref_h = ref_w;\nvar ref_u = 1.5; // ground height\nvar ref_wallwidth = 1.0; // wall width\nvar ref_wallheight = 3.5;\nvar factor = 1;\nvar playerSpeedX = 10*1.75;\nvar playerSpeedY = 10*1.35;\nvar maxBallSpeed = 15*1.5;\nvar gravity;\nvar timeStep = 1/30;\nvar theFrameRate = 60*1;\nvar nudge = 0.1;\nvar friction = 1.0; // 1 means no friction, less means friction\nvar windDrag = 1.0;\nvar initDelayFrames = 30*2*1;\nvar trainingFrames = 30*20; // assume each match is 7 seconds. (vs 30fps)\nvar theGravity = -9.8*2*1.5;\nvar trainingMode = false;\nvar human1 = false; // if this is true, then player 1 is controlled by keyboard\nvar human2 = false; // same as above\nvar humanHasControlled = false;\nvar trainer = null;\nvar generationCounter = 0;\nvar baseScoreFontSize = 64;\n//var trainingVersion = false; // this variable is stored on html file pro.html\n\nvar initGeneJSON = '{\"fitness\":1.3846153846153846,\"nTrial\":0,\"gene\":{\"0\":7.5555,\"1\":4.5121,\"2\":2.357,\"3\":0.139,\"4\":-8.3413,\"5\":-2.36,\"6\":-3.3343,\"7\":0.0262,\"8\":-7.4142,\"9\":-8.0999,\"10\":2.1553,\"11\":2.4759,\"12\":1.5587,\"13\":-0.7062,\"14\":0.2747,\"15\":0.1406,\"16\":0.8988,\"17\":0.4121,\"18\":-2.082,\"19\":1.4061,\"20\":-12.1837,\"21\":1.2683,\"22\":-0.3427,\"23\":-6.1471,\"24\":5.064,\"25\":1.2345,\"26\":0.3956,\"27\":-2.5808,\"28\":0.665,\"29\":-0.0652,\"30\":0.1629,\"31\":-2.3924,\"32\":-3.9673,\"33\":-6.1155,\"34\":5.97,\"35\":2.9588,\"36\":6.6727,\"37\":-2.2779,\"38\":2.0302,\"39\":13.094,\"40\":2.7659,\"41\":-1.3683,\"42\":2.5079,\"43\":-2.6932,\"44\":-2.0672,\"45\":-4.2688,\"46\":-4.9919,\"47\":-1.1571,\"48\":-2.0693,\"49\":2.9565,\"50\":9.6875,\"51\":-0.7638,\"52\":-1.5896,\"53\":2.4563,\"54\":-2.5956,\"55\":-9.8478,\"56\":-4.9463,\"57\":-3.4502,\"58\":-3.0604,\"59\":-1.158,\"60\":6.3533,\"61\":16.0047,\"62\":1.4911,\"63\":7.9886,\"64\":2.3879,\"65\":-4.5006,\"66\":-1.8171,\"67\":0.9859,\"68\":-2.414,\"69\":-1.5698,\"70\":2.5173,\"71\":-8.6187,\"72\":-0.3068,\"73\":-3.6185,\"74\":-5.202,\"75\":-0.05,\"76\":7.2617,\"77\":-3.1099,\"78\":0.9881,\"79\":-0.5022,\"80\":1.6499,\"81\":2.1346,\"82\":2.8479,\"83\":2.1166,\"84\":-6.177,\"85\":0.2584,\"86\":-3.7623,\"87\":-4.8107,\"88\":-9.1331,\"89\":-2.9681,\"90\":-7.1177,\"91\":-1.4894,\"92\":-1.1885,\"93\":-4.1906,\"94\":-5.821,\"95\":-4.3202,\"96\":-1.4603,\"97\":2.3514,\"98\":-4.8101,\"99\":3.6935,\"100\":1.388,\"101\":3.2504,\"102\":6.6364,\"103\":-3.7216,\"104\":1.6191,\"105\":6.4388,\"106\":0.4765,\"107\":-4.4931,\"108\":-1.1007,\"109\":-4.3594,\"110\":-2.9777,\"111\":-0.3744,\"112\":3.5822,\"113\":3.9402,\"114\":-9.2382,\"115\":-4.3392,\"116\":0.2103,\"117\":-1.3699,\"118\":9.2494,\"119\":10.8483,\"120\":0.2389,\"121\":2.6535,\"122\":-8.2731,\"123\":-3.5133,\"124\":-5.0808,\"125\":3.0846,\"126\":-0.4851,\"127\":0.3938,\"128\":0.2459,\"129\":-0.3466,\"130\":-0.1684,\"131\":-0.7868,\"132\":-0.6009,\"133\":2.5491,\"134\":-3.2234,\"135\":-3.3352,\"136\":4.7229,\"137\":-4.1547,\"138\":3.6065,\"139\":-0.1261}}';\n\nvar initGeneRaw = JSON.parse(initGeneJSON);\n\nvar initGene = convnetjs.zeros(Object.keys(initGeneRaw.gene).length); // Float64 faster.\nfor (var i = 0; i < initGene.length; i++) {\n  initGene[i] = initGeneRaw.gene[i];\n}\n\n//initGene = null;\n\n// html elements\nvar myCanvas;\n\nvar handSymbolDisplayed = true;\nfunction moveHandSymbol(x, y) {\n  $(\"#theHand\").css({ \n      \"position\": \"absolute\",\n      \"top\": (y) + \"px\",\n      \"left\": (x-32) + \"px\",\n      \"font-size\": 3.5 +\"em\",\n      \"color\": \"#459AD3\"\n      });\n}\n\nfunction hideHandSymbol() {\n  if (handSymbolDisplayed) {\n    $(\"#theHand\").hide();\n  }\n  handSymbolDisplayed = false;\n}\n\nfunction showHandSymbol() {\n  $(\"#theHand\").fadeIn(500);\n}\n/*\nvar intro = {\n  text: null,\n};\n*/\n\n// declare objects\nvar game = {\n  ball: null,\n  deadball: null,\n  ground: null,\n  fence: null,\n  fenceStub: null,\n  agent1: null,\n  agent2: null\n};\n\n// deal with mobile device nuances\nvar mobileMode = false;\nvar md = null;\n\n// conversion to pixels\nfunction toX(x) {\n  return (x+ref_w/2)*factor;\n}\nfunction toP(x) {\n  return (x)*factor;\n}\nfunction toY(y) {\n  return height-y*factor;\n}\n\nvar delayScreen = {\n  life: initDelayFrames,\n  init: function(life) {\n    this.life = life;\n  },\n  status: function() {\n    if (this.life === 0) {\n      return true;\n    }\n    this.life -= 1;\n    return false;\n  }\n};\n\n// objects\nfunction Particle(loc, v, r, c) { // location p5.Vector, velocity p5.Vector, r float, color\n  \"use strict\";\n  this.loc = loc || createVector(random(-ref_w*1/4, ref_w*1/4), random(ref_w/4, ref_w*3/4));\n  //console.log(this.loc);\n  this.prevLoc = this.loc.copy();\n  this.v = v || createVector(random(-20, 20), random(10, 25));\n  this.r = r || random(0.5, 1.5);\n  this.c = c || getRandomColor(128);\n}\nParticle.prototype.move = function() {\n  this.prevLoc = this.loc.copy();\n  this.loc.add(p5.Vector.mult(this.v, timeStep));\n  this.v.mult(1-(1-windDrag)*timeStep);\n};\nParticle.prototype.applyAcceleration = function(acceleration) {\n  this.v.add(p5.Vector.mult(acceleration, timeStep));\n};\nParticle.prototype.checkEdges = function() {\n  if (this.loc.x<=this.r-ref_w/2) {\n    this.v.x *= -friction;\n    this.loc.x = this.r-ref_w/2+nudge*timeStep;\n  }\n  if (this.loc.x >= (ref_w/2-this.r)) {\n    this.v.x *= -friction;\n    this.loc.x = ref_w/2-this.r-nudge*timeStep;\n  }\n  if (this.loc.y<=this.r+ref_u) {\n    this.v.y *= -friction;\n    this.loc.y = this.r+ref_u+nudge*timeStep;\n    if (this.loc.x <= 0) {\n      return -1;\n    } else {\n      return 1;\n    }\n  }\n  if (this.loc.y >= (ref_h-this.r)) {\n    this.v.y *= -friction;\n    this.loc.y = ref_h-this.r-nudge*timeStep;\n  }\n  // fence:\n  if ((this.loc.x <= (ref_wallwidth/2+this.r)) && (this.prevLoc.x > (ref_wallwidth/2+this.r)) && (this.loc.y <= ref_wallheight)) {\n    this.v.x *= -friction;\n    this.loc.x = ref_wallwidth/2+this.r+nudge*timeStep;\n  }\n  if ((this.loc.x >= (-ref_wallwidth/2-this.r)) && (this.prevLoc.x < (-ref_wallwidth/2-this.r)) && (this.loc.y <= ref_wallheight)) {\n    this.v.x *= -friction;\n    this.loc.x = -ref_wallwidth/2-this.r-nudge*timeStep;\n  }\n  return 0;\n};\nParticle.prototype.getDist2 = function(p) { // returns distance squared from p\n  var dy = p.loc.y - this.loc.y;\n  var dx = p.loc.x - this.loc.x;\n  return (dx*dx+dy*dy);\n};\nParticle.prototype.isColliding = function(p) { // returns true if it is colliding w/ p\n  var r = this.r + p.r;\n  return (r*r > this.getDist2(p)); // if distance is less than total radius, then colliding.\n};\nParticle.prototype.bounce = function(p) { // bounce two balls that have collided (this and that)\n  var ab = createVector();\n  //debugger;\n  ab.set(this.loc);\n  ab.sub(p.loc);\n  ab.normalize();\n  ab.mult(nudge);\n  while(this.isColliding(p)) {\n    this.loc.add(ab);\n  }\n  var n = p5.Vector.sub(this.loc, p.loc);\n  n.normalize();\n  var u = p5.Vector.sub(this.v, p.v);\n  var un = p5.Vector.mult(n, u.dot(n)*2); // added factor of 2\n  u.sub(un);\n  //u.mult(0.5);\n  this.v = p5.Vector.add(u, p.v);\n\n  //p.v = p5.Vector.add(un, p.v); // don't move the agent.\n};\nParticle.prototype.limitSpeed = function(minSpeed, maxSpeed) {\n  var mag2 = this.v.magSq();\n  if (mag2 > (maxSpeed*maxSpeed) ) {\n    this.v.normalize();\n    this.v.mult(maxSpeed);\n  }\n  if (mag2 < (minSpeed*minSpeed) ) {\n    this.v.normalize();\n    this.v.mult(minSpeed);\n  }\n  return;\n};\nParticle.prototype.display = function() {\n  \"use strict\";\n  noStroke();\n  fill(this.c);\n  ellipse(toX(this.loc.x), toY(this.loc.y), toP(this.r)*2, toP(this.r)*2);\n};\n\n// design agent's brain using neural network\nfunction Brain() {\n  \"use strict\";\n  this.nGameInput = 12; // 8 states for agent, plus 4 state for opponent\n  this.nGameOutput = 3; // 3 buttons (forward, backward, jump)\n  this.nRecurrentState = 4; // extra recurrent states for feedback.\n  this.nOutput = this.nGameOutput+this.nRecurrentState;\n  this.nInput = this.nGameInput+this.nOutput;\n\n  // store current inputs and outputs\n  this.inputState = convnetjs.zeros(this.nInput);\n  this.convInputState = new convnetjs.Vol(1, 1, this.nInput); // compatible with convnetjs lib input.\n  this.outputState = convnetjs.zeros(this.nOutput);\n  this.prevOutputState = convnetjs.zeros(this.nOutput);\n\n  // setup neural network:\n  this.layer_defs = [];\n  this.layer_defs.push({\n    type: 'input',\n    out_sx: 1,\n    out_sy: 1,\n    out_depth: this.nInput\n  });\n  this.layer_defs.push({\n    type: 'fc',\n    num_neurons: this.nOutput,\n    activation: 'tanh'\n  });\n\n  this.net = new convnetjs.Net();\n  this.net.makeLayers(this.layer_defs);\n\n  var chromosome = new convnetjs.Chromosome(initGene);\n\n  chromosome.pushToNetwork(this.net);\n\n  //convnetjs.randomizeNetwork(this.net); // set init settings to be random.\n}\nBrain.prototype.populate = function (chromosome) { // populate network with a given chromosome.\n  chromosome.pushToNetwork(this.net);\n};\nBrain.prototype.arrayToString = function(x, precision) {\n  \"use strict\";\n  var result = \"[\";\n  for (var i = 0; i < x.length; i++) {\n    result += Math.round(precision*x[i])/precision;\n    if (i < x.length-1) {\n      result += \",\";\n    }\n  }\n  result += \"]\";\n  return result;\n};\nBrain.prototype.getInputStateString = function() {\n  \"use strict\";\n  return this.arrayToString(this.inputState, 100);\n};\nBrain.prototype.getOutputStateString = function() {\n  \"use strict\";\n  return this.arrayToString(this.outputState, 100);\n};\n// get current input for nn\nBrain.prototype.setCurrentInputState = function (agent, opponent) {\n  \"use strict\";\n  var i;\n  var scaleFactor = 10; // scale inputs to be in the order of magnitude of 10.\n  var scaleFeedback = 1; // to scale back up the feedback.\n  this.inputState[0] = agent.state.x/scaleFactor;\n  this.inputState[1] = agent.state.y/scaleFactor;\n  this.inputState[2] = agent.state.vx/scaleFactor;\n  this.inputState[3] = agent.state.vy/scaleFactor;\n  this.inputState[4] = agent.state.bx/scaleFactor;\n  this.inputState[5] = agent.state.by/scaleFactor;\n  this.inputState[6] = agent.state.bvx/scaleFactor;\n  this.inputState[7] = agent.state.bvy/scaleFactor;\n  this.inputState[8] = 0*opponent.state.x/scaleFactor;\n  this.inputState[9] = 0*opponent.state.y/scaleFactor;\n  this.inputState[10] = 0*opponent.state.vx/scaleFactor;\n  this.inputState[11] = 0*opponent.state.vy/scaleFactor;\n  for (i = 0; i < this.nOutput; i++) { // feeds back output to input\n    this.inputState[i+this.nGameInput] = this.outputState[i]*scaleFeedback*1; \n  }\n\n  for (i = 0; i < this.nInput; i++) { // copies input state into convnet cube object format to be used later.\n    this.convInputState.w[i] = this.inputState[i];\n  }\n\n};\nBrain.prototype.forward = function () {\n  \"use strict\";\n  // get output from neural network:\n  var a = this.net.forward(this.convInputState);\n  for (var i = 0; i < this.nOutput; i++) {\n    this.prevOutputState[i] = this.outputState[i]; // backs up previous value.\n    this.outputState[i] = a.w[i];\n  }\n};\n\nfunction matchFunction(chromosome1, chromosome2) { // this function is passed to trainer.\n  var result = 0;\n  var oldInitDelayFrames = initDelayFrames;\n  initDelayFrames = 1;\n  trainingMode = true;\n  initGame();\n  // put chromosomes into brains before getting them to duel it out.\n  game.agent1.brain.populate(chromosome1);\n  game.agent2.brain.populate(chromosome2);\n  result = update(trainingFrames); // the dual\n  trainingMode = false;\n  initDelayFrames = oldInitDelayFrames;\n  return result; // -1 means chromosome1 beat chromosome2, 1 means vice versa, 0 means tie.\n}\n\nfunction Trainer(brain, initialGene) {\n  // trainer for neural network interface.  must pass in an initial brain so it knows the net topology.\n  // the constructor won't modify the brain object passed in.\n\n  this.net = new convnetjs.Net();\n  this.net.makeLayers(brain.layer_defs);\n\n  this.trainer = new convnetjs.GATrainer(this.net, {\n      population_size: 100*1,\n      mutation_size: 0.3,\n      mutation_rate: 0.05,\n      num_match: 4*2,\n      elite_percentage: 0.20\n    }, initialGene);\n\n}\nTrainer.prototype.train = function() {\n  this.trainer.matchTrain(matchFunction);\n};\nTrainer.prototype.getChromosome = function(n) {\n  // returns a copy of the nth best chromosome (if not provided, returns first one, which is the best one)\n  n = n || 0;\n  return this.trainer.chromosomes[n].clone();\n};\n\nfunction Agent(dir, loc, c) {\n  \"use strict\";\n  this.dir = dir; // -1 means left, 1 means right player for symmetry.\n  this.loc = loc || createVector(ref_w/4, 1.5);\n  this.v = createVector(0, 0);\n  this.desiredVelocity = createVector(0, 0);\n  this.r = 1.5;\n  this.c = c;\n  this.opponent = null;\n  this.score = 0;\n  this.emotion = \"happy\"; // hehe...\n  this.scoreSize = baseScoreFontSize; // font size for score.\n  this.action = { // the current set of actions the agent wants to take \n    forward : false, // this set of actions can be set either by neural net, or keyboard\n    backward : false,\n    jump : false\n  };\n  this.actionIntensity = [0, 0, 0];\n  this.state = { // complete game state for this agent.  used by neural network.\n    x: 0, // normalized to side, appears different for each agent's perspective\n    y: 0,\n    vx: 0,\n    vy: 0,\n    bx: 0, \n    by: 0,\n    bvx: 0,\n    bvy: 0\n  };\n  this.brain = new Brain();\n}\nAgent.prototype.setOpponent = function(opponent) { // sets the opponent into this agent\n  \"use strict\";\n  this.opponent = opponent;\n};\nAgent.prototype.setAction = function(forward, backward, jump) {\n  \"use strict\";\n  this.action.forward = forward;\n  this.action.backward = backward;\n  this.action.jump = jump;\n};\nAgent.prototype.setBrainAction = function() {\n  \"use strict\"; // this function converts the brain's output layer into actions to move forward, backward, or jump\n  var forward = this.brain.outputState[0] > 0.75; // sigmoid decision.\n  var backward = this.brain.outputState[1] > 0.75; // sigmoid decision.\n  var jump = this.brain.outputState[2] > 0.75; // sigmoid decision.\n  this.setAction(forward, backward, jump);\n};\nAgent.prototype.processAction = function() { // convert action into real movement\n  \"use strict\";\n  var forward = this.action.forward;\n  var backward = this.action.backward;\n  var jump = this.action.jump;\n  this.desiredVelocity.x = 0;\n  this.desiredVelocity.y = 0;\n\n  if (forward && !backward) {\n    this.desiredVelocity.x = -playerSpeedX;\n  }\n  if (backward && !forward) {\n    this.desiredVelocity.x = playerSpeedX;\n  }\n\n  if (jump) {\n    this.desiredVelocity.y = playerSpeedY;\n  }\n};\nAgent.prototype.move = function() {\n  \"use strict\";\n  this.loc.add(p5.Vector.mult(this.v, timeStep));\n};\nAgent.prototype.getState = function() { // returns game state for this agent\n  \"use strict\";\n  this.state = { // complete game state for this agent.  used by neural network.\n    x: this.loc.x*this.dir, // normalized to side, appears different for each agent's perspective\n    y: this.loc.y,\n    vx: this.v.x*this.dir,\n    vy: this.v.y,\n    bx: game.ball.loc.x*this.dir, \n    by: game.ball.loc.y,\n    bvx: game.ball.v.x*this.dir,\n    bvy: game.ball.v.y\n  };\n  return this.state;\n};\nAgent.prototype.printState = function() {\n  // prints the state of the agent on the side of the screen the agent is on\n  // uses p5.js text functions\n  \"use strict\";\n  // print fps\n  var r = 10;\n  var stateText = '';\n  var state = this.getState();\n  stateText += 'X: '+Math.round(state.x*r)/r+'\\n';\n  stateText += 'Y: '+Math.round(state.y*r)/r+'\\n';\n  stateText += 'vx: '+Math.round(state.vx*r)/r+'\\n';\n  stateText += 'vy: '+Math.round(state.vy*r)/r+'\\n';\n  stateText += 'bx: '+Math.round(state.bx*r)/r+'\\n';\n  stateText += 'by: '+Math.round(state.by*r)/r+'\\n';\n  stateText += 'bvx: '+Math.round(state.bvx*r)/r+'\\n';\n  stateText += 'bvy: '+Math.round(state.bvy*r)/r+'\\n';\n  fill(this.c);\n  stroke(this.c);\n  textFont(\"Courier New\");\n  textSize(16);\n  text(stateText, toX(this.dir*ref_w/4), toP(ref_u));\n};\nAgent.prototype.drawState = function(human) { // illustrates inputState and output actions on p5 canvas\n  \"use strict\";\n  var brain = this.brain;\n  var r = red(this.c);\n  var g = green(this.c);\n  var b = blue(this.c);\n  var i, j = 0;\n  var temp;\n  var radius = ref_w/2/((brain.nGameInput-4)+4);\n  var factor = 3/4;\n  var startX = ref_w/4 - radius*((brain.nGameInput-4)/2);\n  var ballFactor = 1.0;\n  var startX2 = ref_w/4 - ballFactor*radius*(brain.nGameOutput/2);\n  var secondLayerY = Math.max(height*1/8+toP(radius)+0.5*toP(radius), height*3/16);\n\n  this.actionIntensity[0] += (this.action.forward ? 16 : 0);\n  this.actionIntensity[1] += (this.action.jump ? 16 : 0);\n  this.actionIntensity[2] += (this.action.backward ? 16 : 0);\n\n  if (!human) {\n    for (i = 0; i < (brain.nGameInput-4); i++) {\n\n      noStroke();\n      fill(r, g, b, brain.inputState[i]*32+8);\n      ellipse(toX((startX+i*radius)*this.dir), height*1/8+toP(radius), toP(radius*factor), toP(radius*factor));\n\n      for (j = 0; j < brain.nGameOutput; j++) {\n\n        if (this.actionIntensity[j] > 64) {\n          stroke(r, g, b, brain.inputState[i]*32);\n          line(toX((startX+i*radius)*this.dir), height*1/8+toP(radius), toX((startX2+ballFactor*j*radius)*this.dir), secondLayerY+(ballFactor+0)*toP(radius));\n        }\n      }\n\n    }\n  }\n\n  for (j = 0; j < brain.nGameOutput; j++) {\n\n      this.actionIntensity[j] -= 4;\n      this.actionIntensity[j] = Math.min(this.actionIntensity[j], 128);\n      this.actionIntensity[j] = Math.max(this.actionIntensity[j], 16);\n\n      noStroke();\n      fill(r, g, b, (this.actionIntensity[j]));\n      ellipse(toX((startX2+ballFactor*j*radius)*this.dir), secondLayerY+(ballFactor+0)*toP(radius), toP(radius*factor)*ballFactor, toP(radius*factor)*ballFactor);\n\n  }\n\n\n};\nAgent.prototype.update = function() {\n  \"use strict\";\n  this.v.add(p5.Vector.mult(gravity, timeStep));\n  if (this.loc.y <= ref_u + nudge*timeStep) {\n    this.v.y = this.desiredVelocity.y;\n  }\n  this.v.x = this.desiredVelocity.x*this.dir;\n  this.move();\n  if (this.loc.y <= ref_u) {\n    this.loc.y = ref_u;\n    this.v.y = 0;\n  }\n\n  // stay in their own half:\n  if (this.loc.x*this.dir <= (ref_wallwidth/2+this.r) ) {\n    this.v.x = 0;\n    this.loc.x = this.dir*(ref_wallwidth/2+this.r);\n  }\n  if (this.loc.x*this.dir >= (ref_w/2-this.r) ) {\n    this.v.x = 0;\n    this.loc.x = this.dir*(ref_w/2-this.r);\n  }\n};\nAgent.prototype.display = function() {\n  \"use strict\";\n  var x = this.loc.x;\n  var y = this.loc.y;\n  var r = this.r;\n  var angle = 60;\n  var eyeX = 0;\n  var eyeY = 0;\n\n  if (this.dir === 1) angle = 135;\n  noStroke();\n  fill(this.c);\n  //ellipse(toX(x), toY(y), toP(r)*2, toP(r)*2);\n  arc(toX(x), toY(y), toP(r)*2, toP(r)*2, Math.PI, 2*Math.PI);\n  /*\n  fill(255);\n  rect(toX(x-r), toY(y), 2*r*factor, r*factor);\n  */\n\n  // track ball with eyes (replace with observed info later):\n  var ballX = game.ball.loc.x-(x+(0.6)*r*fastCos(angle));\n  var ballY = game.ball.loc.y-(y+(0.6)*r*fastSin(angle));\n  if (this.emotion === \"sad\") {\n    ballX = -this.dir;\n    ballY = -3;\n  }\n  var dist = Math.sqrt(ballX*ballX+ballY*ballY);\n  eyeX = ballX/dist;\n  eyeY = ballY/dist;\n\n  fill(255);\n  ellipse(toX(x+(0.6)*r*fastCos(angle)), toY(y+(0.6)*r*fastSin(angle)), toP(r)*0.6, toP(r)*0.6);\n  fill(0);\n  ellipse(toX(x+(0.6)*r*fastCos(angle)+eyeX*0.15*r), toY(y+(0.6)*r*fastSin(angle)+eyeY*0.15*r), toP(r)*0.2, toP(r)*0.2);\n\n};\nAgent.prototype.drawScore = function() {\n  \"use strict\";\n  var r = red(this.c);\n  var g = green(this.c);\n  var b = blue(this.c);\n  var size = this.scoreSize;\n  var factor = 0.95;\n  this.scoreSize = baseScoreFontSize + (this.scoreSize-baseScoreFontSize) * factor;\n\n  if (this.score > 0) {\n    textFont(\"Courier New\");\n    textSize(size);\n    //stroke(255);\n    stroke(r, g, b, 128*(baseScoreFontSize/this.scoreSize));\n    fill(r, g, b, 64*(baseScoreFontSize/this.scoreSize));\n    textAlign(this.dir === -1? LEFT:RIGHT);\n    text(this.score, this.dir === -1? size*3/4 : width-size/4, size/2+height/3);\n  }\n\n};\n\nfunction Wall(x, y, w, h) {\n  \"use strict\";\n  this.x = x;\n  this.y = y;\n  this.w = w;\n  this.h = h;\n  this.c = color(0, 200, 50, 128);\n}\n\nWall.prototype.display = function() {\n  \"use strict\";\n  noStroke();\n  fill(255);\n  rect(toX(this.x-this.w/2), toY(this.y+this.h/2), toP(this.w), toP(this.h));\n  fill(this.c);\n  rect(toX(this.x-this.w/2), toY(this.y+this.h/2), toP(this.w), toP(this.h));\n};\n\nfunction initGame() {\n  game.ball = new Particle(createVector(0, ref_w/4));\n  game.ball.r = 0.5;\n\n  game.agent1 = game.agent1 || new Agent(-1, createVector(-ref_w/4, 1.5), color(240, 75, 0, 255));\n  game.agent2 = game.agent2 || new Agent(1, createVector(ref_w/4, 1.5), color(0, 150, 255, 255));\n\n  game.agent1.setOpponent(game.agent2); // point agent to the other agent as an opponent.\n  game.agent2.setOpponent(game.agent1);\n\n  human1 = false;\n  human2 = false;\n\n  delayScreen.init(initDelayFrames);\n}\n\nfunction setup() {\n  \"use strict\";\n\n  // deal with mobile device nuances\n  md = new MobileDetect(window.navigator.userAgent);\n  if (md.mobile()) {\n      mobileMode = true;\n      console.log('mobile: '+md.mobile());\n  } else {\n      theFrameRate /= 2;\n      console.log('not mobile');\n  }\n\n  myCanvas = createCanvas(windowWidth,windowHeight);\n  factor = windowWidth / ref_w;\n  ref_h = ref_w;\n  myCanvas.parent('p5Container');\n  frameRate(theFrameRate);\n\n  // create html elements\n  //http://otoro.net/slimevolley/\n\n  //intro.text = createA(\"http://blog.otoro.net/2015/03/28/neural-slime-volleyball/\", \"neural slime volleyball\", \"_blank\");\n  //intro.text.position(32+width/32, height/32);\n\n  gravity = createVector(0, theGravity);\n\n  // setup game objects\n  game.ground = new Wall(0, 0.75, ref_w, ref_u);\n  game.fence = new Wall(0, 0.75 + ref_wallheight/2, ref_wallwidth, (ref_wallheight-1.5));\n  game.fence.c = color(240, 210, 130, 255);\n  game.fenceStub = new Particle(createVector(0, ref_wallheight), createVector(0, 0), ref_wallwidth/2, color(240, 210, 130, 255));\n\n  initGame();\n\n  trainer = new Trainer(game.agent1.brain, initGene);\n  game.agent1.brain.populate(trainer.getChromosome()); // best one\n  game.agent2.brain.populate(trainer.getChromosome()); // best one\n}\n\n// updates game element according to physics\nfunction update(nStep) {\n  \"use strict\";\n\n  var result = 0;\n\n  for (var step = 0; step < nStep; step++) {\n\n    // ai here\n    // update internal states\n    game.agent1.getState();\n    game.agent2.getState();\n    // push states to brain\n    game.agent1.brain.setCurrentInputState(game.agent1, game.agent2);\n    game.agent2.brain.setCurrentInputState(game.agent2, game.agent1);\n    // make a decision\n    game.agent1.brain.forward();\n    game.agent2.brain.forward();\n    // convert brain's output signals into game actions\n    game.agent1.setBrainAction();\n    game.agent2.setBrainAction();\n\n    // get human keyboard control\n    if (!trainingMode) {\n      if (!trainingVersion) {\n        keyboardControl(); // may want to disable this for speed.\n        touchControl(); // mobile device\n      }\n      betweenGameControl();\n    }\n\n    // process actions\n    game.agent1.processAction();\n    game.agent2.processAction();\n    game.agent1.update();\n    game.agent2.update();\n\n    if (delayScreen.status() === true) {\n      game.ball.applyAcceleration(gravity);\n      game.ball.limitSpeed(0, maxBallSpeed);\n      game.ball.move();\n    }\n\n    if (game.ball.isColliding(game.agent1)) {\n      game.ball.bounce(game.agent1);\n    }\n    if (game.ball.isColliding(game.agent2)) {\n      game.ball.bounce(game.agent2);\n    }\n    if (game.ball.isColliding(game.fenceStub)) {\n      game.ball.bounce(game.fenceStub);\n    }\n\n    result = game.ball.checkEdges();\n    if (Math.abs(result) > 0) {\n      // make graphics for dead ball\n      if (!trainingMode) {\n        game.deadball = new Particle(game.ball.loc.copy());\n        game.deadball.r = 0.5;\n        game.deadball.life = initDelayFrames;\n      }\n      initGame();\n      if (!trainingMode) {\n        console.log('player '+(result > 0? '1' : '2')+' won.');\n        if (result > 0) {\n          game.agent1.score += 1;\n          game.agent1.scoreSize *= 4;\n          game.agent1.emotion = \"happy\";\n          game.agent2.emotion = \"sad\";\n        } else {\n          game.agent2.score += 1;\n          game.agent2.scoreSize *= 4;\n          game.agent2.emotion = \"happy\";\n          game.agent1.emotion = \"sad\";\n        }\n      }\n      return result;\n    }\n\n  }\n\n  return result; // 0 means tie, -1 means landed on left side, 1 means landed on right side.\n}\n\nfunction drawScenery() {\n  // draws the scenery\n  for (var i = 0; i < 24; i++) {\n    noStroke();\n    fill(50, 100, 240, 16*(24-i)/24);\n    rect(0, i*height/24/3, width, height/24/3);\n  }\n  fill(255, 240, 0, 64);\n  noStroke();\n  ellipse(toX(-ref_w/4), 1*height/2, 2*factor*2, 2*factor*2);\n  fill(50, 255, 50, 16);\n  ellipse(toX(ref_w/8), toY(-1.5), 12*factor*2, 20*factor*2);\n  fill(50, 255, 50, 16);\n  ellipse(toX(-ref_w/8), toY(-1.5), 8*factor*2, 12*factor*2);\n  fill(50, 255, 50, 16);\n  ellipse(toX(ref_w/3), toY(-1.5), 6*factor*2, 24*factor*2);\n}\n\nfunction keyboardControl() {\n  // player 1:\n  var a1_forward = 68; // 'd' key\n  var a1_backward = 65; // 'a' key\n  var a1_jump = 87; // 'w' key\n  // player 2:\n  var a2_forward = LEFT_ARROW;\n  var a2_backward = RIGHT_ARROW;\n  var a2_jump = UP_ARROW;\n\n  if (keyIsDown(a1_forward) || keyIsDown(a1_backward) || keyIsDown(a1_jump)) {\n    human1 = true;\n    humanHasControlled = true;\n  }\n  if (human1) {\n    game.agent1.setAction(keyIsDown(a1_forward), keyIsDown(a1_backward), keyIsDown(a1_jump));\n  }\n\n  if (keyIsDown(a2_forward) || keyIsDown(a2_backward) || keyIsDown(a2_jump)) {\n    human2 = true;\n    humanHasControlled = true;\n  }\n  if (human2) {\n    game.agent2.setAction(keyIsDown(a2_forward), keyIsDown(a2_backward), keyIsDown(a2_jump));\n  }\n\n}\n\nfunction touchControl() {\n  \"use strict\";\n  var paddingY = height/64;\n  var paddingX = width/64;\n  var dx = 0;\n  var dy = 0;\n  var x = 0;\n  var y = 0;\n  var agentX = toX(game.agent2.loc.x);\n  var agentY = toY(game.agent2.loc.y);\n  var jumpY = toY(ref_wallheight*2);\n  var gestureEvent = false;\n\n  if (touchIsDown) {\n    x = touchX;\n    y = touchY;\n    dx = touchX-ptouchX;\n    dy = touchY-ptouchY;\n    gestureEvent = true;\n  }\n\n  if (mouseIsPressed) {\n    x = mouseX;\n    y = mouseY;\n    dx = mouseX-pmouseX;\n    dy = mouseY-pmouseY;\n    gestureEvent = true;\n  }\n\n  if (gestureEvent) {\n    human2 = true;\n    humanHasControlled = true;\n    game.agent2.setAction((x - agentX) < -paddingX, (x - agentX) > paddingX, dy < -paddingY);\n  }\n\n}\n\n// between end of this match to the next match.  guy wins jumps, guy who loses regrets...\nfunction betweenGameControl() {\n  \"use strict\";\n  var agent = [game.agent1, game.agent2];\n  if (delayScreen.life > 0) {\n    for (var i = 0; i < 2; i++) {\n      if (agent[i].emotion === \"happy\") {\n        agent[i].action.jump = true;\n      } else {\n        agent[i].action.jump = false;\n      }\n    }\n  } else {\n    agent[0].emotion = \"happy\";\n    agent[1].emotion = \"happy\";\n  }\n}\n\nfunction getNNDebugString() {\n  \"use strict\";\n  var result = \"\";\n  result += \"agent1:\\n\";\n  result += \"input1: \"+JSON.stringify(game.agent1.brain.getInputStateString())+\"\\n\";\n  result += \"output1: \"+JSON.stringify(game.agent1.brain.getOutputStateString())+\"\\n\";\n  result += \"agent2:\\n\";\n  result += \"input2: \"+JSON.stringify(game.agent2.brain.getInputStateString())+\"\\n\";\n  result += \"output2: \"+JSON.stringify(game.agent2.brain.getOutputStateString())+\"\\n\";\n  return result;\n}\n\nfunction arrayToString(x, precision) {\n  \"use strict\";\n  precision = precision || 1000;\n  var result = \"[\";\n  for (var i = 0; i < x.length; i++) {\n    result += Math.round(precision*x[i])/precision;\n    if (i < x.length-1) {\n      result += \",\";\n    }\n  }\n  result += \"]\";\n  return result;\n}\n\n// cool p5.js functions to draw p-noise bouncy keyboard control graphics.\nvar pNoiseSeed = 0;\nfunction drawArrowKeyboard(x, y, s1, c, intensity, theColor) {\n  \"use strict\";\n\n  var rc = red(theColor);\n  var gc = green(theColor);\n  var bc = blue(theColor);\n\n  function nextNoise() {\n    var pFactor = 10;\n    var f = 5;\n    pNoiseSeed = pNoiseSeed || 0;\n    pNoiseSeed += 1;\n    return (noise(pNoiseSeed / pFactor)-0.5)*f;\n  }\n\n  function drawArrowKey(x, y, s, r) {\n\n\n    var f = 5;\n    //console.log(nextNoise());\n    stroke(rc, gc, bc, intensity);\n    noFill();\n    beginShape();\n    var x1offset = nextNoise();\n    var y1offset = nextNoise();\n    var x2offset = nextNoise();\n    var y2offset = nextNoise();\n    var x3offset = nextNoise();\n    var y3offset = nextNoise();\n    curveVertex(x-s+x1offset, y+s-r+y1offset);\n    curveVertex(x-s+x2offset, y-s+r+y2offset);\n    curveVertex(x-s+r+x3offset, y-s+y3offset);\n    curveVertex(x+s-r+nextNoise(), y-s+nextNoise());\n    curveVertex(x+s+nextNoise(), y-s+r+nextNoise());\n    curveVertex(x+s+nextNoise(), y+s-r+nextNoise());\n    curveVertex(x+s-r+nextNoise(), y+s+nextNoise());\n    curveVertex(x-s+r+nextNoise(), y+s+nextNoise());\n    curveVertex(x-s+x1offset, y+s-r+y1offset);\n    curveVertex(x-s+x2offset, y-s+r+y2offset);\n    curveVertex(x-s+r+x3offset, y-s+y3offset);\n    endShape();\n    noStroke();\n  }\n\n  var s2 = s1 * 0.8;\n  var r1 = s1 * 0.2;\n  var r2 = s2 * 0.2;\n  var fontSize = 32;\n\n  function drawFullKey(x, y, c) {\n    drawArrowKey(x, y, s1/2, r1);\n    drawArrowKey(x, y, s2/2, r2);\n\n    stroke(rc, gc, bc, intensity);\n    fill(rc, gc, bc, intensity);\n\n    text(c, x+nextNoise()/1-fontSize/2, y+nextNoise()/1+fontSize/4);\n  }\n\n  textFont(\"monospace\");\n  textSize(fontSize);\n  drawFullKey(x-s1, y, c[0]);\n  drawFullKey(x, y-s1, c[1]);\n  drawFullKey(x+s1, y, c[2]);\n\n}\n\n// n = 1, first agent, n = 2, second agent.\nfunction drawAgentKeyboard(x, y, s, n, intensity, theColor) {\n  var c = ['ａ', 'ｗ', 'ｄ'];\n  if (n == 2) c = ['◀', '▲', '▶'];\n  drawArrowKeyboard(x, y, s, c, intensity, theColor);\n}\n\nfunction draw() {\n  \"use strict\";\n  var result = 0;\n\n  background(255);\n\n  // draw box around frame\n\n  result = update(1);\n\n  if (result !== 0 && trainingVersion) { // someone has lost\n    var genStep = 50;\n    console.log('training generation #'+(generationCounter+genStep));\n    for (var i = 0; i < genStep; i++) {\n      trainer.train();\n    }\n    // print results\n    for (i = 0; i < 4; i++) {\n      console.log('#'+i+':'+Math.round(100*trainer.getChromosome(i).fitness)/100);\n    }\n    var N = trainer.trainer.population_size;\n    for (i = N-4; i < N; i++) {\n      console.log('#'+i+':'+Math.round(100*trainer.getChromosome(i).fitness)/100);\n    }\n    if (trainingVersion) {\n      $(\"#nn_gene\").text(JSON.stringify(trainer.getChromosome()));\n      console.log('--- start trained gene ---');\n      console.log(JSON.stringify(trainer.getChromosome()));\n      console.log('--- end of trained gene---');\n    }\n    generationCounter += genStep;\n    initGame();\n    game.agent1.brain.populate(trainer.getChromosome(0)); // best one\n    game.agent2.brain.populate(trainer.getChromosome(1)); // second best one\n  }\n\n  // draw the game objects\n  drawScenery();\n  game.agent1.display();\n  game.agent2.display();\n\n  if (!mobileMode && showArrowKeys & !humanHasControlled) {\n    var intensity = 64*Math.min(16*(delayScreen.life/initDelayFrames)*(initDelayFrames-delayScreen.life)/initDelayFrames, 64);\n    drawAgentKeyboard(width/4, toY(ref_wallheight*1), width/12, 1, intensity, game.agent1.c);\n    drawAgentKeyboard(3*width/4, toY(ref_wallheight*1), width/12, 2, intensity, game.agent2.c);\n  }\n  if (!humanHasControlled && handSymbolDisplayed ) {\n    moveHandSymbol(toX(game.agent2.loc.x), toY(game.agent2.loc.y)-height/2.5);\n  } else {\n    hideHandSymbol();\n  }\n\n  game.ball.c = color(255, 200, 20, 255*Math.max((initDelayFrames-delayScreen.life)/initDelayFrames, 0));\n  game.ball.display();\n  game.ground.display();\n  game.fence.display();\n  game.fenceStub.display();\n\n  // prints agent states (used for nn input)\n  if (trainingVersion) {\n    game.agent1.printState();\n    game.agent2.printState();\n  }\n\n  game.agent1.drawState(human1);\n  game.agent2.drawState(human2);\n\n  game.agent1.drawScore();\n  game.agent2.drawScore();\n\n  // draw dead ball\n  if (game.deadball) {\n    game.deadball.life -= 1;\n    game.deadball.c = color(250, 0, 0, 128*(game.deadball.life/initDelayFrames));\n    game.deadball.display();\n    if (game.deadball.life <= 0) {\n      game.deadball = null;\n    }\n  }\n\n  //$(\"#nn_weights\").text(getNNDebugString());\n\n}\n\nfunction windowResized() {\n  \"use strict\";\n  resizeCanvas(windowWidth, windowHeight);\n  myCanvas.size(windowWidth, windowHeight);\n  factor = windowWidth / ref_w;\n}\n\n// When the mouse is released \nvar deviceReleased = function() {\n  \"use strict\";\n};\n\n// When the mouse is pressed we. . .\nvar devicePressed = function(x, y) {\n  \"use strict\";\n};\n\nvar deviceDragged = function(x, y) {\n  \"use strict\";\n};\n\nvar mousePressed = function() {\n  \"use strict\";\n  devicePressed(mouseX, mouseY);\n  return false;\n};\n\nvar touchStarted = function() {\n  \"use strict\";\n  devicePressed(touchX, touchY);\n  return false;\n};\n\n// interaction with touchpad and mosue:\n\nvar mouseDragged = function() {\n  \"use strict\";\n  deviceDragged(mouseX, mouseY);\n  return false;\n};\n\nvar touchMoved = function() {\n  \"use strict\";\n  return false;\n};\n\nvar mouseReleased = function() {\n  \"use strict\";\n  return false;\n};\n\nvar touchEnded = function() {\n  \"use strict\";\n  return false;\n};\n\n\n\n"
  },
  {
    "path": "useful.js",
    "content": "// useful simple math functions\n\nsign = Math.sign || function sign(x) {\n  x = +x; // convert to a number\n  if (x === 0 || isNaN(x)) {\n      return x;\n  }\n  return x > 0 ? 1 : -1;\n};\n\nfunction rectify(x, minValue, maxValue) {\n  if (x > maxValue) return maxValue;\n  if (x < minValue) return minValue;\n  return x;\n}\n\nfunction getWidth() {\n  return $(window).width()-20*0;\n}\n\nfunction getHeight() {\n  return $(window).height()-20*0;\n}\n\n// useful helper functions\nvar getRandom = function (min, max) {\n  return Math.random() * (max - min) + min;\n};\n\nvar getRandomInt = function (min, max) {\n  return Math.floor(Math.random() * (max - min)) + min;\n};\n\nvar getRandomColor = function(alpha) {\n  var c = color(getRandomInt(127, 255), getRandomInt(127, 255), getRandomInt(127, 255), alpha? alpha : 0);\n  return c;\n};\n\nvar cosTable = new Array(360);\nvar sinTable = new Array(360);\nvar PI = Math.PI;\n\n// pre compute sine and cosine values to the nearest degree\nfor (i = 0; i < 360; i++) {\n  cosTable[i] = Math.cos((i / 360) * 2 * PI);\n  sinTable[i] = Math.sin((i / 360) * 2 * PI);\n}\n\nvar fastSin = function (xDeg) {\n  var deg = Math.round(xDeg);\n  if (deg >= 0) {\n    return sinTable[(deg % 360)];\n  }\n  return -sinTable[((-deg) % 360)];\n};\n\nvar fastCos = function (xDeg) {\n  var deg = Math.round(Math.abs(xDeg));\n  return cosTable[deg % 360];\n};\n"
  }
]