{
  "version": 3,
  "file": "c:/git-dev/build-an-atom/build/build-an-atom.min.js",
  "sources": [
    "../node_modules/grunt-requirejs/node_modules/almond/almond.js",
    "../js/common/AtomIdentifier.js",
    "../../phet-core/js/callSuper.js",
    "../../phet-core/js/phetAllocation.js",
    "../../dot/js/dot.js",
    "../../dot/js/Dimension2.js",
    "../../phet-core/js/extend.js",
    "../../phet-core/js/inherit.js",
    "../../axon/js/axon.js",
    "../../axon/js/log.js",
    "../../axon/js/Property.js",
    "../../axon/js/DerivedProperty.js",
    "../../axon/js/PropertySet.js",
    "../js/common/model/NumberAtom.js",
    "../../phet-core/js/Poolable.js",
    "../../dot/js/Util.js",
    "../../dot/js/Vector2.js",
    "../js/common/SharedConstants.js",
    "../js/common/model/Particle.js",
    "../../axon/js/ObservableArray.js",
    "../js/common/Utils.js",
    "../js/common/model/ParticleAtom.js",
    "../../assert/js/assert.js",
    "../../kite/js/kite.js",
    "../../dot/js/Bounds2.js",
    "../../dot/js/Ray2.js",
    "../../dot/js/Vector4.js",
    "../../dot/js/Vector3.js",
    "../../dot/js/Matrix4.js",
    "../../dot/js/Matrix3.js",
    "../../dot/js/Transform3.js",
    "../../kite/js/segments/Segment.js",
    "../../kite/js/segments/Line.js",
    "../../kite/js/segments/Arc.js",
    "../../kite/js/util/Subpath.js",
    "../../kite/js/../parser/svgPath.js",
    "../../kite/js/util/LineStyles.js",
    "../../kite/js/segments/Quadratic.js",
    "../../kite/js/segments/Cubic.js",
    "../../kite/js/segments/EllipticalArc.js",
    "../../kite/js/Shape.js",
    "../../phetcommon/js/model/Bucket.js",
    "../../phetcommon/js/model/SphereBucket.js",
    "../js/common/model/BuildAnAtomModel.js",
    "../../scenery/js/scenery.js",
    "../../scenery/js/util/FixedNodeEvents.js",
    "../../scenery/js/layers/LayerStrategy.js",
    "../../scenery/js/nodes/Node.js",
    "../../scenery/js/util/Trail.js",
    "../../scenery/js/input/DownUpListener.js",
    "../../scenery/js/input/ButtonListener.js",
    "../../scenery/js/layers/LayerType.js",
    "../../scenery/js/layers/Layer.js",
    "../../scenery/js/util/CanvasContextWrapper.js",
    "../../scenery/js/util/TrailPointer.js",
    "../../scenery/js/util/Util.js",
    "../../scenery/js/layers/CanvasLayer.js",
    "../../scenery/js/layers/DOMLayer.js",
    "../../scenery/js/layers/SVGLayer.js",
    "../../scenery/js/layers/Renderer.js",
    "../../scenery/js/nodes/Fillable.js",
    "../../scenery/js/nodes/Strokable.js",
    "../../scenery/js/nodes/Path.js",
    "../../sun/js/ExpandCollapseButton.js",
    "../../scenery/js/nodes/Rectangle.js",
    "../../phet-core/js/escapeHTML.js",
    "../../scenery/js/util/Font.js",
    "../../scenery/js/nodes/Text.js",
    "../../sun/js/AccordionBox.js",
    "../../scenery/js/nodes/Circle.js",
    "../../sun/js/RadioButton.js",
    "../../sun/js/AquaRadioButton.js",
    "../../scenery-phet/js/PhetFont.js",
    "../../scenery/js/util/Color.js",
    "../../scenery/js/util/Gradient.js",
    "../../scenery/js/util/RadialGradient.js",
    "../../scenery/js/input/SimpleDragHandler.js",
    "../js/common/view/ElectronCloudView.js",
    "../js/common/view/ElectronShellView.js",
    "../js/common/view/AtomNode.js",
    "../js/buildanatom/view/BucketDragHandler.js",
    "../../scenery/js/util/LinearGradient.js",
    "../../scenery-phet/js/bucket/BucketFront.js",
    "../../scenery-phet/js/bucket/BucketHole.js",
    "../../phetcommon/js/view/ModelViewTransform2.js",
    "../../sun/js/Panel.js",
    "../js/common/view/ParticleNode.js",
    "../js/common/view/ParticleCountDisplay.js",
    "../../scenery/js/nodes/Image.js",
    "../js/common/view/ParticleView.js",
    "../js/common/view/PeriodicTableCell.js",
    "../js/common/view/PeriodicTableNode.js",
    "../js/buildanatom/view/PeriodicTableAndSymbol.js",
    "../js/imageLoader.js",
    "../../sun/js/PushButton.js",
    "../js/common/view/ResetAllButton.js",
    "../../joist/js/ScreenView.js",
    "../../scenery/js/nodes/VBox.js",
    "../../scenery/js/nodes/DOM.js",
    "../../scenery/js/nodes/HBox.js",
    "../../phet-core/js/collect.js",
    "../../scenery/js/util/AccessibilityPeer.js",
    "../../scenery/js/util/LiveRegion.js",
    "../../scenery/js/util/Instance.js",
    "../../scenery/js/util/RenderInterval.js",
    "../../scenery/js/input/Pointer.js",
    "../../scenery/js/input/Mouse.js",
    "../../scenery/js/input/Touch.js",
    "../../scenery/js/input/Pen.js",
    "../../scenery/js/input/Key.js",
    "../../scenery/js/input/Event.js",
    "../../scenery/js/input/Input.js",
    "../../scenery/js/layers/LayerBoundary.js",
    "../../scenery/js/layers/LayerBuilder.js",
    "../../scenery/js/Scene.js",
    "../../sun/js/FontAwesomeNode.js",
    "../../sun/js/CheckBox.js",
    "../../sun/js/VerticalCheckBoxGroup.js",
    "../js/common/view/AtomView.js",
    "../../kite/js/shape.js",
    "../js/buildanatom/view/ChargeComparisonDisplay.js",
    "../../scenery-phet/js/ArrowShape.js",
    "../../scenery-phet/js/ArrowNode.js",
    "../js/common/view/ChargeMeter.js",
    "../js/buildanatom/view/MassNumberDisplay.js",
    "../js/buildanatom/view/BuildAnAtomView.js",
    "../js/game/model/BAAGameProblem.js",
    "../../scenery-phet/js/MultiLineText.js",
    "../../scenery-phet/js/ArrowButton.js",
    "../js/game/view/NumberEntryNode.js",
    "../js/game/view/ParticleCountsNode.js",
    "../../sun/js/RectangleButton.js",
    "../../sun/js/TextButton.js",
    "../../scenery-phet/js/FaceNode.js",
    "../js/game/view/ProblemView.js",
    "../js/game/view/CountsToChargeProblemView.js",
    "../js/game/model/CountsToChargeProblem.js",
    "../js/game/view/InteractiveSymbolNode.js",
    "../js/game/view/CountsToSymbolProblemView.js",
    "../js/game/model/CountsToSymbolProblem.js",
    "../js/game/model/ToElementProblem.js",
    "../js/game/view/ToElementProblemView.js",
    "../js/game/view/CountsToElementProblemView.js",
    "../js/game/model/CountsToElementProblem.js",
    "../js/game/view/CountsToMassNumberProblemView.js",
    "../js/game/model/CountsToMassNumberProblem.js",
    "../js/game/model/AtomValuePool.js",
    "../js/game/view/NonInteractiveSchematicAtomNode.js",
    "../js/game/view/SchematicToChargeProblemView.js",
    "../js/game/model/SchematicToChargeProblem.js",
    "../js/game/view/SchematicToElementProblemView.js",
    "../js/game/model/SchematicToElementProblem.js",
    "../js/game/view/SchematicToMassNumberProblemView.js",
    "../js/game/model/SchematicToMassNumberProblem.js",
    "../js/game/view/SchematicToSymbolProblemView.js",
    "../js/game/model/SchematicToSymbolProblem.js",
    "../js/game/view/InteractiveParticleCountsNode.js",
    "../js/game/view/SymbolToCountsProblemView.js",
    "../js/game/model/SymbolToCountsProblem.js",
    "../js/common/view/InteractiveSchematicAtom.js",
    "../js/game/view/SymbolToSchematicProblemView.js",
    "../js/game/model/SymbolToSchematicProblem.js",
    "../js/game/model/ProblemSetFactory.js",
    "../js/game/model/BAAGameModel.js",
    "../js/game/view/GameScoreboardNode.js",
    "../js/game/view/HalfStar.js",
    "../js/game/view/Star.js",
    "../js/game/view/GameProgressIndicator.js",
    "../js/game/view/GameStartButton.js",
    "../../sun/js/ToggleNode.js",
    "../../sun/js/ToggleButton.js",
    "../../scenery-phet/js/SoundToggleButton.js",
    "../js/game/view/TimerToggleButton.js",
    "../js/game/view/StartSubGameNode.js",
    "../../scenery/js/nodes/Line.js",
    "../js/game/view/LevelCompletedNode.js",
    "../js/game/view/BAAGameView.js",
    "../js/symbol/view/SymbolNode.js",
    "../js/symbol/view/SymbolView.js",
    "../../scenery-phet/js/HomeButton.js",
    "../../scenery/js/nodes/HTMLText.js",
    "../../joist/js/AboutDialog.js",
    "../../scenery/js/nodes/Plane.js",
    "../../joist/js/PhetMenu.js",
    "../../phet-core/js/platform.js",
    "../../joist/js/joistImageLoader.js",
    "../../joist/js/PhetButton.js",
    "../../joist/js/Highlight.js",
    "../../joist/js/NavigationBar.js",
    "../../joist/js/Frame.js",
    "../../joist/js/FullScreenButton.js",
    "../../joist/js/HomeScreen.js",
    "../js/version.js",
    "../../joist/js/share/Pointer.js",
    "../../joist/js/share/Pointers.js",
    "../../joist/js/share/LogPointers.js",
    "../../joist/js/Sim.js",
    "../../joist/js/SimLauncher.js",
    "../js/build-an-atom-main.js",
    "../js/build-an-atom-config.js"
  ],
  "names": [],
  "mappings": "AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AClQA,ADmQA;AClQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AChNA,ADiNA;AChNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACTA,ADUA;ACTA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AClCA,ADmCA;AClCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AClBA,ADmBA;AClBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AClBA,ADmBA;AClBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACZA,ADaA;ACZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACZA,ADaA;ACZA;AACA;AACA;AACA;ACJA,ADKA;ACJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AClGA,ADmGA;AClGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC/GA,ADgHA;AC/GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC9DA,AD+DA;AC9DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACxIA,ADyIA;ACxIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACzCA,AD0CA;ACzCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AClCA,ADmCA;AClCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC5IA,AD6IA;AC5IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACjNA,ADkNA;ACjNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACpBA,ADqBA;ACpBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC9CA,AD+CA;AC9CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC5HA,AD6HA;AC5HA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AChBA,ADiBA;AChBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC/OA,ADgPA;AC/OA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACxBA,ADyBA;ACxBA;AACA;AACA;AACA;AACA;AACA;ACNA,ADOA;ACNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACvQA,ADwQA;ACvQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACvBA,ADwBA;ACvBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC9LA,AD+LA;AC9LA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACtLA,ADuLA;ACtLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACpNA,ADqNA;ACpNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AClcA,ADmcA;AClcA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACnLA,ADoLA;ACnLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC9BA,AD+BA;AC9BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AChGA,ADiGA;AChGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACrOA,ADsOA;ACrOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACxOA,ADyOA;ACxOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACtqFA,ADuqFA;ACtqFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACpCA,ADqCA;ACpCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACvKA,ADwKA;ACvKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC/MA,ADgNA;AC/MA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACvPA,ADwPA;ACvPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACzeA,AD0eA;ACzeA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC3BA,AD4BA;AC3BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACpLA,ADqLA;ACpLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACrNA,ADsNA;ACrNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACvCA,ADwCA;ACvCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC9CA,AD+CA;AC9CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACrEA,ADsEA;ACrEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AChkDA,ADikDA;AChkDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC9ZA,AD+ZA;AC9ZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACpEA,ADqEA;ACpEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACnEA,ADoEA;ACnEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC/BA,ADgCA;AC/BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC1HA,AD2HA;AC1HA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AClGA,ADmGA;AClGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACjMA,ADkMA;ACjMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AChSA,ADiSA;AChSA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACtTA,ADuTA;ACtTA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACnLA,ADoLA;ACnLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC7XA,AD8XA;AC7XA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AChCA,ADiCA;AChCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC3HA,AD4HA;AC3HA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACpPA,ADqPA;ACpPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACtIA,ADuIA;ACtIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AClDA,ADmDA;AClDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACxKA,ADyKA;ACxKA;AACA;AACA;AACA;AACA;ACLA,ADMA;ACLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACnOA,ADoOA;ACnOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACzYA,AD0YA;ACzYA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACxGA,ADyGA;ACxGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACvDA,ADwDA;ACvDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC3BA,AD4BA;AC3BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACxCA,ADyCA;ACxCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACdA,ADeA;ACdA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC9cA,AD+cA;AC9cA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC1CA,AD2CA;AC1CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACzEA,AD0EA;ACzEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACpHA,ADqHA;ACpHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC5DA,AD6DA;AC5DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AClCA,ADmCA;AClCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC/IA,ADgJA;AC/IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC/BA,ADgCA;AC/BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC/CA,ADgDA;AC/CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC9BA,AD+BA;AC9BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACxBA,ADyBA;ACxBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC1GA,AD2GA;AC1GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACzCA,AD0CA;ACzCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACzBA,AD0BA;ACzBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACtFA,ADuFA;ACtFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACxIA,ADyIA;ACxIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACtDA,ADuDA;ACtDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC9CA,AD+CA;AC9CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACzIA,AD0IA;ACzIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACzCA,AD0CA;ACzCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACnBA,ADoBA;ACnBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACvFA,ADwFA;ACvFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACtBA,ADuBA;ACtBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AClCA,ADmCA;AClCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AClDA,ADmDA;AClDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AClIA,ADmIA;AClIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AClDA,ADmDA;AClDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACTA,ADUA;ACTA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC1EA,AD2EA;AC1EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC7BA,AD8BA;AC7BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACzPA,AD0PA;ACzPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC/CA,ADgDA;AC/CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACrBA,ADsBA;ACrBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC3DA,AD4DA;AC3DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC7BA,AD8BA;AC7BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC7BA,AD8BA;AC7BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACfA,ADgBA;ACfA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC1BA,AD2BA;AC1BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACzjBA,AD0jBA;ACzjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC3CA,AD4CA;AC3CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC/GA,ADgHA;AC/GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACtiCA,ADuiCA;ACtiCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACpCA,ADqCA;ACpCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC/GA,ADgHA;AC/GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACnDA,ADoDA;ACnDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACjMA,ADkMA;ACjMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACzeA,AD0eA;ACzeA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC7FA,AD8FA;AC7FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACrDA,ADsDA;ACrDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACpBA,ADqBA;ACpBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACjIA,ADkIA;ACjIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC7CA,AD8CA;AC7CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACtDA,ADuDA;ACtDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACzCA,AD0CA;ACzCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC7BA,AD8BA;AC7BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AChHA,ADiHA;AChHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACzEA,AD0EA;ACzEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACvCA,ADwCA;ACvCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACrCA,ADsCA;ACrCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AClBA,ADmBA;AClBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC5DA,AD6DA;AC5DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACjIA,ADkIA;ACjIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACpDA,ADqDA;ACpDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACfA,ADgBA;ACfA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AClHA,ADmHA;AClHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC5CA,AD6CA;AC5CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AClBA,ADmBA;AClBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACzBA,AD0BA;ACzBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC7EA,AD8EA;AC7EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACjBA,ADkBA;ACjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACfA,ADgBA;ACfA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AChDA,ADiDA;AChDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACfA,ADgBA;ACfA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACz8BA,AD08BA;ACz8BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC9CA,AD+CA;AC9CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACzDA,AD0DA;ACzDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACfA,ADgBA;ACfA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACrBA,ADsBA;ACrBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACfA,ADgBA;ACfA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACrDA,ADsDA;ACrDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACfA,ADgBA;ACfA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACpDA,ADqDA;ACpDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AClBA,ADmBA;AClBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACzCA,AD0CA;ACzCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AClCA,ADmCA;AClCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACfA,ADgBA;ACfA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC3EA,AD4EA;AC3EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACvCA,ADwCA;ACvCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACvBA,ADwBA;ACvBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC/IA,ADgJA;AC/IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC/FA,ADgGA;AC/FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AChFA,ADiFA;AChFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACnBA,ADoBA;ACnBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACnBA,ADoBA;ACnBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACtEA,ADuEA;ACtEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AChEA,ADiEA;AChEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACnBA,ADoBA;ACnBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC3DA,AD4DA;AC3DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACdA,ADeA;ACdA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACtCA,ADuCA;ACtCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACpEA,ADqEA;ACpEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC7HA,AD8HA;AC7HA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACnFA,ADoFA;ACnFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC1CA,AD2CA;AC1CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC3FA,AD4FA;AC3FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AChCA,ADiCA;AChCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AClBA,ADmBA;AClBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACZA,ADaA;ACZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACpFA,ADqFA;ACpFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACXA,ADYA;ACXA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AChLA,ADiLA;AChLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC1BA,AD2BA;AC1BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACTA,ADUA;ACTA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC3GA,AD4GA;AC3GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACzCA,AD0CA;ACzCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC5LA,AD6LA;AC5LA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACvCA,ADwCA;ACvCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACxCA,ADyCA;ACxCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC5JA,AD6JA;AC5JA;AACA;AACA;AACA;AACA;ACLA,ADMA;ACLA;AACA;AACA;AACA;AACA;ACLA,ADMA;ACLA;AACA;AACA;AACA;ACJA,ADKA;ACJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACpEA,ADqEA;ACpEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACxUA,ADyUA;ACxUA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC1DA,AD2DA;AC1DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC3DA,AD4DA;AC3DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA",
  "sourcesContent": [
    "\nvar requirejs, require, define;\n(function (undef) {\n  var main, req, makeMap, handlers, defined = {}, waiting = {}, config = {}, defining = {}, hasOwn = Object.prototype.hasOwnProperty, aps = [].slice;\n  function hasProp(obj, prop) {\n    return hasOwn.call(obj, prop);\n  }\n  function normalize(name, baseName) {\n    var nameParts, nameSegment, mapValue, foundMap, foundI, foundStarMap, starI, i, j, part, baseParts = baseName && baseName.split('/'), map = config.map, starMap = map && map['*'] || {};\n    if (name && name.charAt(0) === '.') {\n      if (baseName) {\n        baseParts = baseParts.slice(0, baseParts.length - 1);\n        name = baseParts.concat(name.split('/'));\n        for (i = 0; i < name.length; i += 1) {\n          part = name[i];\n          if (part === '.') {\n            name.splice(i, 1);\n            i -= 1;\n          } else if (part === '..') {\n            if (i === 1 && (name[2] === '..' || name[0] === '..')) {\n              break;\n            } else if (i > 0) {\n              name.splice(i - 1, 2);\n              i -= 2;\n            }\n          }\n        }\n        name = name.join('/');\n      } else if (name.indexOf('./') === 0) {\n        name = name.substring(2);\n      }\n    }\n    if ((baseParts || starMap) && map) {\n      nameParts = name.split('/');\n      for (i = nameParts.length; i > 0; i -= 1) {\n        nameSegment = nameParts.slice(0, i).join('/');\n        if (baseParts) {\n          for (j = baseParts.length; j > 0; j -= 1) {\n            mapValue = map[baseParts.slice(0, j).join('/')];\n            if (mapValue) {\n              mapValue = mapValue[nameSegment];\n              if (mapValue) {\n                foundMap = mapValue;\n                foundI = i;\n                break;\n              }\n            }\n          }\n        }\n        if (foundMap) {\n          break;\n        }\n        if (!foundStarMap && starMap && starMap[nameSegment]) {\n          foundStarMap = starMap[nameSegment];\n          starI = i;\n        }\n      }\n      if (!foundMap && foundStarMap) {\n        foundMap = foundStarMap;\n        foundI = starI;\n      }\n      if (foundMap) {\n        nameParts.splice(0, foundI, foundMap);\n        name = nameParts.join('/');\n      }\n    }\n    return name;\n  }\n  function makeRequire(relName, forceSync) {\n    return function () {\n      return req.apply(undef, aps.call(arguments, 0).concat([\n        relName,\n        forceSync\n      ]));\n    };\n  }\n  function makeNormalize(relName) {\n    return function (name) {\n      return normalize(name, relName);\n    };\n  }\n  function makeLoad(depName) {\n    return function (value) {\n      defined[depName] = value;\n    };\n  }\n  function callDep(name) {\n    if (hasProp(waiting, name)) {\n      var args = waiting[name];\n      delete waiting[name];\n      defining[name] = true;\n      main.apply(undef, args);\n    }\n    if (!hasProp(defined, name) && !hasProp(defining, name)) {\n      throw new Error('No ' + name);\n    }\n    return defined[name];\n  }\n  function splitPrefix(name) {\n    var prefix, index = name ? name.indexOf('!') : -1;\n    if (index > -1) {\n      prefix = name.substring(0, index);\n      name = name.substring(index + 1, name.length);\n    }\n    return [\n      prefix,\n      name\n    ];\n  }\n  makeMap = function (name, relName) {\n    var plugin, parts = splitPrefix(name), prefix = parts[0];\n    name = parts[1];\n    if (prefix) {\n      prefix = normalize(prefix, relName);\n      plugin = callDep(prefix);\n    }\n    if (prefix) {\n      if (plugin && plugin.normalize) {\n        name = plugin.normalize(name, makeNormalize(relName));\n      } else {\n        name = normalize(name, relName);\n      }\n    } else {\n      name = normalize(name, relName);\n      parts = splitPrefix(name);\n      prefix = parts[0];\n      name = parts[1];\n      if (prefix) {\n        plugin = callDep(prefix);\n      }\n    }\n    return {\n      f: prefix ? prefix + '!' + name : name,\n      n: name,\n      pr: prefix,\n      p: plugin\n    };\n  };\n  function makeConfig(name) {\n    return function () {\n      return config && config.config && config.config[name] || {};\n    };\n  }\n  handlers = {\n    require: function (name) {\n      return makeRequire(name);\n    },\n    exports: function (name) {\n      var e = defined[name];\n      if (typeof e !== 'undefined') {\n        return e;\n      } else {\n        return defined[name] = {};\n      }\n    },\n    module: function (name) {\n      return {\n        id: name,\n        uri: '',\n        exports: defined[name],\n        config: makeConfig(name)\n      };\n    }\n  };\n  main = function (name, deps, callback, relName) {\n    var cjsModule, depName, ret, map, i, args = [], usingExports;\n    relName = relName || name;\n    if (typeof callback === 'function') {\n      deps = !deps.length && callback.length ? [\n        'require',\n        'exports',\n        'module'\n      ] : deps;\n      for (i = 0; i < deps.length; i += 1) {\n        map = makeMap(deps[i], relName);\n        depName = map.f;\n        if (depName === 'require') {\n          args[i] = handlers.require(name);\n        } else if (depName === 'exports') {\n          args[i] = handlers.exports(name);\n          usingExports = true;\n        } else if (depName === 'module') {\n          cjsModule = args[i] = handlers.module(name);\n        } else if (hasProp(defined, depName) || hasProp(waiting, depName) || hasProp(defining, depName)) {\n          args[i] = callDep(depName);\n        } else if (map.p) {\n          map.p.load(map.n, makeRequire(relName, true), makeLoad(depName), {});\n          args[i] = defined[depName];\n        } else {\n          throw new Error(name + ' missing ' + depName);\n        }\n      }\n      ret = callback.apply(defined[name], args);\n      if (name) {\n        if (cjsModule && cjsModule.exports !== undef && cjsModule.exports !== defined[name]) {\n          defined[name] = cjsModule.exports;\n        } else if (ret !== undef || !usingExports) {\n          defined[name] = ret;\n        }\n      }\n    } else if (name) {\n      defined[name] = callback;\n    }\n  };\n  requirejs = require = req = function (deps, callback, relName, forceSync, alt) {\n    if (typeof deps === 'string') {\n      if (handlers[deps]) {\n        return handlers[deps](callback);\n      }\n      return callDep(makeMap(deps, callback).f);\n    } else if (!deps.splice) {\n      config = deps;\n      if (callback.splice) {\n        deps = callback;\n        callback = relName;\n        relName = null;\n      } else {\n        deps = undef;\n      }\n    }\n    callback = callback || function () {\n    };\n    if (typeof relName === 'function') {\n      relName = forceSync;\n      forceSync = alt;\n    }\n    if (forceSync) {\n      main(undef, deps, callback, relName);\n    } else {\n      setTimeout(function () {\n        main(undef, deps, callback, relName);\n      }, 4);\n    }\n    return req;\n  };\n  req.config = function (cfg) {\n    config = cfg;\n    if (config.deps) {\n      req(config.deps, config.callback);\n    }\n    return req;\n  };\n  requirejs._defined = defined;\n  define = function (name, deps, callback) {\n    if (!deps.splice) {\n      callback = deps;\n      deps = [];\n    }\n    if (!hasProp(defined, name) && !hasProp(waiting, name)) {\n      waiting[name] = [\n        name,\n        deps,\n        callback\n      ];\n    }\n  };\n  define.amd = { jQuery: true };\n}());\ndefine(\"almond\", function(){});\n",
    "\ndefine('common/AtomIdentifier',[], function () {\n  'use strict';\n  var AtomIdentifier = {};\n  AtomIdentifier.getSymbol = function (numProtons) {\n    return _symbolTable[numProtons];\n  };\n  AtomIdentifier.getName = function (numProtons) {\n    return _nameTable[numProtons];\n  };\n  AtomIdentifier.isStable = function (numProtons, numNeutrons) {\n    var tableEntry = _stableElementTable[numProtons];\n    if (typeof tableEntry === 'undefined') {\n      return false;\n    }\n    return $.inArray(numNeutrons, tableEntry) > -1;\n  };\n  AtomIdentifier.getNumNeutronsInMostCommonIsotope = function (atomicNumber) {\n    return _numNeutronsInMostStableIsotope[atomicNumber];\n  };\n  var _nameTable = [\n      '',\n      'Hydrogen',\n      'Helium',\n      'Lithium',\n      'Beryllium',\n      'Boron',\n      'Carbon',\n      'Nitrogen',\n      'Oxygen',\n      'Fluorine',\n      'Neon',\n      'Sodium',\n      'Magnesium',\n      'Aluminium',\n      'Silicon',\n      'Phosphorus',\n      'Sulfur',\n      'Chlorine',\n      'Argon'\n    ];\n  var _symbolTable = [\n      '-',\n      'H',\n      'He',\n      'Li',\n      'Be',\n      'B',\n      'C',\n      'N',\n      'O',\n      'F',\n      'Ne',\n      'Na',\n      'Mg',\n      'Al',\n      'Si',\n      'P',\n      'S',\n      'Cl',\n      'Ar',\n      'K',\n      'Ca',\n      'Sc',\n      'Ti',\n      'V',\n      'Cr',\n      'Mn',\n      'Fe',\n      'Co',\n      'Ni',\n      'Cu',\n      'Zn',\n      'Ga',\n      'Ge',\n      'As',\n      'Se',\n      'Br',\n      'Kr',\n      'Rb',\n      'Sr',\n      'Y',\n      'Zr',\n      'Nb',\n      'Mo',\n      'Tc',\n      'Ru',\n      'Rh',\n      'Pd',\n      'Ag',\n      'Cd',\n      'In',\n      'Sn',\n      'Sb',\n      'Te',\n      'I',\n      'Xe',\n      'Cs',\n      'Ba',\n      'La',\n      'Ce',\n      'Pr',\n      'Nd',\n      'Pm',\n      'Sm',\n      'Eu',\n      'Gd',\n      'Tb',\n      'Dy',\n      'Ho',\n      'Er',\n      'Tm',\n      'Yb',\n      'Lu',\n      'Hf',\n      'Ta',\n      'W',\n      'Re',\n      'Os',\n      'Ir',\n      'Pt',\n      'Au',\n      'Hg',\n      'Tl',\n      'Pb',\n      'Bi',\n      'Po',\n      'At',\n      'Rn',\n      'Fr',\n      'Ra',\n      'Ac',\n      'Th',\n      'Pa',\n      'U',\n      'Np',\n      'Pu',\n      'Am',\n      'Cm',\n      'Bk',\n      'Cf',\n      'Es',\n      'Fm',\n      'Md',\n      'No',\n      'Lr',\n      'Rf',\n      'Db',\n      'Sg',\n      'Bh',\n      'Hs',\n      'Mt',\n      'Ds',\n      'Rg',\n      'Cn'\n    ];\n  var _stableElementTable = [\n      [],\n      [\n        0,\n        1\n      ],\n      [\n        1,\n        2\n      ],\n      [\n        3,\n        4\n      ],\n      [5],\n      [\n        5,\n        6\n      ],\n      [\n        6,\n        7\n      ],\n      [\n        7,\n        8\n      ],\n      [\n        8,\n        9,\n        10\n      ],\n      [10],\n      [\n        10,\n        11,\n        12\n      ]\n    ];\n  var _numNeutronsInMostStableIsotope = [\n      0,\n      0,\n      2,\n      4,\n      5,\n      6,\n      6,\n      8,\n      8,\n      10,\n      10\n    ];\n  return AtomIdentifier;\n});",
    "\ndefine('PHET_CORE/callSuper',['require'],function (require) {\n  'use strict';\n  function callSuper(supertype, name, context) {\n    (function () {\n      var fn = supertype.prototype[name];\n      Function.call.apply(fn, arguments);\n    }(context));\n  }\n  return callSuper;\n});",
    "\ndefine('PHET_CORE/phetAllocation',['require'],function (require) {\n  'use strict';\n  return function phetAllocation(name) {\n    if (window.alloc) {\n      var stack;\n      try {\n        throw new Error();\n      } catch (e) {\n        stack = e.stack;\n      }\n      if (!window.alloc[name]) {\n        window.alloc[name] = {\n          count: 0,\n          stacks: {}\n        };\n      }\n      var log = window.alloc[name];\n      log.count++;\n      if (!log.stacks[stack]) {\n        log.stacks[stack] = 1;\n      } else {\n        log.stacks[stack] += 1;\n      }\n      log.report = function () {\n        var stacks = Object.keys(log.stacks);\n        stacks = _.sortBy(stacks, function (key) {\n          return log.stacks[key];\n        });\n        _.each(stacks, function (stack) {\n          console.log(log.stacks[stack] + ': ' + stack);\n        });\n      };\n    }\n  };\n});",
    "\ndefine('DOT/dot',['require','PHET_CORE/phetAllocation'],function (require) {\n  'use strict';\n  window.phetAllocation = require('PHET_CORE/phetAllocation');\n  var dot = function dot() {\n    switch (arguments.length) {\n    case 2:\n      return new dot.Vector2(arguments[0], arguments[1]);\n    case 3:\n      return new dot.Vector3(arguments[0], arguments[1], arguments[2]);\n    case 4:\n      return new dot.Vector4(arguments[0], arguments[1], arguments[2], arguments[3]);\n    default:\n      throw new Error('dot takes 2-4 arguments');\n    }\n  };\n  dot.FastArray = window.Float64Array ? window.Float64Array : window.Array;\n  dot.assert = null;\n  return dot;\n});",
    "\ndefine('DOT/Dimension2',['require','DOT/dot'],function (require) {\n  'use strict';\n  var dot = require('DOT/dot');\n  dot.Dimension2 = function Dimension2(width, height) {\n    this.width = width;\n    this.height = height;\n  };\n  var Dimension2 = dot.Dimension2;\n  Dimension2.prototype = {\n    constructor: Dimension2,\n    toString: function () {\n      return '[' + this.width + 'w, ' + this.height + 'h]';\n    },\n    equals: function (other) {\n      return this.width === other.width && this.height === other.height;\n    }\n  };\n  return Dimension2;\n});",
    "\ndefine('PHET_CORE/extend',['require'],function (require) {\n  'use strict';\n  return function extend(obj) {\n    _.each(Array.prototype.slice.call(arguments, 1), function (source) {\n      if (source) {\n        for (var prop in source) {\n          Object.defineProperty(obj, prop, Object.getOwnPropertyDescriptor(source, prop));\n        }\n      }\n    });\n    return obj;\n  };\n});",
    "\ndefine('PHET_CORE/inherit',['require','PHET_CORE/extend'],function (require) {\n  'use strict';\n  var extend = require('PHET_CORE/extend');\n  function inherit(supertype, subtype, prototypeProperties, staticProperties) {\n    function F() {\n    }\n    F.prototype = supertype.prototype;\n    subtype.prototype = extend(new F(), { constructor: subtype }, prototypeProperties);\n    extend(subtype, staticProperties);\n    return subtype;\n  }\n  return inherit;\n});",
    "\ndefine('AXON/axon',['require'],function (require) {\n  'use strict';\n  var axon = {};\n  return axon;\n});",
    "\ndefine('AXON/log',['require','AXON/axon'],function (require) {\n  'use strict';\n  var axon = require('AXON/axon');\n  var cid = 0;\n  function Log() {\n    var log = this;\n    this.enabled = window && window.phetcommon && window.phetcommon.getQueryParameter && window.phetcommon.getQueryParameter('log');\n    this.properties = [];\n    this.collections = [];\n    this.propertySets = [];\n    this.entries = [];\n    this.replacer = function (key, value) {\n      if (value && value.cid) {\n        return {\n          jsonClass: 'Property',\n          cid: value.cid\n        };\n      }\n      if (value && value.constructor.name === 'Vector2') {\n        return {\n          x: value.x,\n          y: value.y,\n          jsonClass: 'Vector2'\n        };\n      }\n      return value;\n    };\n    this.reviver = function (key, value) {\n      if (value && value.jsonClass && value.jsonClass === 'Property') {\n        return log.properties[value.cid];\n      }\n      if (value && value.jsonClass && value.jsonClass === 'Vector2') {\n        return {\n          x: value.x,\n          y: value.y\n        };\n      }\n      return value;\n    };\n  }\n  Log.prototype = {\n    registerProperty: function (property) {\n      if (!this.enabled) {\n        return;\n      }\n      var index = this.properties.length;\n      var log = this;\n      this.properties.push(property);\n      property.lazyLink(function (value) {\n        var entry = {\n            time: Date.now(),\n            type: 'property',\n            index: index,\n            action: 'change',\n            value: JSON.stringify(value, log.replacer)\n          };\n        log.entries.push(entry);\n      });\n    },\n    clear: function () {\n      this.properties = [];\n      this.collection = [];\n      this.propertySets = [];\n    },\n    stepUntil: function (logArray, playbackTime, logIndex) {\n      var log = this;\n      while (logIndex < logArray.length) {\n        var time = logArray[logIndex].time;\n        if (time <= playbackTime) {\n          var entry = logArray[logIndex];\n          var cid = entry.cid;\n          if (entry.action === 'change') {\n            if (entry.value) {\n              log.properties[cid].value = JSON.parse(entry.value, log.reviver);\n            } else {\n              console.log('missing value for index: ', logIndex, entry);\n            }\n          } else if (entry.action === 'trigger') {\n            log.properties[cid].trigger(entry.event);\n          } else if (entry.action === 'add') {\n            log.collections[entry.collectionCid].add(log.properties[entry.cid]);\n          } else if (entry.action === 'remove') {\n            log.collections[entry.collectionCid].remove(log.properties[entry.cid]);\n          } else if (entry.action === 'reset') {\n            log.collections[entry.collectionCid].reset();\n          } else if (entry.action === 'sort') {\n            log.collections[entry.collectionCid].sort();\n          }\n          logIndex++;\n        } else {\n          break;\n        }\n      }\n      return logIndex;\n    }\n  };\n  axon.log = axon.log || new Log();\n  return axon.log;\n});",
    "\ndefine('AXON/Property',['require','AXON/log','AXON/axon'],function (require) {\n  'use strict';\n  var log = require('AXON/log');\n  var axon = require('AXON/axon');\n  axon.Property = function Property(value) {\n    this._value = value;\n    this._initialValue = value;\n    this._observers = [];\n    log.registerProperty(this);\n  };\n  axon.Property.prototype = {\n    get: function () {\n      return this._value;\n    },\n    set: function (value) {\n      if (value !== this._value) {\n        var oldValue = this._value;\n        this._value = value;\n        var observersCopy = this._observers.slice();\n        for (var i = 0; i < observersCopy.length; i++) {\n          observersCopy[i](value, oldValue);\n        }\n      }\n    },\n    notifyObserversUnsafe: function () {\n      for (var i = 0; i < this._observers.length; i++) {\n        this._observers[i](this._value);\n      }\n    },\n    reset: function () {\n      this.set(this._initialValue);\n    },\n    _set: function (value) {\n      return this.set.bind(this, value);\n    },\n    get value() {\n      return this.get();\n    },\n    set value(newValue) {\n      this.set(newValue);\n    },\n    link: function (observer) {\n      if (this._observers.indexOf(observer) === -1) {\n        this._observers.push(observer);\n        observer(this._value, null);\n      }\n    },\n    unlink: function (observer) {\n      var index = this._observers.indexOf(observer);\n      if (index !== -1) {\n        this._observers.splice(index, index + 1);\n      }\n    },\n    lazyLink: function (observer) {\n      if (this._observers.indexOf(observer) === -1) {\n        this._observers.push(observer);\n      }\n    },\n    toString: function () {\n      return 'Property{' + this.get() + '}';\n    },\n    valueOf: function () {\n      return this.toString();\n    },\n    once: function (observer) {\n      var property = this;\n      var wrapper = function (newValue, oldValue) {\n        observer(newValue, oldValue);\n        property.unlink(wrapper);\n      };\n      this.lazyLink(wrapper);\n      return wrapper;\n    },\n    linkAttribute: function (object, attributeName) {\n      var handle = function (value) {\n        object[attributeName] = value;\n      };\n      this.link(handle);\n      return handle;\n    },\n    valueEquals: function (value) {\n      return new axon.DerivedProperty([this], function (propertyValue) {\n        return propertyValue === value;\n      });\n    },\n    not: function () {\n      var parentProperty = this;\n      var childProperty = new axon.Property(!this.value);\n      var setParentToChild = function (value) {\n        childProperty.set(!value);\n      };\n      parentProperty.link(setParentToChild);\n      var setChildToParent = function (value) {\n        parentProperty.set(!value);\n      };\n      childProperty.link(setChildToParent);\n      childProperty.detach = function () {\n        parentProperty.unlink(setParentToChild);\n        childProperty.unlink(setChildToParent);\n      };\n      return childProperty;\n    },\n    debug: function (name) {\n      var listener = function (value) {\n        console.log(name, value);\n      };\n      this.link(listener);\n      return listener;\n    }\n  };\n  return axon.Property;\n});",
    "\ndefine('AXON/DerivedProperty',['require','AXON/Property','AXON/axon'],function (require) {\n  'use strict';\n  var Property = require('AXON/Property');\n  var axon = require('AXON/axon');\n  axon.DerivedProperty = function DerivedProperty(dependencies, derivation) {\n    this.observers = [];\n    this.dependencies = dependencies;\n    var derivedProperty = this;\n    function update() {\n      var args = dependencies.map(function (property) {\n          return property.get();\n        });\n      var newValue = derivation.apply(null, args);\n      if (newValue !== derivedProperty._value) {\n        var oldValue = derivedProperty._value;\n        derivedProperty._value = newValue;\n        derivedProperty.observers.forEach(function (observer) {\n          observer(newValue, oldValue);\n        });\n      }\n    }\n    this.update = update;\n    dependencies.forEach(function (property) {\n      property.lazyLink(update);\n    });\n    update();\n  };\n  axon.DerivedProperty.prototype = {\n    get value() {\n      return this._value;\n    },\n    get: function () {\n      return this._value;\n    },\n    link: function (observer) {\n      this.observers.push(observer);\n      observer(this._value);\n    },\n    linkAttribute: function (object, attributeName) {\n      var handle = function (value) {\n        object[attributeName] = value;\n      };\n      this.link(handle);\n      return handle;\n    },\n    unlink: function (observer) {\n      var index = this.observers.indexOf(observer);\n      if (index !== -1) {\n        this.observers.splice(index, index + 1);\n      }\n    },\n    lazyLink: function (observer) {\n      this.observers.push(observer);\n    },\n    detach: function () {\n      var derivedProperty = this;\n      this.dependencies.forEach(function (property) {\n        property.unlink(derivedProperty.update);\n      });\n    }\n  };\n  return axon.DerivedProperty;\n});",
    "\ndefine('AXON/PropertySet',['require','AXON/Property','AXON/DerivedProperty','AXON/axon'],function (require) {\n  'use strict';\n  var Property = require('AXON/Property');\n  var DerivedProperty = require('AXON/DerivedProperty');\n  var axon = require('AXON/axon');\n  axon.PropertySet = function PropertySet(values) {\n    var propertySet = this;\n    this.keys = [];\n    Object.getOwnPropertyNames(values).forEach(function (value) {\n      propertySet.addProperty(value, values[value]);\n    });\n    this.eventListeners = {};\n  };\n  axon.PropertySet.prototype = {\n    addProperty: function (name, value) {\n      this[name + 'Property'] = new Property(value);\n      this.addGetterAndSetter(name);\n      this.keys.push(name);\n    },\n    removeProperty: function (name) {\n      var index = this.keys.indexOf(name);\n      if (index !== -1) {\n        this.keys.splice(index, index + 1);\n      }\n      delete this[name + 'Property'];\n      delete this[name];\n    },\n    addGetterAndSetter: function (name) {\n      var propertyName = name + 'Property';\n      Object.defineProperty(this, name, {\n        get: function () {\n          return this[propertyName].get();\n        },\n        set: function (value) {\n          this[propertyName].set(value);\n        },\n        configurable: true,\n        enumerable: true\n      });\n    },\n    addGetter: function (name) {\n      var propertyName = name + 'Property';\n      Object.defineProperty(this, name, {\n        get: function () {\n          return this[propertyName].get();\n        },\n        configurable: true,\n        enumerable: true\n      });\n    },\n    reset: function () {\n      var propertySet = this;\n      this.keys.forEach(function (key) {\n        propertySet[key + 'Property'].reset();\n      });\n    },\n    toDerivedProperty: function (dependencyNames, derivation) {\n      var propertySet = this;\n      var dependencies = dependencyNames.map(function (dependency) {\n          return propertySet[dependency + 'Property'];\n        });\n      return new DerivedProperty(dependencies, derivation);\n    },\n    addDerivedProperty: function (name, dependencyNames, derivation) {\n      this[name + 'Property'] = this.toDerivedProperty(dependencyNames, derivation);\n      this.addGetter(name);\n    },\n    set: function (values) {\n      var propertySet = this;\n      Object.getOwnPropertyNames(values).forEach(function (val) {\n        if (typeof (propertySet[val + 'Property'] === 'Property')) {\n          propertySet[val + 'Property'].set(values[val]);\n        } else {\n          throw new Error('property not found: ' + val);\n        }\n      });\n    },\n    multilink: function (dependencyNames, listener) {\n      return this.toDerivedProperty(dependencyNames, listener);\n    },\n    unmultilink: function (derivedProperty) {\n      derivedProperty.detach();\n    },\n    toString: function () {\n      var text = 'PropertySet{';\n      var propertySet = this;\n      for (var i = 0; i < this.keys.length; i++) {\n        var key = this.keys[i];\n        text = text + key + ':' + propertySet[key].toString();\n        if (i < this.keys.length - 1) {\n          text = text + ',';\n        }\n      }\n      return text + '}';\n    },\n    on: function (eventName, callback) {\n      this.eventListeners[eventName] = this.eventListeners[eventName] || [];\n      this.eventListeners[eventName].push(callback);\n    },\n    once: function (eventName, callback) {\n      var propertySet = this;\n      var wrappedCallback = function () {\n        propertySet.off(eventName, wrappedCallback);\n        if (arguments.length === 0) {\n          callback();\n        } else {\n          callback.apply(this, Array.prototype.slice.call(arguments, 0));\n        }\n      };\n      this.on(eventName, wrappedCallback);\n      return wrappedCallback;\n    },\n    off: function (eventName, callback) {\n      if (this.eventListeners[eventName]) {\n        var index = this.eventListeners[eventName].indexOf(callback);\n        if (index !== -1) {\n          this.eventListeners[eventName].splice(index, index + 1);\n        }\n      }\n    },\n    trigger: function (eventName) {\n      if (this.eventListeners[eventName]) {\n        var listenersCopy = this.eventListeners[eventName].slice();\n        for (var i = 0; i < listenersCopy.length; i++) {\n          var listener = listenersCopy[i];\n          if (arguments.length === 1) {\n            listener(arguments);\n          } else {\n            var suffix = Array.prototype.slice.call(arguments, 1);\n            listener.apply(this, suffix);\n          }\n        }\n      }\n    }\n  };\n  return axon.PropertySet;\n});",
    "\ndefine('common/model/NumberAtom',['require','PHET_CORE/inherit','AXON/PropertySet'],function (require) {\n  'use strict';\n  var inherit = require('PHET_CORE/inherit');\n  var PropertySet = require('AXON/PropertySet');\n  function NumberAtom(options) {\n    options = _.extend({\n      protonCount: 0,\n      neutronCount: 0,\n      electronCount: 0\n    }, options);\n    PropertySet.call(this, {\n      protonCount: options.protonCount,\n      neutronCount: options.neutronCount,\n      electronCount: options.electronCount\n    });\n    this.addDerivedProperty('charge', [\n      'protonCount',\n      'electronCount'\n    ], function (protonCount, electronCount) {\n      return protonCount - electronCount;\n    });\n    this.addDerivedProperty('massNumber', [\n      'protonCount',\n      'neutronCount'\n    ], function (protonCount, neutronCount) {\n      return protonCount + neutronCount;\n    });\n    this.addDerivedProperty('particleCount', [\n      'protonCount',\n      'neutronCount',\n      'electronCount'\n    ], function (protonCount, neutronCount, electronCount) {\n      return protonCount + neutronCount + electronCount;\n    });\n  }\n  inherit(PropertySet, NumberAtom, {\n    equals: function (otherAtom) {\n      return this.protonCount === otherAtom.protonCount && this.neutronCount === otherAtom.neutronCount && this.electronCount === otherAtom.electronCount;\n    }\n  });\n  return NumberAtom;\n});",
    "\ndefine('PHET_CORE/Poolable',['require','PHET_CORE/extend'],function (require) {\n  'use strict';\n  var extend = require('PHET_CORE/extend');\n  return function Poolable(type, options) {\n    var proto = type.prototype;\n    options = extend({\n      maxPoolSize: 50,\n      initialSize: 0\n    }, options);\n    var pool = type.pool = [];\n    if (options.defaultFactory) {\n      type.dirtyFromPool = function () {\n        if (pool.length) {\n          return pool.pop();\n        } else {\n          return options.defaultFactory();\n        }\n      };\n      type.fillPool = function (n) {\n        while (pool.length < n) {\n          pool.push(options.defaultFactory());\n        }\n      };\n      type.fillPool(options.initialSize);\n    }\n    if (options.constructorDuplicateFactory) {\n      type.createFromPool = options.constructorDuplicateFactory(pool);\n    }\n    proto.freeToPool = function () {\n      if (pool.length < options.maxPoolSize) {\n        pool.push(this);\n      }\n    };\n  };\n});",
    "\ndefine('DOT/Util',['require','DOT/dot'],function (require) {\n  'use strict';\n  var dot = require('DOT/dot');\n  dot.Util = {\n    testAssert: function () {\n      return 'assert.dot: ' + (null ? 'true' : 'false');\n    },\n    clamp: function (value, min, max) {\n      if (value < min) {\n        return min;\n      } else if (value > max) {\n        return max;\n      } else {\n        return value;\n      }\n    },\n    moduloBetweenDown: function (value, min, max) {\n      null;\n      var divisor = max - min;\n      var partial = (value - min) % divisor;\n      if (partial < 0) {\n        partial += divisor;\n      }\n      return partial + min;\n    },\n    moduloBetweenUp: function (value, min, max) {\n      return -Util.moduloBetweenDown(-value, -max, -min);\n    },\n    rangeInclusive: function (a, b) {\n      if (b < a) {\n        return [];\n      }\n      var result = new Array(b - a + 1);\n      for (var i = a; i <= b; i++) {\n        result[i - a] = i;\n      }\n      return result;\n    },\n    rangeExclusive: function (a, b) {\n      return Util.rangeInclusive(a + 1, b - 1);\n    },\n    toRadians: function (degrees) {\n      return Math.PI * degrees / 180;\n    },\n    toDegrees: function (radians) {\n      return 180 * radians / Math.PI;\n    },\n    lineLineIntersection: function (p1, p2, p3, p4) {\n      var x12 = p1.x - p2.x;\n      var x34 = p3.x - p4.x;\n      var y12 = p1.y - p2.y;\n      var y34 = p3.y - p4.y;\n      var denom = x12 * y34 - y12 * x34;\n      var a = p1.x * p2.y - p1.y * p2.x;\n      var b = p3.x * p4.y - p3.y * p4.x;\n      return new dot.Vector2((a * x34 - x12 * b) / denom, (a * y34 - y12 * b) / denom);\n    },\n    solveQuadraticRootsReal: function (a, b, c) {\n      var epsilon = 10000000;\n      if (a === 0 || Math.abs(b / a) > epsilon || Math.abs(c / a) > epsilon) {\n        return [-c / b];\n      }\n      var discriminant = b * b - 4 * a * c;\n      if (discriminant < 0) {\n        return [];\n      }\n      var sqrt = Math.sqrt(discriminant);\n      return [\n        (-b - sqrt) / (2 * a),\n        (-b + sqrt) / (2 * a)\n      ];\n    },\n    solveCubicRootsReal: function (a, b, c, d) {\n      var epsilon = 10000000;\n      if (a === 0 || Math.abs(b / a) > epsilon || Math.abs(c / a) > epsilon || Math.abs(d / a) > epsilon) {\n        return Util.solveQuadraticRootsReal(b, c, d);\n      }\n      if (d === 0 || Math.abs(a / d) > epsilon || Math.abs(b / d) > epsilon || Math.abs(c / d) > epsilon) {\n        return Util.solveQuadraticRootsReal(a, b, c);\n      }\n      b /= a;\n      c /= a;\n      d /= a;\n      var s, t;\n      var q = (3 * c - b * b) / 9;\n      var r = (-(27 * d) + b * (9 * c - 2 * (b * b))) / 54;\n      var discriminant = q * q * q + r * r;\n      var b3 = b / 3;\n      if (discriminant > 0) {\n        var dsqrt = Math.sqrt(discriminant);\n        return [Util.cubeRoot(r + dsqrt) + Util.cubeRoot(r - dsqrt) - b3];\n      }\n      if (discriminant === 0) {\n        var rsqrt = Util.cubeRoot(r);\n        var doubleRoot = b3 - rsqrt;\n        return [\n          -b3 + 2 * rsqrt,\n          doubleRoot,\n          doubleRoot\n        ];\n      } else {\n        var qX = -q * q * q;\n        qX = Math.acos(r / Math.sqrt(qX));\n        var rr = 2 * Math.sqrt(-q);\n        return [\n          -b3 + rr * Math.cos(qX / 3),\n          -b3 + rr * Math.cos((qX + 2 * Math.PI) / 3),\n          -b3 + rr * Math.cos((qX + 4 * Math.PI) / 3)\n        ];\n      }\n    },\n    cubeRoot: function (x) {\n      return x >= 0 ? Math.pow(x, 1 / 3) : -Math.pow(-x, 1 / 3);\n    },\n    linear: function (a1, a2, b1, b2, a3) {\n      return (b2 - b1) / (a2 - a1) * (a3 - a1) + b1;\n    },\n    toFixed: function (number, decimalPlaces) {\n      var multiplier = Math.pow(10, decimalPlaces);\n      return Math.round(number * multiplier) / multiplier;\n    },\n    isInteger: function (number) {\n      return Math.floor(number) === number;\n    }\n  };\n  var Util = dot.Util;\n  dot.testAssert = Util.testAssert;\n  dot.clamp = Util.clamp;\n  dot.moduloBetweenDown = Util.moduloBetweenDown;\n  dot.moduloBetweenUp = Util.moduloBetweenUp;\n  dot.rangeInclusive = Util.rangeInclusive;\n  dot.rangeExclusive = Util.rangeExclusive;\n  dot.toRadians = Util.toRadians;\n  dot.toDegrees = Util.toDegrees;\n  dot.lineLineIntersection = Util.lineLineIntersection;\n  dot.solveQuadraticRootsReal = Util.solveQuadraticRootsReal;\n  dot.solveCubicRootsReal = Util.solveCubicRootsReal;\n  dot.cubeRoot = Util.cubeRoot;\n  dot.linear = Util.linear;\n  return Util;\n});",
    "\ndefine('DOT/Vector2',['require','DOT/dot','PHET_CORE/inherit','PHET_CORE/Poolable','DOT/Util'],function (require) {\n  'use strict';\n  var dot = require('DOT/dot');\n  var inherit = require('PHET_CORE/inherit');\n  var Poolable = require('PHET_CORE/Poolable');\n  require('DOT/Util');\n  dot.Vector2 = function Vector2(x, y) {\n    this.x = x || 0;\n    this.y = y || 0;\n    null;\n    null;\n    phetAllocation && phetAllocation('Vector2');\n  };\n  var Vector2 = dot.Vector2;\n  Vector2.createPolar = function (magnitude, angle) {\n    return new Vector2(magnitude * Math.cos(angle), magnitude * Math.sin(angle));\n  };\n  Vector2.prototype = {\n    constructor: Vector2,\n    isVector2: true,\n    dimension: 2,\n    magnitude: function () {\n      return Math.sqrt(this.magnitudeSquared());\n    },\n    magnitudeSquared: function () {\n      return this.x * this.x + this.y * this.y;\n    },\n    distance: function (point) {\n      return Math.sqrt(this.distanceSquared(point));\n    },\n    distanceXY: function (x, y) {\n      var dx = this.x - x;\n      var dy = this.y - y;\n      return Math.sqrt(dx * dx + dy * dy);\n    },\n    distanceSquared: function (point) {\n      var dx = this.x - point.x;\n      var dy = this.y - point.y;\n      return dx * dx + dy * dy;\n    },\n    dot: function (v) {\n      return this.x * v.x + this.y * v.y;\n    },\n    equals: function (other) {\n      return this.x === other.x && this.y === other.y;\n    },\n    equalsEpsilon: function (other, epsilon) {\n      if (!epsilon) {\n        epsilon = 0;\n      }\n      return Math.max(Math.abs(this.x - other.x), Math.abs(this.y - other.y)) <= epsilon;\n    },\n    isFinite: function () {\n      return isFinite(this.x) && isFinite(this.y);\n    },\n    copy: function () {\n      return new Vector2(this.x, this.y);\n    },\n    crossScalar: function (v) {\n      return this.x * v.y - this.y * v.x;\n    },\n    normalized: function () {\n      var mag = this.magnitude();\n      if (mag === 0) {\n        throw new Error('Cannot normalize a zero-magnitude vector');\n      } else {\n        return new Vector2(this.x / mag, this.y / mag);\n      }\n    },\n    timesScalar: function (scalar) {\n      return new Vector2(this.x * scalar, this.y * scalar);\n    },\n    times: function (scalar) {\n      null;\n      return this.timesScalar(scalar);\n    },\n    componentTimes: function (v) {\n      return new Vector2(this.x * v.x, this.y * v.y);\n    },\n    plus: function (v) {\n      return new Vector2(this.x + v.x, this.y + v.y);\n    },\n    plusScalar: function (scalar) {\n      return new Vector2(this.x + scalar, this.y + scalar);\n    },\n    minus: function (v) {\n      return new Vector2(this.x - v.x, this.y - v.y);\n    },\n    minusScalar: function (scalar) {\n      return new Vector2(this.x - scalar, this.y - scalar);\n    },\n    dividedScalar: function (scalar) {\n      return new Vector2(this.x / scalar, this.y / scalar);\n    },\n    negated: function () {\n      return new Vector2(-this.x, -this.y);\n    },\n    angle: function () {\n      return Math.atan2(this.y, this.x);\n    },\n    perpendicular: function () {\n      return new Vector2(this.y, -this.x);\n    },\n    angleBetween: function (v) {\n      var thisMagnitude = this.magnitude();\n      var vMagnitude = v.magnitude();\n      return Math.acos(dot.clamp((this.x * v.x + this.y * v.y) / (thisMagnitude * vMagnitude), -1, 1));\n    },\n    rotated: function (angle) {\n      var newAngle = this.angle() + angle;\n      var mag = this.magnitude();\n      return new Vector2(mag * Math.cos(newAngle), mag * Math.sin(newAngle));\n    },\n    blend: function (vector, ratio) {\n      return new Vector2(this.x + (vector.x - this.x) * ratio, this.y + (vector.y - this.y) * ratio);\n    },\n    toString: function () {\n      return 'Vector2(' + this.x + ', ' + this.y + ')';\n    },\n    toVector3: function () {\n      return new dot.Vector3(this.x, this.y);\n    },\n    set: function (x, y) {\n      this.x = x;\n      this.y = y;\n      return this;\n    },\n    setX: function (x) {\n      this.x = x;\n      return this;\n    },\n    setY: function (y) {\n      this.y = y;\n      return this;\n    },\n    add: function (v) {\n      this.x += v.x;\n      this.y += v.y;\n      return this;\n    },\n    addScalar: function (scalar) {\n      this.x += scalar;\n      this.y += scalar;\n      return this;\n    },\n    subtract: function (v) {\n      this.x -= v.x;\n      this.y -= v.y;\n      return this;\n    },\n    subtractScalar: function (scalar) {\n      this.x -= scalar;\n      this.y -= scalar;\n      return this;\n    },\n    componentMultiply: function (v) {\n      this.x *= v.x;\n      this.y *= v.y;\n      return this;\n    },\n    divideScalar: function (scalar) {\n      this.x /= scalar;\n      this.y /= scalar;\n      return this;\n    },\n    negate: function () {\n      this.x = -this.x;\n      this.y = -this.y;\n      return this;\n    }\n  };\n  Poolable(Vector2, {\n    defaultFactory: function () {\n      return new Vector2();\n    },\n    constructorDuplicateFactory: function (pool) {\n      return function (x, y) {\n        if (pool.length) {\n          return pool.pop().set(x, y);\n        } else {\n          return new Vector2(x, y);\n        }\n      };\n    }\n  });\n  Vector2.Immutable = function ImmutableVector2(x, y) {\n    Vector2.call(this, x, y);\n  };\n  var Immutable = Vector2.Immutable;\n  inherit(Vector2, Immutable);\n  Immutable.mutableOverrideHelper = function (mutableFunctionName) {\n    Immutable.prototype[mutableFunctionName] = function () {\n      throw new Error('Cannot call mutable method \\'' + mutableFunctionName + '\\' on immutable Vector2');\n    };\n  };\n  Immutable.mutableOverrideHelper('set');\n  Immutable.mutableOverrideHelper('setX');\n  Immutable.mutableOverrideHelper('setY');\n  Immutable.mutableOverrideHelper('add');\n  Immutable.mutableOverrideHelper('addScalar');\n  Immutable.mutableOverrideHelper('subtract');\n  Immutable.mutableOverrideHelper('subtractScalar');\n  Immutable.mutableOverrideHelper('componentMultiply');\n  Immutable.mutableOverrideHelper('divideScalar');\n  Immutable.mutableOverrideHelper('negate');\n  Vector2.ZERO = new Immutable(0, 0);\n  Vector2.X_UNIT = new Immutable(1, 0);\n  Vector2.Y_UNIT = new Immutable(0, 1);\n  return Vector2;\n});",
    "\ndefine('common/SharedConstants',['require'],function (require) {\n  'use strict';\n  var SharedConstants = {};\n  SharedConstants.NUCLEON_RADIUS = 10;\n  SharedConstants.ELECTRON_RADIUS = 8;\n  SharedConstants.DISPLAY_PANEL_BACKGROUND_COLOR = 'rgb( 254, 255, 153 )';\n  SharedConstants.MAX_PROBLEM_ATTEMPTS = 2;\n  SharedConstants.CHARGE_TEXT_COLOR = function (charge) {\n    return charge > 0 ? 'red' : charge < 0 ? 'blue' : 'black';\n  };\n  SharedConstants.SUB_GAME_TYPES = [\n    'periodic-table-game',\n    'mass-and-charge-game',\n    'symbol-game',\n    'advanced-symbol-game'\n  ];\n  SharedConstants.SUB_GAME_TO_LEVEL = function (subGameType) {\n    return this.SUB_GAME_TYPES.indexOf(subGameType);\n  };\n  return SharedConstants;\n});",
    "\ndefine('common/model/Particle',['require','AXON/PropertySet','DOT/Vector2','common/SharedConstants','PHET_CORE/inherit'],function (require) {\n  'use strict';\n  var PropertySet = require('AXON/PropertySet');\n  var Vector2 = require('DOT/Vector2');\n  var SharedConstants = require('common/SharedConstants');\n  var inherit = require('PHET_CORE/inherit');\n  var DEFAULT_PARTICLE_VELOCITY = 200;\n  function Particle(type) {\n    PropertySet.call(this, {\n      type: type,\n      position: Vector2.ZERO,\n      destination: Vector2.ZERO,\n      radius: type === 'electron' ? SharedConstants.ELECTRON_RADIUS : SharedConstants.NUCLEON_RADIUS,\n      velocity: DEFAULT_PARTICLE_VELOCITY,\n      userControlled: false,\n      zLayer: 0\n    });\n  }\n  inherit(PropertySet, Particle, {\n    step: function (dt) {\n      if (!this.userControlled) {\n        var distanceToDestination = this.position.distance(this.destination);\n        if (distanceToDestination > dt * this.velocity) {\n          var stepMagnitude = this.velocity * dt;\n          var stepAngle = Math.atan2(this.destination.y - this.position.y, this.destination.x - this.position.x);\n          var stepVector = Vector2.createPolar(stepMagnitude, stepAngle);\n          this.position = this.position.plus(stepVector);\n        } else if (distanceToDestination > 0) {\n          this.position = this.destination;\n        }\n      }\n    },\n    moveImmediatelyToDestination: function () {\n      this.position = this.destination;\n    },\n    setPositionAndDestination: function (newPosition) {\n      null;\n      if (newPosition instanceof Vector2) {\n        this.destination = newPosition;\n        this.moveImmediatelyToDestination();\n      } else {\n        console.log('Error: Attempt to set position that is not a vector');\n      }\n    }\n  });\n  return Particle;\n});",
    "\ndefine('AXON/ObservableArray',['require','AXON/Property','PHET_CORE/inherit','AXON/axon'],function (require) {\n  'use strict';\n  var Property = require('AXON/Property');\n  var inherit = require('PHET_CORE/inherit');\n  var axon = require('AXON/axon');\n  axon.ObservableArray = function ObservableArray(initialArray, options) {\n    this._options = _.extend({ allowDuplicates: false }, options);\n    this._array = initialArray || [];\n    this._addedListeners = [];\n    this._removedListeners = [];\n    this.lengthProperty = new Property(this._array.length);\n    this.initialArray = initialArray ? initialArray.slice() : [];\n  };\n  axon.ObservableArray.prototype = {\n    reset: function () {\n      for (var i = 0; i < this._array.length; i++) {\n        this._fireItemRemoved(this._array[i]);\n      }\n      this._array = this.initialArray.slice();\n      for (i = 0; i < this._array.length; i++) {\n        this._fireItemAdded(this._array[i]);\n      }\n    },\n    get length() {\n      return this._array.length;\n    },\n    addItemAddedListener: function (listener) {\n      null;\n      this._addedListeners.push(listener);\n    },\n    removeItemAddedListener: function (listener) {\n      var index = this._addedListeners.indexOf(listener);\n      null;\n      this._addedListeners.splice(index, 1);\n    },\n    addItemRemovedListener: function (listener) {\n      null;\n      this._removedListeners.push(listener);\n    },\n    removeItemRemovedListener: function (listener) {\n      var index = this._removedListeners.indexOf(listener);\n      null;\n      this._removedListeners.splice(index, 1);\n    },\n    addListeners: function (itemAddedListener, itemRemovedListener) {\n      this.addItemAddedListener(itemAddedListener);\n      this.addItemRemovedListener(itemRemovedListener);\n    },\n    _fireItemAdded: function (item) {\n      var copy = this._addedListeners.slice(0);\n      for (var i = 0; i < copy.length; i++) {\n        copy[i](item, this);\n      }\n    },\n    _fireItemRemoved: function (item) {\n      var copy = this._removedListeners.slice(0);\n      for (var i = 0; i < copy.length; i++) {\n        copy[i](item, this);\n      }\n    },\n    add: function (item) {\n      this.push(item);\n    },\n    remove: function (item) {\n      var index = this._array.indexOf(item);\n      if (index !== -1) {\n        this._array.splice(index, 1);\n        this.lengthProperty.set(this._array.length);\n        this._fireItemRemoved(item);\n      }\n    },\n    push: function (item) {\n      if (!this._options.allowDuplicates && this.contains(item)) {\n        throw new Error('duplicates are not allowed');\n      }\n      this._array.push(item);\n      this.lengthProperty.set(this._array.length);\n      this._fireItemAdded(item);\n    },\n    pop: function () {\n      var item = this._array.pop();\n      if (item !== undefined) {\n        this.lengthProperty.set(this._array.length);\n        this._fireItemRemoved(item);\n      }\n      return item;\n    },\n    shift: function () {\n      var item = this._array.shift();\n      if (item !== undefined) {\n        this.lengthProperty.set(this._array.length);\n        this._fireItemRemoved(item);\n      }\n      return item;\n    },\n    contains: function (item) {\n      return this.indexOf(item) !== -1;\n    },\n    get: function (index) {\n      return this._array[index];\n    },\n    indexOf: function (item) {\n      return this._array.indexOf(item);\n    },\n    clear: function () {\n      var copy = this._array.slice(0);\n      for (var i = 0; i < copy.length; i++) {\n        this.remove(copy[i]);\n      }\n    },\n    forEach: function (callback) {\n      this._array.slice().forEach(callback);\n    },\n    map: function (mapFunction) {\n      return new axon.ObservableArray(this._array.map(mapFunction));\n    },\n    foldLeft: function (value, combiner) {\n      for (var i = 0; i < this._array.length; i++) {\n        value = combiner(value, this._array[i]);\n      }\n      return value;\n    }\n  };\n  return axon.ObservableArray;\n});",
    "\ndefine('common/Utils',[], function () {\n  'use strict';\n  var Utils = {};\n  Utils.distanceBetweenPoints = function (x1, y1, x2, y2) {\n    return Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));\n  };\n  Utils.roughlyEqual = function (value1, value2, tolerance) {\n    return Math.abs(value1 - value2) < tolerance;\n  };\n  Utils.formatTime = function (secs) {\n    var hours = Math.floor(secs / 3600);\n    var minutes = Math.floor((secs - hours * 3600) / 60);\n    var seconds = Math.floor(secs - hours * 3600 - minutes * 60);\n    return (hours > 0 ? hours + ':' : '') + minutes + ':' + (seconds > 9 ? seconds : '0' + seconds);\n  };\n  return Utils;\n});",
    "\ndefine('common/model/ParticleAtom',['require','AXON/PropertySet','common/SharedConstants','DOT/Vector2','common/model/Particle','AXON/ObservableArray','PHET_CORE/inherit','common/Utils'],function (require) {\n  'use strict';\n  var PropertySet = require('AXON/PropertySet');\n  var SharedConstants = require('common/SharedConstants');\n  var Vector2 = require('DOT/Vector2');\n  var Particle = require('common/model/Particle');\n  var ObservableArray = require('AXON/ObservableArray');\n  var inherit = require('PHET_CORE/inherit');\n  var Utils = require('common/Utils');\n  function ParticleAtom(options) {\n    PropertySet.call(this, {\n      position: Vector2.ZERO,\n      nucleusOffset: Vector2.ZERO\n    });\n    var thisAtom = this;\n    options = _.extend({\n      innerElectronShellRadius: 80,\n      outerElectronShellRadius: 150\n    }, options);\n    this.protons = new ObservableArray();\n    this.neutrons = new ObservableArray();\n    this.electrons = new ObservableArray();\n    this.innerElectronShellRadius = options.innerElectronShellRadius;\n    this.outerElectronShellRadius = options.outerElectronShellRadius;\n    this.electronAddMode = 'proximal';\n    this.validElectronPositions = new Array(10);\n    var angle = 0;\n    this.validElectronPositions[0] = {\n      electron: null,\n      position: new Vector2(thisAtom.innerElectronShellRadius, 0)\n    };\n    angle += Math.PI;\n    this.validElectronPositions[1] = {\n      electron: null,\n      position: new Vector2(-thisAtom.innerElectronShellRadius, 0)\n    };\n    var numSlotsInOuterShell = 8;\n    angle += Math.PI / numSlotsInOuterShell / 2;\n    for (var i = 0; i < numSlotsInOuterShell; i++) {\n      this.validElectronPositions[i + 2] = {\n        electron: null,\n        position: new Vector2(Math.cos(angle) * thisAtom.outerElectronShellRadius, Math.sin(angle) * thisAtom.outerElectronShellRadius)\n      };\n      angle += Math.PI / numSlotsInOuterShell * 2;\n    }\n    this.electrons.addItemRemovedListener(function (electron) {\n      thisAtom.validElectronPositions.forEach(function (validElectronPosition) {\n        if (validElectronPosition.electron === electron) {\n          validElectronPosition.electron = null;\n          if (Math.abs(validElectronPosition.position.magnitude() - thisAtom.innerElectronShellRadius) < 0.00001) {\n            var occupiedOuterShellPositions = _.filter(thisAtom.validElectronPositions, function (validElectronPosition) {\n                return validElectronPosition.electron !== null && Utils.roughlyEqual(validElectronPosition.position.magnitude(), thisAtom.outerElectronShellRadius, 0.00001);\n              });\n            occupiedOuterShellPositions = _.sortBy(occupiedOuterShellPositions, function (occupiedShellPosition) {\n              return occupiedShellPosition.position.distance(validElectronPosition.position);\n            });\n            if (occupiedOuterShellPositions.length > 0) {\n              validElectronPosition.electron = occupiedOuterShellPositions[0].electron;\n              occupiedOuterShellPositions[0].electron = null;\n              validElectronPosition.electron.destination = validElectronPosition.position;\n            }\n          }\n        }\n      });\n    });\n    var translateParticle = function (particle, translation) {\n      if (particle.position.equals(particle.destination)) {\n        particle.setPositionAndDestination(particle.position.plus(translation));\n      } else {\n        particle.destination = particle.destination.plus(translation);\n      }\n    };\n    this.nucleusOffsetProperty.link(function (newOffset, oldOffset) {\n      var translation = oldOffset === null ? Vector2.ZERO : newOffset.minus(oldOffset);\n      thisAtom.protons.forEach(function (particle) {\n        translateParticle(particle, translation);\n      });\n      thisAtom.neutrons.forEach(function (particle) {\n        translateParticle(particle, translation);\n      });\n    });\n  }\n  return inherit(PropertySet, ParticleAtom, {\n    addParticle: function (particle) {\n      var thisAtom = this;\n      if (particle.type === 'proton') {\n        this.protons.add(particle);\n        this.reconfigureNucleus();\n        var userControlledProtonListener = function (userControlled) {\n          if (userControlled && thisAtom.protons.contains(particle)) {\n            thisAtom.protons.remove(particle);\n            thisAtom.reconfigureNucleus();\n            particle.zLayer = 0;\n          }\n          particle.userControlledProperty.unlink(userControlledProtonListener);\n        };\n        particle.userControlledProperty.lazyLink(userControlledProtonListener);\n      } else if (particle.type === 'neutron') {\n        this.neutrons.add(particle);\n        this.reconfigureNucleus();\n        particle.userControlledProperty.once(function (userControlled) {\n          if (userControlled && thisAtom.neutrons.contains(particle)) {\n            thisAtom.neutrons.remove(particle);\n            thisAtom.reconfigureNucleus();\n            particle.zLayer = 0;\n          }\n        });\n      } else if (particle.type === 'electron') {\n        this.electrons.add(particle);\n        var openPositions = this.validElectronPositions.filter(function (electronPosition) {\n            return electronPosition.electron === null;\n          });\n        var sortedOpenPositions;\n        if (this.electronAddMode === 'proximal') {\n          sortedOpenPositions = openPositions.sort(function (p1, p2) {\n            return Utils.distanceBetweenPoints(particle.position.x, particle.position.y, p1.position.x, p1.position.y) - Utils.distanceBetweenPoints(particle.position.x, particle.position.y, p2.position.x, p2.position.y);\n          });\n        } else {\n          sortedOpenPositions = _.shuffle(openPositions);\n        }\n        sortedOpenPositions = sortedOpenPositions.sort(function (p1, p2) {\n          return Math.round(Utils.distanceBetweenPoints(thisAtom.position.x, thisAtom.position.y, p1.position.x, p1.position.y) - Utils.distanceBetweenPoints(thisAtom.position.x, thisAtom.position.y, p2.position.x, p2.position.y));\n        });\n        null;\n        sortedOpenPositions[0].electron = particle;\n        particle.destination = sortedOpenPositions[0].position;\n        particle.userControlledProperty.once(function (userControlled) {\n          if (userControlled && thisAtom.electrons.contains(particle)) {\n            thisAtom.electrons.remove(particle);\n          }\n        });\n      } else {\n        null;\n      }\n    },\n    removeParticle: function (particleType) {\n      var thisAtom = this;\n      var particle;\n      if (particleType === 'proton') {\n        particle = this.protons.pop();\n        this.reconfigureNucleus();\n      } else if (particleType === 'neutron') {\n        particle = this.neutrons.pop();\n        this.reconfigureNucleus();\n      } else if (particleType === 'electron') {\n        particle = this.electrons.pop();\n      } else {\n        null;\n      }\n      return particle;\n    },\n    moveAllParticlesToDestination: function () {\n      this.protons.forEach(function (p) {\n        p.moveImmediatelyToDestination();\n      });\n      this.neutrons.forEach(function (p) {\n        p.moveImmediatelyToDestination();\n      });\n      this.electrons.forEach(function (p) {\n        p.moveImmediatelyToDestination();\n      });\n    },\n    getWeight: function () {\n      return this.protons.length + this.neutrons.length;\n    },\n    getCharge: function () {\n      return this.protons.length - this.electrons.length;\n    },\n    reconfigureNucleus: function () {\n      var centerX = this.position.x + this.nucleusOffset.x;\n      var centerY = this.position.y + this.nucleusOffset.y;\n      var nucleonRadius = SharedConstants.NUCLEON_RADIUS;\n      var angle, distFromCenter;\n      var nucleons = [];\n      var protonIndex = 0, neutronIndex = 0;\n      var neutronsPerProton = this.neutrons.length / this.protons.length;\n      var neutronsToAdd = 0;\n      while (nucleons.length < this.neutrons.length + this.protons.length) {\n        neutronsToAdd += neutronsPerProton;\n        while (neutronsToAdd >= 1 && neutronIndex < this.neutrons.length) {\n          nucleons.push(this.neutrons.get(neutronIndex++));\n          neutronsToAdd -= 1;\n        }\n        if (protonIndex < this.protons.length) {\n          nucleons.push(this.protons.get(protonIndex++));\n        }\n      }\n      if (nucleons.length === 1) {\n        nucleons[0].destination = new Vector2(centerX, centerY);\n        nucleons[0].zLayer = 0;\n      } else if (nucleons.length === 2) {\n        angle = 0.2 * 2 * Math.PI;\n        nucleons[0].destination = new Vector2(centerX + nucleonRadius * Math.cos(angle), centerY + nucleonRadius * Math.sin(angle));\n        nucleons[0].zLayer = 0;\n        nucleons[1].destination = new Vector2(centerX - nucleonRadius * Math.cos(angle), centerY - nucleonRadius * Math.sin(angle));\n        nucleons[1].zLayer = 0;\n      } else if (nucleons.length === 3) {\n        angle = 0.7 * 2 * Math.PI;\n        distFromCenter = nucleonRadius * 1.155;\n        nucleons[0].destination = new Vector2(centerX + distFromCenter * Math.cos(angle), centerY + distFromCenter * Math.sin(angle));\n        nucleons[0].zLayer = 0;\n        nucleons[1].destination = new Vector2(centerX + distFromCenter * Math.cos(angle + 2 * Math.PI / 3), centerY + distFromCenter * Math.sin(angle + 2 * Math.PI / 3));\n        nucleons[1].zLayer = 0;\n        nucleons[2].destination = new Vector2(centerX + distFromCenter * Math.cos(angle + 4 * Math.PI / 3), centerY + distFromCenter * Math.sin(angle + 4 * Math.PI / 3));\n        nucleons[2].zLayer = 0;\n      } else if (nucleons.length === 4) {\n        angle = 1.4 * 2 * Math.PI;\n        nucleons[0].destination = new Vector2(centerX + nucleonRadius * Math.cos(angle), centerY + nucleonRadius * Math.sin(angle));\n        nucleons[0].zLayer = 0;\n        nucleons[2].destination = new Vector2(centerX - nucleonRadius * Math.cos(angle), centerY - nucleonRadius * Math.sin(angle));\n        nucleons[2].zLayer = 0;\n        distFromCenter = nucleonRadius * 2 * Math.cos(Math.PI / 3);\n        nucleons[1].destination = new Vector2(centerX + distFromCenter * Math.cos(angle + Math.PI / 2), centerY + distFromCenter * Math.sin(angle + Math.PI / 2));\n        nucleons[1].zLayer = 1;\n        nucleons[3].destination = new Vector2(centerX - distFromCenter * Math.cos(angle + Math.PI / 2), centerY - distFromCenter * Math.sin(angle + Math.PI / 2));\n        nucleons[3].zLayer = 1;\n      } else if (nucleons.length >= 5) {\n        var placementRadius = 0;\n        var numAtThisRadius = 1;\n        var level = 0;\n        var placementAngle = 0;\n        var placementAngleDelta = 0;\n        for (var i = 0; i < nucleons.length; i++) {\n          nucleons[i].destination = new Vector2(centerX + placementRadius * Math.cos(placementAngle), centerY + placementRadius * Math.sin(placementAngle));\n          nucleons[i].zLayer = level;\n          numAtThisRadius--;\n          if (numAtThisRadius > 0) {\n            placementAngle += placementAngleDelta;\n          } else {\n            level++;\n            placementRadius += nucleonRadius * 1.35 / level;\n            placementAngle += Math.PI / 8;\n            numAtThisRadius = Math.floor(placementRadius * Math.PI / nucleonRadius);\n            placementAngleDelta = 2 * Math.PI / numAtThisRadius;\n          }\n        }\n      }\n    }\n  });\n});",
    "\ndefine('ASSERT/assert',['require'],function (require) {\n  'use strict';\n  return function assert(name, excludeByDefault) {\n    var hasName = 'assert.' + name;\n    var flagDefined = window.has && window.has(hasName) !== undefined;\n    var skipAssert = flagDefined ? !window.has(hasName) : excludeByDefault;\n    if (skipAssert) {\n      return null;\n    } else {\n      return function (predicate, message) {\n        var result = typeof predicate === 'function' ? predicate() : predicate;\n        if (!result) {\n          if (window.navigator && window.navigator.appName === 'Microsoft Internet Explorer') {\n            try {\n              throw new Error();\n            } catch (e) {\n              message = message + ', stack=\\n' + e.stack;\n            }\n          }\n          throw new Error('Assertion failed: ' + message);\n        }\n      };\n    }\n  };\n});",
    "\ndefine('KITE/kite',['require','PHET_CORE/phetAllocation'],function (require) {\n  'use strict';\n  window.phetAllocation = require('PHET_CORE/phetAllocation');\n  var kite = {};\n  kite.assert = null;\n  return kite;\n});",
    "\ndefine('DOT/Bounds2',['require','DOT/dot','DOT/Vector2'],function (require) {\n  'use strict';\n  var dot = require('DOT/dot');\n  require('DOT/Vector2');\n  dot.Bounds2 = function Bounds2(minX, minY, maxX, maxY) {\n    null;\n    this.minX = minX;\n    this.minY = minY;\n    this.maxX = maxX;\n    this.maxY = maxY;\n    phetAllocation && phetAllocation('Bounds2');\n  };\n  var Bounds2 = dot.Bounds2;\n  Bounds2.prototype = {\n    constructor: Bounds2,\n    getWidth: function () {\n      return this.maxX - this.minX;\n    },\n    get width() {\n      return this.getWidth();\n    },\n    getHeight: function () {\n      return this.maxY - this.minY;\n    },\n    get height() {\n      return this.getHeight();\n    },\n    getX: function () {\n      return this.minX;\n    },\n    get x() {\n      return this.getX();\n    },\n    getY: function () {\n      return this.minY;\n    },\n    get y() {\n      return this.getY();\n    },\n    getCenter: function () {\n      return new dot.Vector2(this.getCenterX(), this.getCenterY());\n    },\n    get center() {\n      return this.getCenter();\n    },\n    getCenterX: function () {\n      return (this.maxX + this.minX) / 2;\n    },\n    get centerX() {\n      return this.getCenterX();\n    },\n    getCenterY: function () {\n      return (this.maxY + this.minY) / 2;\n    },\n    get centerY() {\n      return this.getCenterY();\n    },\n    getMinX: function () {\n      return this.minX;\n    },\n    getMinY: function () {\n      return this.minY;\n    },\n    getMaxX: function () {\n      return this.maxX;\n    },\n    getMaxY: function () {\n      return this.maxY;\n    },\n    isEmpty: function () {\n      return this.getWidth() < 0 || this.getHeight() < 0;\n    },\n    isFinite: function () {\n      return isFinite(this.minX) && isFinite(this.minY) && isFinite(this.maxX) && isFinite(this.maxY);\n    },\n    isValid: function () {\n      return !this.isEmpty() && this.isFinite();\n    },\n    containsCoordinates: function (x, y) {\n      return this.minX <= x && x <= this.maxX && this.minY <= y && y <= this.maxY;\n    },\n    containsPoint: function (point) {\n      return this.containsCoordinates(point.x, point.y);\n    },\n    containsBounds: function (bounds) {\n      return this.minX <= bounds.minX && this.maxX >= bounds.maxX && this.minY <= bounds.minY && this.maxY >= bounds.maxY;\n    },\n    intersectsBounds: function (bounds) {\n      return !this.intersection(bounds).isEmpty();\n    },\n    toString: function () {\n      return '[x:(' + this.minX + ',' + this.maxX + '),y:(' + this.minY + ',' + this.maxY + ')]';\n    },\n    equals: function (other) {\n      return this.minX === other.minX && this.minY === other.minY && this.maxX === other.maxX && this.maxY === other.maxY;\n    },\n    equalsEpsilon: function (other, epsilon) {\n      epsilon = epsilon || 0;\n      var thisFinite = this.isFinite();\n      var otherFinite = other.isFinite();\n      if (thisFinite && otherFinite) {\n        return Math.abs(this.minX - other.minX) < epsilon && Math.abs(this.minY - other.minY) < epsilon && Math.abs(this.maxX - other.maxX) < epsilon && Math.abs(this.maxY - other.maxY) < epsilon;\n      } else if (thisFinite !== otherFinite) {\n        return false;\n      } else if (this === other) {\n        return true;\n      } else {\n        return (isFinite(this.minX + other.minX) ? Math.abs(this.minX - other.minX) < epsilon : this.minX === other.minX) && (isFinite(this.minY + other.minY) ? Math.abs(this.minY - other.minY) < epsilon : this.minY === other.minY) && (isFinite(this.maxX + other.maxX) ? Math.abs(this.maxX - other.maxX) < epsilon : this.maxX === other.maxX) && (isFinite(this.maxY + other.maxY) ? Math.abs(this.maxY - other.maxY) < epsilon : this.maxY === other.maxY);\n      }\n    },\n    copy: function () {\n      return new Bounds2(this.minX, this.minY, this.maxX, this.maxY);\n    },\n    union: function (bounds) {\n      return new Bounds2(Math.min(this.minX, bounds.minX), Math.min(this.minY, bounds.minY), Math.max(this.maxX, bounds.maxX), Math.max(this.maxY, bounds.maxY));\n    },\n    intersection: function (bounds) {\n      return new Bounds2(Math.max(this.minX, bounds.minX), Math.max(this.minY, bounds.minY), Math.min(this.maxX, bounds.maxX), Math.min(this.maxY, bounds.maxY));\n    },\n    withCoordinates: function (x, y) {\n      return new Bounds2(Math.min(this.minX, x), Math.min(this.minY, y), Math.max(this.maxX, x), Math.max(this.maxY, y));\n    },\n    withPoint: function (point) {\n      return this.withCoordinates(point.x, point.y);\n    },\n    withMinX: function (minX) {\n      return new Bounds2(minX, this.minY, this.maxX, this.maxY);\n    },\n    withMinY: function (minY) {\n      return new Bounds2(this.minX, minY, this.maxX, this.maxY);\n    },\n    withMaxX: function (maxX) {\n      return new Bounds2(this.minX, this.minY, maxX, this.maxY);\n    },\n    withMaxY: function (maxY) {\n      return new Bounds2(this.minX, this.minY, this.maxX, maxY);\n    },\n    roundedOut: function () {\n      return new Bounds2(Math.floor(this.minX), Math.floor(this.minY), Math.ceil(this.maxX), Math.ceil(this.maxY));\n    },\n    roundedIn: function () {\n      return new Bounds2(Math.ceil(this.minX), Math.ceil(this.minY), Math.floor(this.maxX), Math.floor(this.maxY));\n    },\n    transformed: function (matrix) {\n      return this.copy().transform(matrix);\n    },\n    dilated: function (d) {\n      return new Bounds2(this.minX - d, this.minY - d, this.maxX + d, this.maxY + d);\n    },\n    eroded: function (d) {\n      return this.dilated(-d);\n    },\n    shiftedX: function (x) {\n      return new Bounds2(this.minX + x, this.minY, this.maxX + x, this.maxY);\n    },\n    shiftedY: function (y) {\n      return new Bounds2(this.minX, this.minY + y, this.maxX, this.maxY + y);\n    },\n    shifted: function (x, y) {\n      return new Bounds2(this.minX + x, this.minY + y, this.maxX + x, this.maxY + y);\n    },\n    set: function (minX, minY, maxX, maxY) {\n      this.minX = minX;\n      this.minY = minY;\n      this.maxX = maxX;\n      this.maxY = maxY;\n      return this;\n    },\n    setBounds: function (bounds) {\n      return this.set(bounds.minX, bounds.minY, bounds.maxX, bounds.maxY);\n    },\n    includeBounds: function (bounds) {\n      this.minX = Math.min(this.minX, bounds.minX);\n      this.minY = Math.min(this.minY, bounds.minY);\n      this.maxX = Math.max(this.maxX, bounds.maxX);\n      this.maxY = Math.max(this.maxY, bounds.maxY);\n      return this;\n    },\n    constrainBounds: function (bounds) {\n      this.minX = Math.max(this.minX, bounds.minX);\n      this.minY = Math.max(this.minY, bounds.minY);\n      this.maxX = Math.min(this.maxX, bounds.maxX);\n      this.maxY = Math.min(this.maxY, bounds.maxY);\n      return this;\n    },\n    addCoordinates: function (x, y) {\n      this.minX = Math.min(this.minX, x);\n      this.minY = Math.min(this.minY, y);\n      this.maxX = Math.max(this.maxX, x);\n      this.maxY = Math.max(this.maxY, y);\n      return this;\n    },\n    addPoint: function (point) {\n      return this.addCoordinates(point.x, point.y);\n    },\n    setMinX: function (minX) {\n      this.minX = minX;\n      return this;\n    },\n    setMinY: function (minY) {\n      this.minY = minY;\n      return this;\n    },\n    setMaxX: function (maxX) {\n      this.maxX = maxX;\n      return this;\n    },\n    setMaxY: function (maxY) {\n      this.maxY = maxY;\n      return this;\n    },\n    roundOut: function () {\n      this.minX = Math.floor(this.minX);\n      this.minY = Math.floor(this.minY);\n      this.maxX = Math.ceil(this.maxX);\n      this.maxY = Math.ceil(this.maxY);\n      return this;\n    },\n    roundIn: function () {\n      this.minX = Math.ceil(this.minX);\n      this.minY = Math.ceil(this.minY);\n      this.maxX = Math.floor(this.maxX);\n      this.maxY = Math.floor(this.maxY);\n      return this;\n    },\n    transform: function (matrix) {\n      if (this.isEmpty()) {\n        return this;\n      }\n      var minX = this.minX;\n      var minY = this.minY;\n      var maxX = this.maxX;\n      var maxY = this.maxY;\n      var vector = new dot.Vector2();\n      this.setBounds(Bounds2.NOTHING);\n      this.addPoint(matrix.multiplyVector2(vector.set(minX, minY)));\n      this.addPoint(matrix.multiplyVector2(vector.set(minX, maxY)));\n      this.addPoint(matrix.multiplyVector2(vector.set(maxX, minY)));\n      this.addPoint(matrix.multiplyVector2(vector.set(maxX, maxY)));\n      return this;\n    },\n    dilate: function (d) {\n      return this.set(this.minX - d, this.minY - d, this.maxX + d, this.maxY + d);\n    },\n    erode: function (d) {\n      return this.dilate(-d);\n    },\n    shiftX: function (x) {\n      return this.setMinX(this.minX + x).setMaxX(this.maxX + x);\n    },\n    shiftY: function (y) {\n      return this.setMinY(this.minY + y).setMaxY(this.maxY + y);\n    },\n    shift: function (x, y) {\n      return this.shiftX(x).shiftY(y);\n    }\n  };\n  Bounds2.rect = function (x, y, width, height) {\n    return new Bounds2(x, y, x + width, y + height);\n  };\n  Bounds2.EVERYTHING = new Bounds2(Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY);\n  Bounds2.NOTHING = new Bounds2(Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY);\n  return Bounds2;\n});",
    "\ndefine('DOT/Ray2',['require','DOT/dot'],function (require) {\n  'use strict';\n  var dot = require('DOT/dot');\n  dot.Ray2 = function Ray2(pos, dir) {\n    this.pos = pos;\n    this.dir = dir;\n    null;\n    phetAllocation && phetAllocation('Ray2');\n  };\n  var Ray2 = dot.Ray2;\n  Ray2.prototype = {\n    constructor: Ray2,\n    shifted: function (distance) {\n      return new Ray2(this.pointAtDistance(distance), this.dir);\n    },\n    pointAtDistance: function (distance) {\n      return this.pos.plus(this.dir.timesScalar(distance));\n    },\n    toString: function () {\n      return this.pos.toString() + ' => ' + this.dir.toString();\n    }\n  };\n  return Ray2;\n});",
    "\ndefine('DOT/Vector4',['require','DOT/dot','DOT/Util'],function (require) {\n  'use strict';\n  var dot = require('DOT/dot');\n  require('DOT/Util');\n  dot.Vector4 = function Vector4(x, y, z, w) {\n    this.x = x || 0;\n    this.y = y || 0;\n    this.z = z || 0;\n    this.w = w !== undefined ? w : 1;\n  };\n  var Vector4 = dot.Vector4;\n  Vector4.prototype = {\n    constructor: Vector4,\n    magnitude: function () {\n      return Math.sqrt(this.magnitudeSquared());\n    },\n    magnitudeSquared: function () {\n      this.dot(this);\n    },\n    distance: function (point) {\n      return this.minus(point).magnitude();\n    },\n    distanceSquared: function (point) {\n      return this.minus(point).magnitudeSquared();\n    },\n    dot: function (v) {\n      return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w;\n    },\n    isFinite: function () {\n      return isFinite(this.x) && isFinite(this.y) && isFinite(this.z) && isFinite(this.w);\n    },\n    normalized: function () {\n      var mag = this.magnitude();\n      if (mag === 0) {\n        throw new Error('Cannot normalize a zero-magnitude vector');\n      } else {\n        return new Vector4(this.x / mag, this.y / mag, this.z / mag, this.w / mag);\n      }\n    },\n    timesScalar: function (scalar) {\n      return new Vector4(this.x * scalar, this.y * scalar, this.z * scalar, this.w * scalar);\n    },\n    times: function (scalar) {\n      null;\n      return this.timesScalar(scalar);\n    },\n    componentTimes: function (v) {\n      return new Vector4(this.x * v.x, this.y * v.y, this.z * v.z, this.w * v.w);\n    },\n    plus: function (v) {\n      return new Vector4(this.x + v.x, this.y + v.y, this.z + v.z, this.w + v.w);\n    },\n    plusScalar: function (scalar) {\n      return new Vector4(this.x + scalar, this.y + scalar, this.z + scalar, this.w + scalar);\n    },\n    minus: function (v) {\n      return new Vector4(this.x - v.x, this.y - v.y, this.z - v.z, this.w - v.w);\n    },\n    minusScalar: function (scalar) {\n      return new Vector4(this.x - scalar, this.y - scalar, this.z - scalar, this.w - scalar);\n    },\n    dividedScalar: function (scalar) {\n      return new Vector4(this.x / scalar, this.y / scalar, this.z / scalar, this.w / scalar);\n    },\n    negated: function () {\n      return new Vector4(-this.x, -this.y, -this.z, -this.w);\n    },\n    angleBetween: function (v) {\n      return Math.acos(dot.clamp(this.normalized().dot(v.normalized()), -1, 1));\n    },\n    blend: function (vector, ratio) {\n      return this.plus(vector.minus(this).times(ratio));\n    },\n    toString: function () {\n      return 'Vector4(' + this.x + ', ' + this.y + ', ' + this.z + ', ' + this.w + ')';\n    },\n    toVector3: function () {\n      return new dot.Vector3(this.x, this.y, this.z);\n    },\n    set: function (x, y, z, w) {\n      this.x = x;\n      this.y = y;\n      this.z = z;\n      this.w = w;\n    },\n    setX: function (x) {\n      this.x = x;\n    },\n    setY: function (y) {\n      this.y = y;\n    },\n    setZ: function (z) {\n      this.z = z;\n    },\n    setW: function (w) {\n      this.w = w;\n    },\n    copy: function (v) {\n      this.x = v.x;\n      this.y = v.y;\n      this.z = v.z;\n      this.w = v.w;\n    },\n    add: function (v) {\n      this.x += v.x;\n      this.y += v.y;\n      this.z += v.z;\n      this.w += v.w;\n    },\n    addScalar: function (scalar) {\n      this.x += scalar;\n      this.y += scalar;\n      this.z += scalar;\n      this.w += scalar;\n    },\n    subtract: function (v) {\n      this.x -= v.x;\n      this.y -= v.y;\n      this.z -= v.z;\n      this.w -= v.w;\n    },\n    subtractScalar: function (scalar) {\n      this.x -= scalar;\n      this.y -= scalar;\n      this.z -= scalar;\n      this.w -= scalar;\n    },\n    componentMultiply: function (v) {\n      this.x *= v.x;\n      this.y *= v.y;\n      this.z *= v.z;\n      this.w *= v.w;\n    },\n    divideScalar: function (scalar) {\n      this.x /= scalar;\n      this.y /= scalar;\n      this.z /= scalar;\n      this.w /= scalar;\n    },\n    negate: function () {\n      this.x = -this.x;\n      this.y = -this.y;\n      this.z = -this.z;\n      this.w = -this.w;\n    },\n    equals: function (other) {\n      return this.x === other.x && this.y === other.y && this.z === other.z && this.w === other.w;\n    },\n    equalsEpsilon: function (other, epsilon) {\n      if (!epsilon) {\n        epsilon = 0;\n      }\n      return Math.abs(this.x - other.x) + Math.abs(this.y - other.y) + Math.abs(this.z - other.z) + Math.abs(this.w - other.w) <= epsilon;\n    },\n    isVector4: true,\n    dimension: 4\n  };\n  Vector4.Immutable = function (x, y, z, w) {\n    this.x = x || 0;\n    this.y = y || 0;\n    this.z = z || 0;\n    this.w = w !== undefined ? w : 1;\n  };\n  var Immutable = Vector4.Immutable;\n  Immutable.prototype = new Vector4();\n  Immutable.prototype.constructor = Immutable;\n  Immutable.mutableOverrideHelper = function (mutableFunctionName) {\n    Immutable.prototype[mutableFunctionName] = function () {\n      throw new Error('Cannot call mutable method \\'' + mutableFunctionName + '\\' on immutable Vector4');\n    };\n  };\n  Immutable.mutableOverrideHelper('set');\n  Immutable.mutableOverrideHelper('setX');\n  Immutable.mutableOverrideHelper('setY');\n  Immutable.mutableOverrideHelper('setZ');\n  Immutable.mutableOverrideHelper('setW');\n  Immutable.mutableOverrideHelper('copy');\n  Immutable.mutableOverrideHelper('add');\n  Immutable.mutableOverrideHelper('addScalar');\n  Immutable.mutableOverrideHelper('subtract');\n  Immutable.mutableOverrideHelper('subtractScalar');\n  Immutable.mutableOverrideHelper('componentMultiply');\n  Immutable.mutableOverrideHelper('divideScalar');\n  Immutable.mutableOverrideHelper('negate');\n  Vector4.ZERO = new Immutable(0, 0, 0, 0);\n  Vector4.X_UNIT = new Immutable(1, 0, 0, 0);\n  Vector4.Y_UNIT = new Immutable(0, 1, 0, 0);\n  Vector4.Z_UNIT = new Immutable(0, 0, 1, 0);\n  Vector4.W_UNIT = new Immutable(0, 0, 0, 1);\n  return Vector4;\n});",
    "\ndefine('DOT/Vector3',['require','DOT/dot','DOT/Util','DOT/Vector2','DOT/Vector4'],function (require) {\n  'use strict';\n  var dot = require('DOT/dot');\n  require('DOT/Util');\n  require('DOT/Vector2');\n  require('DOT/Vector4');\n  dot.Vector3 = function Vector3(x, y, z) {\n    this.x = x || 0;\n    this.y = y || 0;\n    this.z = z || 0;\n  };\n  var Vector3 = dot.Vector3;\n  Vector3.prototype = {\n    constructor: Vector3,\n    magnitude: function () {\n      return Math.sqrt(this.magnitudeSquared());\n    },\n    magnitudeSquared: function () {\n      return this.dot(this);\n    },\n    distance: function (point) {\n      return this.minus(point).magnitude();\n    },\n    distanceSquared: function (point) {\n      return this.minus(point).magnitudeSquared();\n    },\n    dot: function (v) {\n      return this.x * v.x + this.y * v.y + this.z * v.z;\n    },\n    isFinite: function () {\n      return isFinite(this.x) && isFinite(this.y) && isFinite(this.z);\n    },\n    cross: function (v) {\n      return new Vector3(this.y * v.z - this.z * v.y, this.z * v.x - this.x * v.z, this.x * v.y - this.y * v.x);\n    },\n    normalized: function () {\n      var mag = this.magnitude();\n      if (mag === 0) {\n        throw new Error('Cannot normalize a zero-magnitude vector');\n      } else {\n        return new Vector3(this.x / mag, this.y / mag, this.z / mag);\n      }\n    },\n    timesScalar: function (scalar) {\n      return new Vector3(this.x * scalar, this.y * scalar, this.z * scalar);\n    },\n    times: function (scalar) {\n      null;\n      return this.timesScalar(scalar);\n    },\n    componentTimes: function (v) {\n      return new Vector3(this.x * v.x, this.y * v.y, this.z * v.z);\n    },\n    plus: function (v) {\n      return new Vector3(this.x + v.x, this.y + v.y, this.z + v.z);\n    },\n    plusScalar: function (scalar) {\n      return new Vector3(this.x + scalar, this.y + scalar, this.z + scalar);\n    },\n    minus: function (v) {\n      return new Vector3(this.x - v.x, this.y - v.y, this.z - v.z);\n    },\n    minusScalar: function (scalar) {\n      return new Vector3(this.x - scalar, this.y - scalar, this.z - scalar);\n    },\n    dividedScalar: function (scalar) {\n      return new Vector3(this.x / scalar, this.y / scalar, this.z / scalar);\n    },\n    negated: function () {\n      return new Vector3(-this.x, -this.y, -this.z);\n    },\n    angleBetween: function (v) {\n      return Math.acos(dot.clamp(this.normalized().dot(v.normalized()), -1, 1));\n    },\n    blend: function (vector, ratio) {\n      return this.plus(vector.minus(this).times(ratio));\n    },\n    toString: function () {\n      return 'Vector3(' + this.x + ', ' + this.y + ', ' + this.z + ')';\n    },\n    toVector2: function () {\n      return new dot.Vector2(this.x, this.y);\n    },\n    toVector4: function () {\n      return new dot.Vector4(this.x, this.y, this.z);\n    },\n    set: function (x, y, z) {\n      this.x = x;\n      this.y = y;\n      this.z = z;\n    },\n    setX: function (x) {\n      this.x = x;\n    },\n    setY: function (y) {\n      this.y = y;\n    },\n    setZ: function (z) {\n      this.z = z;\n    },\n    copy: function (v) {\n      this.x = v.x;\n      this.y = v.y;\n      this.z = v.z;\n    },\n    add: function (v) {\n      this.x += v.x;\n      this.y += v.y;\n      this.z += v.z;\n    },\n    addScalar: function (scalar) {\n      this.x += scalar;\n      this.y += scalar;\n      this.z += scalar;\n    },\n    subtract: function (v) {\n      this.x -= v.x;\n      this.y -= v.y;\n      this.z -= v.z;\n    },\n    subtractScalar: function (scalar) {\n      this.x -= scalar;\n      this.y -= scalar;\n      this.z -= scalar;\n    },\n    componentMultiply: function (v) {\n      this.x *= v.x;\n      this.y *= v.y;\n      this.z *= v.z;\n    },\n    divideScalar: function (scalar) {\n      this.x /= scalar;\n      this.y /= scalar;\n      this.z /= scalar;\n    },\n    negate: function () {\n      this.x = -this.x;\n      this.y = -this.y;\n      this.z = -this.z;\n    },\n    equals: function (other) {\n      return this.x === other.x && this.y === other.y && this.z === other.z;\n    },\n    equalsEpsilon: function (other, epsilon) {\n      if (!epsilon) {\n        epsilon = 0;\n      }\n      return Math.abs(this.x - other.x) + Math.abs(this.y - other.y) + Math.abs(this.z - other.z) <= epsilon;\n    },\n    isVector3: true,\n    dimension: 3\n  };\n  Vector3.Immutable = function (x, y, z) {\n    this.x = x || 0;\n    this.y = y || 0;\n    this.z = z || 0;\n  };\n  var Immutable = Vector3.Immutable;\n  Immutable.prototype = new Vector3();\n  Immutable.prototype.constructor = Immutable;\n  Immutable.mutableOverrideHelper = function (mutableFunctionName) {\n    Immutable.prototype[mutableFunctionName] = function () {\n      throw new Error('Cannot call mutable method \\'' + mutableFunctionName + '\\' on immutable Vector3');\n    };\n  };\n  Immutable.mutableOverrideHelper('set');\n  Immutable.mutableOverrideHelper('setX');\n  Immutable.mutableOverrideHelper('setY');\n  Immutable.mutableOverrideHelper('setZ');\n  Immutable.mutableOverrideHelper('copy');\n  Immutable.mutableOverrideHelper('add');\n  Immutable.mutableOverrideHelper('addScalar');\n  Immutable.mutableOverrideHelper('subtract');\n  Immutable.mutableOverrideHelper('subtractScalar');\n  Immutable.mutableOverrideHelper('componentMultiply');\n  Immutable.mutableOverrideHelper('divideScalar');\n  Immutable.mutableOverrideHelper('negate');\n  Vector3.ZERO = new Immutable(0, 0, 0);\n  Vector3.X_UNIT = new Immutable(1, 0, 0);\n  Vector3.Y_UNIT = new Immutable(0, 1, 0);\n  Vector3.Z_UNIT = new Immutable(0, 0, 1);\n  return Vector3;\n});",
    "\ndefine('DOT/Matrix4',['require','DOT/dot','DOT/Vector3','DOT/Vector4'],function (require) {\n  'use strict';\n  var dot = require('DOT/dot');\n  require('DOT/Vector3');\n  require('DOT/Vector4');\n  var Float32Array = window.Float32Array || Array;\n  dot.Matrix4 = function Matrix4(v00, v01, v02, v03, v10, v11, v12, v13, v20, v21, v22, v23, v30, v31, v32, v33, type) {\n    this.entries = new Float32Array(16);\n    this.rowMajor(v00 === undefined ? 1 : v00, v01 || 0, v02 || 0, v03 || 0, v10 || 0, v11 === undefined ? 1 : v11, v12 || 0, v13 || 0, v20 || 0, v21 || 0, v22 === undefined ? 1 : v22, v23 || 0, v30 || 0, v31 || 0, v32 || 0, v33 === undefined ? 1 : v33, type);\n  };\n  var Matrix4 = dot.Matrix4;\n  Matrix4.Types = {\n    OTHER: 0,\n    IDENTITY: 1,\n    TRANSLATION_3D: 2,\n    SCALING: 3\n  };\n  var Types = Matrix4.Types;\n  Matrix4.identity = function () {\n    return new Matrix4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, Types.IDENTITY);\n  };\n  Matrix4.translation = function (x, y, z) {\n    return new Matrix4(1, 0, 0, x, 0, 1, 0, y, 0, 0, 1, z, 0, 0, 0, 1, Types.TRANSLATION_3D);\n  };\n  Matrix4.translationFromVector = function (v) {\n    return Matrix4.translation(v.x, v.y, v.z);\n  };\n  Matrix4.scaling = function (x, y, z) {\n    y = y === undefined ? x : y;\n    z = z === undefined ? x : z;\n    return new Matrix4(x, 0, 0, 0, 0, y, 0, 0, 0, 0, z, 0, 0, 0, 0, 1, Types.SCALING);\n  };\n  Matrix4.rotationAxisAngle = function (axis, angle) {\n    var c = Math.cos(angle);\n    var s = Math.sin(angle);\n    var C = 1 - c;\n    return new Matrix4(axis.x * axis.x * C + c, axis.x * axis.y * C - axis.z * s, axis.x * axis.z * C + axis.y * s, 0, axis.y * axis.x * C + axis.z * s, axis.y * axis.y * C + c, axis.y * axis.z * C - axis.x * s, 0, axis.z * axis.x * C - axis.y * s, axis.z * axis.y * C + axis.x * s, axis.z * axis.z * C + c, 0, 0, 0, 0, 1, Types.OTHER);\n  };\n  Matrix4.rotationX = function (angle) {\n    var c = Math.cos(angle);\n    var s = Math.sin(angle);\n    return new Matrix4(1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, 0, 0, 0, 1, Types.OTHER);\n  };\n  Matrix4.rotationY = function (angle) {\n    var c = Math.cos(angle);\n    var s = Math.sin(angle);\n    return new Matrix4(c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1, Types.OTHER);\n  };\n  Matrix4.rotationZ = function (angle) {\n    var c = Math.cos(angle);\n    var s = Math.sin(angle);\n    return new Matrix4(c, -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, Types.OTHER);\n  };\n  Matrix4.gluPerspective = function (fovYRadians, aspect, zNear, zFar) {\n    var cotangent = Math.cos(fovYRadians) / Math.sin(fovYRadians);\n    return new Matrix4(cotangent / aspect, 0, 0, 0, 0, cotangent, 0, 0, 0, 0, (zFar + zNear) / (zNear - zFar), 2 * zFar * zNear / (zNear - zFar), 0, 0, -1, 0);\n  };\n  Matrix4.prototype = {\n    constructor: Matrix4,\n    rowMajor: function (v00, v01, v02, v03, v10, v11, v12, v13, v20, v21, v22, v23, v30, v31, v32, v33, type) {\n      this.entries[0] = v00;\n      this.entries[1] = v10;\n      this.entries[2] = v20;\n      this.entries[3] = v30;\n      this.entries[4] = v01;\n      this.entries[5] = v11;\n      this.entries[6] = v21;\n      this.entries[7] = v31;\n      this.entries[8] = v02;\n      this.entries[9] = v12;\n      this.entries[10] = v22;\n      this.entries[11] = v32;\n      this.entries[12] = v03;\n      this.entries[13] = v13;\n      this.entries[14] = v23;\n      this.entries[15] = v33;\n      this.type = type === undefined ? Types.OTHER : type;\n    },\n    columnMajor: function (v00, v10, v20, v30, v01, v11, v21, v31, v02, v12, v22, v32, v03, v13, v23, v33, type) {\n      this.rowMajor(v00, v01, v02, v03, v10, v11, v12, v13, v20, v21, v22, v23, v30, v31, v32, v33, type);\n    },\n    m00: function () {\n      return this.entries[0];\n    },\n    m01: function () {\n      return this.entries[4];\n    },\n    m02: function () {\n      return this.entries[8];\n    },\n    m03: function () {\n      return this.entries[12];\n    },\n    m10: function () {\n      return this.entries[1];\n    },\n    m11: function () {\n      return this.entries[5];\n    },\n    m12: function () {\n      return this.entries[9];\n    },\n    m13: function () {\n      return this.entries[13];\n    },\n    m20: function () {\n      return this.entries[2];\n    },\n    m21: function () {\n      return this.entries[6];\n    },\n    m22: function () {\n      return this.entries[10];\n    },\n    m23: function () {\n      return this.entries[14];\n    },\n    m30: function () {\n      return this.entries[3];\n    },\n    m31: function () {\n      return this.entries[7];\n    },\n    m32: function () {\n      return this.entries[11];\n    },\n    m33: function () {\n      return this.entries[15];\n    },\n    plus: function (m) {\n      return new Matrix4(this.m00() + m.m00(), this.m01() + m.m01(), this.m02() + m.m02(), this.m03() + m.m03(), this.m10() + m.m10(), this.m11() + m.m11(), this.m12() + m.m12(), this.m13() + m.m13(), this.m20() + m.m20(), this.m21() + m.m21(), this.m22() + m.m22(), this.m23() + m.m23(), this.m30() + m.m30(), this.m31() + m.m31(), this.m32() + m.m32(), this.m33() + m.m33());\n    },\n    minus: function (m) {\n      return new Matrix4(this.m00() - m.m00(), this.m01() - m.m01(), this.m02() - m.m02(), this.m03() - m.m03(), this.m10() - m.m10(), this.m11() - m.m11(), this.m12() - m.m12(), this.m13() - m.m13(), this.m20() - m.m20(), this.m21() - m.m21(), this.m22() - m.m22(), this.m23() - m.m23(), this.m30() - m.m30(), this.m31() - m.m31(), this.m32() - m.m32(), this.m33() - m.m33());\n    },\n    transposed: function () {\n      return new Matrix4(this.m00(), this.m10(), this.m20(), this.m30(), this.m01(), this.m11(), this.m21(), this.m31(), this.m02(), this.m12(), this.m22(), this.m32(), this.m03(), this.m13(), this.m23(), this.m33());\n    },\n    negated: function () {\n      return new Matrix4(-this.m00(), -this.m01(), -this.m02(), -this.m03(), -this.m10(), -this.m11(), -this.m12(), -this.m13(), -this.m20(), -this.m21(), -this.m22(), -this.m23(), -this.m30(), -this.m31(), -this.m32(), -this.m33());\n    },\n    inverted: function () {\n      var det = this.determinant();\n      if (det !== 0) {\n        return new Matrix4((-this.m31() * this.m22() * this.m13() + this.m21() * this.m32() * this.m13() + this.m31() * this.m12() * this.m23() - this.m11() * this.m32() * this.m23() - this.m21() * this.m12() * this.m33() + this.m11() * this.m22() * this.m33()) / det, (this.m31() * this.m22() * this.m03() - this.m21() * this.m32() * this.m03() - this.m31() * this.m02() * this.m23() + this.m01() * this.m32() * this.m23() + this.m21() * this.m02() * this.m33() - this.m01() * this.m22() * this.m33()) / det, (-this.m31() * this.m12() * this.m03() + this.m11() * this.m32() * this.m03() + this.m31() * this.m02() * this.m13() - this.m01() * this.m32() * this.m13() - this.m11() * this.m02() * this.m33() + this.m01() * this.m12() * this.m33()) / det, (this.m21() * this.m12() * this.m03() - this.m11() * this.m22() * this.m03() - this.m21() * this.m02() * this.m13() + this.m01() * this.m22() * this.m13() + this.m11() * this.m02() * this.m23() - this.m01() * this.m12() * this.m23()) / det, (this.m30() * this.m22() * this.m13() - this.m20() * this.m32() * this.m13() - this.m30() * this.m12() * this.m23() + this.m10() * this.m32() * this.m23() + this.m20() * this.m12() * this.m33() - this.m10() * this.m22() * this.m33()) / det, (-this.m30() * this.m22() * this.m03() + this.m20() * this.m32() * this.m03() + this.m30() * this.m02() * this.m23() - this.m00() * this.m32() * this.m23() - this.m20() * this.m02() * this.m33() + this.m00() * this.m22() * this.m33()) / det, (this.m30() * this.m12() * this.m03() - this.m10() * this.m32() * this.m03() - this.m30() * this.m02() * this.m13() + this.m00() * this.m32() * this.m13() + this.m10() * this.m02() * this.m33() - this.m00() * this.m12() * this.m33()) / det, (-this.m20() * this.m12() * this.m03() + this.m10() * this.m22() * this.m03() + this.m20() * this.m02() * this.m13() - this.m00() * this.m22() * this.m13() - this.m10() * this.m02() * this.m23() + this.m00() * this.m12() * this.m23()) / det, (-this.m30() * this.m21() * this.m13() + this.m20() * this.m31() * this.m13() + this.m30() * this.m11() * this.m23() - this.m10() * this.m31() * this.m23() - this.m20() * this.m11() * this.m33() + this.m10() * this.m21() * this.m33()) / det, (this.m30() * this.m21() * this.m03() - this.m20() * this.m31() * this.m03() - this.m30() * this.m01() * this.m23() + this.m00() * this.m31() * this.m23() + this.m20() * this.m01() * this.m33() - this.m00() * this.m21() * this.m33()) / det, (-this.m30() * this.m11() * this.m03() + this.m10() * this.m31() * this.m03() + this.m30() * this.m01() * this.m13() - this.m00() * this.m31() * this.m13() - this.m10() * this.m01() * this.m33() + this.m00() * this.m11() * this.m33()) / det, (this.m20() * this.m11() * this.m03() - this.m10() * this.m21() * this.m03() - this.m20() * this.m01() * this.m13() + this.m00() * this.m21() * this.m13() + this.m10() * this.m01() * this.m23() - this.m00() * this.m11() * this.m23()) / det, (this.m30() * this.m21() * this.m12() - this.m20() * this.m31() * this.m12() - this.m30() * this.m11() * this.m22() + this.m10() * this.m31() * this.m22() + this.m20() * this.m11() * this.m32() - this.m10() * this.m21() * this.m32()) / det, (-this.m30() * this.m21() * this.m02() + this.m20() * this.m31() * this.m02() + this.m30() * this.m01() * this.m22() - this.m00() * this.m31() * this.m22() - this.m20() * this.m01() * this.m32() + this.m00() * this.m21() * this.m32()) / det, (this.m30() * this.m11() * this.m02() - this.m10() * this.m31() * this.m02() - this.m30() * this.m01() * this.m12() + this.m00() * this.m31() * this.m12() + this.m10() * this.m01() * this.m32() - this.m00() * this.m11() * this.m32()) / det, (-this.m20() * this.m11() * this.m02() + this.m10() * this.m21() * this.m02() + this.m20() * this.m01() * this.m12() - this.m00() * this.m21() * this.m12() - this.m10() * this.m01() * this.m22() + this.m00() * this.m11() * this.m22()) / det);\n      } else {\n        throw new Error('Matrix could not be inverted, determinant === 0');\n      }\n    },\n    timesMatrix: function (m) {\n      var newType = Types.OTHER;\n      if (this.type === Types.TRANSLATION_3D && m.type === Types.TRANSLATION_3D) {\n        newType = Types.TRANSLATION_3D;\n      }\n      if (this.type === Types.SCALING && m.type === Types.SCALING) {\n        newType = Types.SCALING;\n      }\n      if (this.type === Types.IDENTITY) {\n        newType = m.type;\n      }\n      if (m.type === Types.IDENTITY) {\n        newType = this.type;\n      }\n      return new Matrix4(this.m00() * m.m00() + this.m01() * m.m10() + this.m02() * m.m20() + this.m03() * m.m30(), this.m00() * m.m01() + this.m01() * m.m11() + this.m02() * m.m21() + this.m03() * m.m31(), this.m00() * m.m02() + this.m01() * m.m12() + this.m02() * m.m22() + this.m03() * m.m32(), this.m00() * m.m03() + this.m01() * m.m13() + this.m02() * m.m23() + this.m03() * m.m33(), this.m10() * m.m00() + this.m11() * m.m10() + this.m12() * m.m20() + this.m13() * m.m30(), this.m10() * m.m01() + this.m11() * m.m11() + this.m12() * m.m21() + this.m13() * m.m31(), this.m10() * m.m02() + this.m11() * m.m12() + this.m12() * m.m22() + this.m13() * m.m32(), this.m10() * m.m03() + this.m11() * m.m13() + this.m12() * m.m23() + this.m13() * m.m33(), this.m20() * m.m00() + this.m21() * m.m10() + this.m22() * m.m20() + this.m23() * m.m30(), this.m20() * m.m01() + this.m21() * m.m11() + this.m22() * m.m21() + this.m23() * m.m31(), this.m20() * m.m02() + this.m21() * m.m12() + this.m22() * m.m22() + this.m23() * m.m32(), this.m20() * m.m03() + this.m21() * m.m13() + this.m22() * m.m23() + this.m23() * m.m33(), this.m30() * m.m00() + this.m31() * m.m10() + this.m32() * m.m20() + this.m33() * m.m30(), this.m30() * m.m01() + this.m31() * m.m11() + this.m32() * m.m21() + this.m33() * m.m31(), this.m30() * m.m02() + this.m31() * m.m12() + this.m32() * m.m22() + this.m33() * m.m32(), this.m30() * m.m03() + this.m31() * m.m13() + this.m32() * m.m23() + this.m33() * m.m33(), newType);\n    },\n    timesVector4: function (v) {\n      var x = this.m00() * v.x + this.m01() * v.y + this.m02() * v.z + this.m03() * v.w;\n      var y = this.m10() * v.x + this.m11() * v.y + this.m12() * v.z + this.m13() * v.w;\n      var z = this.m20() * v.x + this.m21() * v.y + this.m22() * v.z + this.m23() * v.w;\n      var w = this.m30() * v.x + this.m31() * v.y + this.m32() * v.z + this.m33() * v.w;\n      return new dot.Vector4(x, y, z, w);\n    },\n    timesVector3: function (v) {\n      return this.timesVector4(v.toVector4()).toVector3();\n    },\n    timesTransposeVector4: function (v) {\n      var x = this.m00() * v.x + this.m10() * v.y + this.m20() * v.z + this.m30() * v.w;\n      var y = this.m01() * v.x + this.m11() * v.y + this.m21() * v.z + this.m31() * v.w;\n      var z = this.m02() * v.x + this.m12() * v.y + this.m22() * v.z + this.m32() * v.w;\n      var w = this.m03() * v.x + this.m13() * v.y + this.m23() * v.z + this.m33() * v.w;\n      return new dot.Vector4(x, y, z, w);\n    },\n    timesTransposeVector3: function (v) {\n      return this.timesTransposeVector4(v.toVector4()).toVector3();\n    },\n    timesRelativeVector3: function (v) {\n      var x = this.m00() * v.x + this.m10() * v.y + this.m20() * v.z;\n      var y = this.m01() * v.y + this.m11() * v.y + this.m21() * v.z;\n      var z = this.m02() * v.z + this.m12() * v.y + this.m22() * v.z;\n      return new dot.Vector3(x, y, z);\n    },\n    determinant: function () {\n      return this.m03() * this.m12() * this.m21() * this.m30() - this.m02() * this.m13() * this.m21() * this.m30() - this.m03() * this.m11() * this.m22() * this.m30() + this.m01() * this.m13() * this.m22() * this.m30() + this.m02() * this.m11() * this.m23() * this.m30() - this.m01() * this.m12() * this.m23() * this.m30() - this.m03() * this.m12() * this.m20() * this.m31() + this.m02() * this.m13() * this.m20() * this.m31() + this.m03() * this.m10() * this.m22() * this.m31() - this.m00() * this.m13() * this.m22() * this.m31() - this.m02() * this.m10() * this.m23() * this.m31() + this.m00() * this.m12() * this.m23() * this.m31() + this.m03() * this.m11() * this.m20() * this.m32() - this.m01() * this.m13() * this.m20() * this.m32() - this.m03() * this.m10() * this.m21() * this.m32() + this.m00() * this.m13() * this.m21() * this.m32() + this.m01() * this.m10() * this.m23() * this.m32() - this.m00() * this.m11() * this.m23() * this.m32() - this.m02() * this.m11() * this.m20() * this.m33() + this.m01() * this.m12() * this.m20() * this.m33() + this.m02() * this.m10() * this.m21() * this.m33() - this.m00() * this.m12() * this.m21() * this.m33() - this.m01() * this.m10() * this.m22() * this.m33() + this.m00() * this.m11() * this.m22() * this.m33();\n    },\n    toString: function () {\n      return this.m00() + ' ' + this.m01() + ' ' + this.m02() + ' ' + this.m03() + '\\n' + this.m10() + ' ' + this.m11() + ' ' + this.m12() + ' ' + this.m13() + '\\n' + this.m20() + ' ' + this.m21() + ' ' + this.m22() + ' ' + this.m23() + '\\n' + this.m30() + ' ' + this.m31() + ' ' + this.m32() + ' ' + this.m33();\n    },\n    translation: function () {\n      return new dot.Vector3(this.m03(), this.m13(), this.m23());\n    },\n    scaling: function () {\n      return new dot.Vector3(this.m00(), this.m11(), this.m22());\n    },\n    makeImmutable: function () {\n      this.rowMajor = function () {\n        throw new Error('Cannot modify immutable matrix');\n      };\n    }\n  };\n  Matrix4.IDENTITY = new Matrix4();\n  Matrix4.IDENTITY.makeImmutable();\n  return Matrix4;\n});",
    "\ndefine('DOT/Matrix3',['require','DOT/dot','DOT/Vector2','DOT/Vector3','DOT/Matrix4'],function (require) {\n  'use strict';\n  var dot = require('DOT/dot');\n  var FastArray = dot.FastArray;\n  require('DOT/Vector2');\n  require('DOT/Vector3');\n  require('DOT/Matrix4');\n  dot.Matrix3 = function Matrix3(v00, v01, v02, v10, v11, v12, v20, v21, v22, type) {\n    this.entries = new FastArray(9);\n    this.rowMajor(v00 === undefined ? 1 : v00, v01 || 0, v02 || 0, v10 || 0, v11 === undefined ? 1 : v11, v12 || 0, v20 || 0, v21 || 0, v22 === undefined ? 1 : v22, type);\n    phetAllocation && phetAllocation('Matrix3');\n  };\n  var Matrix3 = dot.Matrix3;\n  Matrix3.Types = {\n    OTHER: 0,\n    IDENTITY: 1,\n    TRANSLATION_2D: 2,\n    SCALING: 3,\n    AFFINE: 4\n  };\n  var Types = Matrix3.Types;\n  Matrix3.identity = function () {\n    return new Matrix3(1, 0, 0, 0, 1, 0, 0, 0, 1, Types.IDENTITY);\n  };\n  Matrix3.translation = function (x, y) {\n    return new Matrix3(1, 0, x, 0, 1, y, 0, 0, 1, Types.TRANSLATION_2D);\n  };\n  Matrix3.translationFromVector = function (v) {\n    return Matrix3.translation(v.x, v.y);\n  };\n  Matrix3.scaling = function (x, y) {\n    y = y === undefined ? x : y;\n    return new Matrix3(x, 0, 0, 0, y, 0, 0, 0, 1, Types.SCALING);\n  };\n  Matrix3.scale = Matrix3.scaling;\n  Matrix3.affine = function (m00, m10, m01, m11, m02, m12) {\n    return new Matrix3(m00, m01, m02, m10, m11, m12, 0, 0, 1, Types.AFFINE);\n  };\n  Matrix3.rotationAxisAngle = function (axis, angle) {\n    var c = Math.cos(angle);\n    var s = Math.sin(angle);\n    var C = 1 - c;\n    return new Matrix3(axis.x * axis.x * C + c, axis.x * axis.y * C - axis.z * s, axis.x * axis.z * C + axis.y * s, axis.y * axis.x * C + axis.z * s, axis.y * axis.y * C + c, axis.y * axis.z * C - axis.x * s, axis.z * axis.x * C - axis.y * s, axis.z * axis.y * C + axis.x * s, axis.z * axis.z * C + c, Types.OTHER);\n  };\n  Matrix3.rotationX = function (angle) {\n    var c = Math.cos(angle);\n    var s = Math.sin(angle);\n    return new Matrix3(1, 0, 0, 0, c, -s, 0, s, c, Types.OTHER);\n  };\n  Matrix3.rotationY = function (angle) {\n    var c = Math.cos(angle);\n    var s = Math.sin(angle);\n    return new Matrix3(c, 0, s, 0, 1, 0, -s, 0, c, Types.OTHER);\n  };\n  Matrix3.rotationZ = function (angle) {\n    var c = Math.cos(angle);\n    var s = Math.sin(angle);\n    return new Matrix3(c, -s, 0, s, c, 0, 0, 0, 1, Types.AFFINE);\n  };\n  Matrix3.rotation2 = Matrix3.rotationZ;\n  Matrix3.fromSVGMatrix = function (svgMatrix) {\n    return new Matrix3(svgMatrix.a, svgMatrix.c, svgMatrix.e, svgMatrix.b, svgMatrix.d, svgMatrix.f, 0, 0, 1, Types.AFFINE);\n  };\n  Matrix3.rotateAToB = function (a, b) {\n    var start = a;\n    var end = b;\n    var epsilon = 0.0001;\n    var e, h, f;\n    var v = start.cross(end);\n    e = start.dot(end);\n    f = e < 0 ? -e : e;\n    if (f > 1 - epsilon) {\n      var c1, c2, c3;\n      var i, j;\n      var x = new dot.Vector3(start.x > 0 ? start.x : -start.x, start.y > 0 ? start.y : -start.y, start.z > 0 ? start.z : -start.z);\n      if (x.x < x.y) {\n        if (x.x < x.z) {\n          x = dot.Vector3.X_UNIT;\n        } else {\n          x = dot.Vector3.Z_UNIT;\n        }\n      } else {\n        if (x.y < x.z) {\n          x = dot.Vector3.Y_UNIT;\n        } else {\n          x = dot.Vector3.Z_UNIT;\n        }\n      }\n      var u = x.minus(start);\n      v = x.minus(end);\n      c1 = 2 / u.dot(u);\n      c2 = 2 / v.dot(v);\n      c3 = c1 * c2 * u.dot(v);\n      return Matrix3.IDENTITY.plus(Matrix3.rowMajor(-c1 * u.x * u.x - c2 * v.x * v.x + c3 * v.x * u.x, -c1 * u.x * u.y - c2 * v.x * v.y + c3 * v.x * u.y, -c1 * u.x * u.z - c2 * v.x * v.z + c3 * v.x * u.z, -c1 * u.y * u.x - c2 * v.y * v.x + c3 * v.y * u.x, -c1 * u.y * u.y - c2 * v.y * v.y + c3 * v.y * u.y, -c1 * u.y * u.z - c2 * v.y * v.z + c3 * v.y * u.z, -c1 * u.z * u.x - c2 * v.z * v.x + c3 * v.z * u.x, -c1 * u.z * u.y - c2 * v.z * v.y + c3 * v.z * u.y, -c1 * u.z * u.z - c2 * v.z * v.z + c3 * v.z * u.z));\n    } else {\n      var hvx, hvz, hvxy, hvxz, hvyz;\n      h = 1 / (1 + e);\n      hvx = h * v.x;\n      hvz = h * v.z;\n      hvxy = hvx * v.y;\n      hvxz = hvx * v.z;\n      hvyz = hvz * v.y;\n      return Matrix3.rowMajor(e + hvx * v.x, hvxy - v.z, hvxz + v.y, hvxy + v.z, e + h * v.y * v.y, hvyz - v.x, hvxz - v.y, hvyz + v.x, e + hvz * v.z);\n    }\n  };\n  Matrix3.prototype = {\n    constructor: Matrix3,\n    m00: function () {\n      return this.entries[0];\n    },\n    m01: function () {\n      return this.entries[3];\n    },\n    m02: function () {\n      return this.entries[6];\n    },\n    m10: function () {\n      return this.entries[1];\n    },\n    m11: function () {\n      return this.entries[4];\n    },\n    m12: function () {\n      return this.entries[7];\n    },\n    m20: function () {\n      return this.entries[2];\n    },\n    m21: function () {\n      return this.entries[5];\n    },\n    m22: function () {\n      return this.entries[8];\n    },\n    isAffine: function () {\n      return this.type === Types.AFFINE || this.m20() === 0 && this.m21() === 0 && this.m22() === 1;\n    },\n    isFinite: function () {\n      return isFinite(this.m00()) && isFinite(this.m01()) && isFinite(this.m02()) && isFinite(this.m10()) && isFinite(this.m11()) && isFinite(this.m12()) && isFinite(this.m20()) && isFinite(this.m21()) && isFinite(this.m22());\n    },\n    getDeterminant: function () {\n      return this.m00() * this.m11() * this.m22() + this.m01() * this.m12() * this.m20() + this.m02() * this.m10() * this.m21() - this.m02() * this.m11() * this.m20() - this.m01() * this.m10() * this.m22() - this.m00() * this.m12() * this.m21();\n    },\n    get determinant() {\n      return this.getDeterminant();\n    },\n    getTranslation: function () {\n      return new dot.Vector2(this.m02(), this.m12());\n    },\n    get translation() {\n      return this.getTranslation();\n    },\n    getScaleVector: function () {\n      return new dot.Vector2(Math.sqrt(this.m00() * this.m00() + this.m10() * this.m10()), Math.sqrt(this.m01() * this.m01() + this.m11() * this.m11()));\n    },\n    get scaleVector() {\n      return this.getScaleVector();\n    },\n    getRotation: function () {\n      var transformedVector = this.timesVector2(dot.Vector2.X_UNIT).minus(this.timesVector2(dot.Vector2.ZERO));\n      return Math.atan2(transformedVector.y, transformedVector.x);\n    },\n    get rotation() {\n      return this.getRotation();\n    },\n    toMatrix4: function () {\n      return new dot.Matrix4(this.m00(), this.m01(), this.m02(), 0, this.m10(), this.m11(), this.m12(), 0, this.m20(), this.m21(), this.m22(), 0, 0, 0, 0, 1);\n    },\n    toString: function () {\n      return this.m00() + ' ' + this.m01() + ' ' + this.m02() + '\\n' + this.m10() + ' ' + this.m11() + ' ' + this.m12() + '\\n' + this.m20() + ' ' + this.m21() + ' ' + this.m22();\n    },\n    toSVGMatrix: function () {\n      var result = document.createElementNS('http://www.w3.org/2000/svg', 'svg').createSVGMatrix();\n      result.a = this.m00();\n      result.b = this.m10();\n      result.c = this.m01();\n      result.d = this.m11();\n      result.e = this.m02();\n      result.f = this.m12();\n      return result;\n    },\n    getCSSTransform: function () {\n      return 'matrix(' + this.entries[0].toFixed(20) + ',' + this.entries[1].toFixed(20) + ',' + this.entries[3].toFixed(20) + ',' + this.entries[4].toFixed(20) + ',' + this.entries[6].toFixed(20) + ',' + this.entries[7].toFixed(20) + ')';\n    },\n    get cssTransform() {\n      return this.getCSSTransform();\n    },\n    getSVGTransform: function () {\n      function svgNumber(number) {\n        return number.toFixed(20);\n      }\n      switch (this.type) {\n      case Types.IDENTITY:\n        return '';\n      case Types.TRANSLATION_2D:\n        return 'translate(' + svgNumber(this.entries[6]) + ',' + this.entries[7] + ')';\n      case Types.SCALING:\n        return 'scale(' + svgNumber(this.entries[0]) + (this.entries[0] === this.entries[4] ? '' : ',' + svgNumber(this.entries[4])) + ')';\n      default:\n        return 'matrix(' + svgNumber(this.entries[0]) + ',' + svgNumber(this.entries[1]) + ',' + svgNumber(this.entries[3]) + ',' + svgNumber(this.entries[4]) + ',' + svgNumber(this.entries[6]) + ',' + svgNumber(this.entries[7]) + ')';\n      }\n    },\n    get svgTransform() {\n      return this.getSVGTransform();\n    },\n    getCSSTransformStyles: function () {\n      var transformCSS = this.getCSSTransform();\n      return {\n        '-webkit-perspective': 1000,\n        '-webkit-backface-visibility': 'hidden',\n        '-webkit-transform': transformCSS + ' translateZ(0)',\n        '-moz-transform': transformCSS + ' translateZ(0)',\n        '-ms-transform': transformCSS,\n        '-o-transform': transformCSS,\n        'transform': transformCSS,\n        'transform-origin': 'top left',\n        '-ms-transform-origin': 'top left'\n      };\n    },\n    get cssTransformStyles() {\n      return this.getCSSTransformStyles();\n    },\n    equals: function (m) {\n      return this.m00() === m.m00() && this.m01() === m.m01() && this.m02() === m.m02() && this.m10() === m.m10() && this.m11() === m.m11() && this.m12() === m.m12() && this.m20() === m.m20() && this.m21() === m.m21() && this.m22() === m.m22();\n    },\n    equalsEpsilon: function (m, epsilon) {\n      return Math.abs(this.m00() - m.m00()) < epsilon && Math.abs(this.m01() - m.m01()) < epsilon && Math.abs(this.m02() - m.m02()) < epsilon && Math.abs(this.m10() - m.m10()) < epsilon && Math.abs(this.m11() - m.m11()) < epsilon && Math.abs(this.m12() - m.m12()) < epsilon && Math.abs(this.m20() - m.m20()) < epsilon && Math.abs(this.m21() - m.m21()) < epsilon && Math.abs(this.m22() - m.m22()) < epsilon;\n    },\n    copy: function () {\n      return new Matrix3(this.m00(), this.m01(), this.m02(), this.m10(), this.m11(), this.m12(), this.m20(), this.m21(), this.m22(), this.type);\n    },\n    plus: function (m) {\n      return new Matrix3(this.m00() + m.m00(), this.m01() + m.m01(), this.m02() + m.m02(), this.m10() + m.m10(), this.m11() + m.m11(), this.m12() + m.m12(), this.m20() + m.m20(), this.m21() + m.m21(), this.m22() + m.m22());\n    },\n    minus: function (m) {\n      return new Matrix3(this.m00() - m.m00(), this.m01() - m.m01(), this.m02() - m.m02(), this.m10() - m.m10(), this.m11() - m.m11(), this.m12() - m.m12(), this.m20() - m.m20(), this.m21() - m.m21(), this.m22() - m.m22());\n    },\n    transposed: function () {\n      return new Matrix3(this.m00(), this.m10(), this.m20(), this.m01(), this.m11(), this.m21(), this.m02(), this.m12(), this.m22(), this.type === Types.IDENTITY || this.type === Types.SCALING ? this.type : undefined);\n    },\n    negated: function () {\n      return new Matrix3(-this.m00(), -this.m01(), -this.m02(), -this.m10(), -this.m11(), -this.m12(), -this.m20(), -this.m21(), -this.m22());\n    },\n    inverted: function () {\n      var det;\n      switch (this.type) {\n      case Types.IDENTITY:\n        return this;\n      case Types.TRANSLATION_2D:\n        return new Matrix3(1, 0, -this.m02(), 0, 1, -this.m12(), 0, 0, 1, Types.TRANSLATION_2D);\n      case Types.SCALING:\n        return new Matrix3(1 / this.m00(), 0, 0, 0, 1 / this.m11(), 0, 0, 0, 1 / this.m22(), Types.SCALING);\n      case Types.AFFINE:\n        det = this.getDeterminant();\n        if (det !== 0) {\n          return new Matrix3((-this.m12() * this.m21() + this.m11() * this.m22()) / det, (this.m02() * this.m21() - this.m01() * this.m22()) / det, (-this.m02() * this.m11() + this.m01() * this.m12()) / det, (this.m12() * this.m20() - this.m10() * this.m22()) / det, (-this.m02() * this.m20() + this.m00() * this.m22()) / det, (this.m02() * this.m10() - this.m00() * this.m12()) / det, 0, 0, 1, Types.AFFINE);\n        } else {\n          throw new Error('Matrix could not be inverted, determinant === 0');\n        }\n        break;\n      case Types.OTHER:\n        det = this.getDeterminant();\n        if (det !== 0) {\n          return new Matrix3((-this.m12() * this.m21() + this.m11() * this.m22()) / det, (this.m02() * this.m21() - this.m01() * this.m22()) / det, (-this.m02() * this.m11() + this.m01() * this.m12()) / det, (this.m12() * this.m20() - this.m10() * this.m22()) / det, (-this.m02() * this.m20() + this.m00() * this.m22()) / det, (this.m02() * this.m10() - this.m00() * this.m12()) / det, (-this.m11() * this.m20() + this.m10() * this.m21()) / det, (this.m01() * this.m20() - this.m00() * this.m21()) / det, (-this.m01() * this.m10() + this.m00() * this.m11()) / det, Types.OTHER);\n        } else {\n          throw new Error('Matrix could not be inverted, determinant === 0');\n        }\n        break;\n      default:\n        throw new Error('Matrix3.inverted with unknown type: ' + this.type);\n      }\n    },\n    timesMatrix: function (m) {\n      if (this.type === Types.IDENTITY || m.type === Types.IDENTITY) {\n        return this.type === Types.IDENTITY ? m : this;\n      }\n      if (this.type === m.type) {\n        if (this.type === Types.TRANSLATION_2D) {\n          return new Matrix3(1, 0, this.m02() + m.m02(), 0, 1, this.m12() + m.m12(), 0, 0, 1, Types.TRANSLATION_2D);\n        } else if (this.type === Types.SCALING) {\n          return new Matrix3(this.m00() * m.m00(), 0, 0, 0, this.m11() * m.m11(), 0, 0, 0, 1, Types.SCALING);\n        }\n      }\n      if (this.type !== Types.OTHER && m.type !== Types.OTHER) {\n        return new Matrix3(this.m00() * m.m00() + this.m01() * m.m10(), this.m00() * m.m01() + this.m01() * m.m11(), this.m00() * m.m02() + this.m01() * m.m12() + this.m02(), this.m10() * m.m00() + this.m11() * m.m10(), this.m10() * m.m01() + this.m11() * m.m11(), this.m10() * m.m02() + this.m11() * m.m12() + this.m12(), 0, 0, 1, Types.AFFINE);\n      }\n      return new Matrix3(this.m00() * m.m00() + this.m01() * m.m10() + this.m02() * m.m20(), this.m00() * m.m01() + this.m01() * m.m11() + this.m02() * m.m21(), this.m00() * m.m02() + this.m01() * m.m12() + this.m02() * m.m22(), this.m10() * m.m00() + this.m11() * m.m10() + this.m12() * m.m20(), this.m10() * m.m01() + this.m11() * m.m11() + this.m12() * m.m21(), this.m10() * m.m02() + this.m11() * m.m12() + this.m12() * m.m22(), this.m20() * m.m00() + this.m21() * m.m10() + this.m22() * m.m20(), this.m20() * m.m01() + this.m21() * m.m11() + this.m22() * m.m21(), this.m20() * m.m02() + this.m21() * m.m12() + this.m22() * m.m22());\n    },\n    timesVector2: function (v) {\n      var x = this.m00() * v.x + this.m01() * v.y + this.m02();\n      var y = this.m10() * v.x + this.m11() * v.y + this.m12();\n      return new dot.Vector2(x, y);\n    },\n    timesVector3: function (v) {\n      var x = this.m00() * v.x + this.m01() * v.y + this.m02() * v.z;\n      var y = this.m10() * v.x + this.m11() * v.y + this.m12() * v.z;\n      var z = this.m20() * v.x + this.m21() * v.y + this.m22() * v.z;\n      return new dot.Vector3(x, y, z);\n    },\n    timesTransposeVector2: function (v) {\n      var x = this.m00() * v.x + this.m10() * v.y;\n      var y = this.m01() * v.x + this.m11() * v.y;\n      return new dot.Vector2(x, y);\n    },\n    timesRelativeVector2: function (v) {\n      var x = this.m00() * v.x + this.m01() * v.y;\n      var y = this.m10() * v.y + this.m11() * v.y;\n      return new dot.Vector2(x, y);\n    },\n    makeImmutable: function () {\n      this.rowMajor = function () {\n        throw new Error('Cannot modify immutable matrix');\n      };\n      return this;\n    },\n    rowMajor: function (v00, v01, v02, v10, v11, v12, v20, v21, v22, type) {\n      this.entries[0] = v00;\n      this.entries[1] = v10;\n      this.entries[2] = v20;\n      this.entries[3] = v01;\n      this.entries[4] = v11;\n      this.entries[5] = v21;\n      this.entries[6] = v02;\n      this.entries[7] = v12;\n      this.entries[8] = v22;\n      this.type = type === undefined ? v20 === 0 && v21 === 0 && v22 === 1 ? Types.AFFINE : Types.OTHER : type;\n      return this;\n    },\n    columnMajor: function (v00, v10, v20, v01, v11, v21, v02, v12, v22, type) {\n      return this.rowMajor(v00, v01, v02, v10, v11, v12, v20, v21, v22, type);\n    },\n    add: function (m) {\n      return this.rowMajor(this.m00() + m.m00(), this.m01() + m.m01(), this.m02() + m.m02(), this.m10() + m.m10(), this.m11() + m.m11(), this.m12() + m.m12(), this.m20() + m.m20(), this.m21() + m.m21(), this.m22() + m.m22());\n    },\n    subtract: function (m) {\n      return this.rowMajor(this.m00() - m.m00(), this.m01() - m.m01(), this.m02() - m.m02(), this.m10() - m.m10(), this.m11() - m.m11(), this.m12() - m.m12(), this.m20() - m.m20(), this.m21() - m.m21(), this.m22() - m.m22());\n    },\n    transpose: function () {\n      return this.rowMajor(this.m00(), this.m10(), this.m20(), this.m01(), this.m11(), this.m21(), this.m02(), this.m12(), this.m22(), this.type === Types.IDENTITY || this.type === Types.SCALING ? this.type : undefined);\n    },\n    negate: function () {\n      return this.rowMajor(-this.m00(), -this.m01(), -this.m02(), -this.m10(), -this.m11(), -this.m12(), -this.m20(), -this.m21(), -this.m22());\n    },\n    invert: function () {\n      var det;\n      switch (this.type) {\n      case Types.IDENTITY:\n        return this;\n      case Types.TRANSLATION_2D:\n        return this.rowMajor(1, 0, -this.m02(), 0, 1, -this.m12(), 0, 0, 1, Types.TRANSLATION_2D);\n      case Types.SCALING:\n        return this.rowMajor(1 / this.m00(), 0, 0, 0, 1 / this.m11(), 0, 0, 0, 1 / this.m22(), Types.SCALING);\n      case Types.AFFINE:\n        det = this.getDeterminant();\n        if (det !== 0) {\n          return this.rowMajor((-this.m12() * this.m21() + this.m11() * this.m22()) / det, (this.m02() * this.m21() - this.m01() * this.m22()) / det, (-this.m02() * this.m11() + this.m01() * this.m12()) / det, (this.m12() * this.m20() - this.m10() * this.m22()) / det, (-this.m02() * this.m20() + this.m00() * this.m22()) / det, (this.m02() * this.m10() - this.m00() * this.m12()) / det, 0, 0, 1, Types.AFFINE);\n        } else {\n          throw new Error('Matrix could not be inverted, determinant === 0');\n        }\n        break;\n      case Types.OTHER:\n        det = this.getDeterminant();\n        if (det !== 0) {\n          return this.rowMajor((-this.m12() * this.m21() + this.m11() * this.m22()) / det, (this.m02() * this.m21() - this.m01() * this.m22()) / det, (-this.m02() * this.m11() + this.m01() * this.m12()) / det, (this.m12() * this.m20() - this.m10() * this.m22()) / det, (-this.m02() * this.m20() + this.m00() * this.m22()) / det, (this.m02() * this.m10() - this.m00() * this.m12()) / det, (-this.m11() * this.m20() + this.m10() * this.m21()) / det, (this.m01() * this.m20() - this.m00() * this.m21()) / det, (-this.m01() * this.m10() + this.m00() * this.m11()) / det, Types.OTHER);\n        } else {\n          throw new Error('Matrix could not be inverted, determinant === 0');\n        }\n        break;\n      default:\n        throw new Error('Matrix3.inverted with unknown type: ' + this.type);\n      }\n    },\n    multiplyMatrix: function (m) {\n      if (this.type === Types.IDENTITY || m.type === Types.IDENTITY) {\n        return this.type === Types.IDENTITY ? m : this;\n      }\n      if (this.type === m.type) {\n        if (this.type === Types.TRANSLATION_2D) {\n          return this.rowMajor(1, 0, this.m02() + m.m02(), 0, 1, this.m12() + m.m12(), 0, 0, 1, Types.TRANSLATION_2D);\n        } else if (this.type === Types.SCALING) {\n          return this.rowMajor(this.m00() * m.m00(), 0, 0, 0, this.m11() * m.m11(), 0, 0, 0, 1, Types.SCALING);\n        }\n      }\n      if (this.type !== Types.OTHER && m.type !== Types.OTHER) {\n        return this.rowMajor(this.m00() * m.m00() + this.m01() * m.m10(), this.m00() * m.m01() + this.m01() * m.m11(), this.m00() * m.m02() + this.m01() * m.m12() + this.m02(), this.m10() * m.m00() + this.m11() * m.m10(), this.m10() * m.m01() + this.m11() * m.m11(), this.m10() * m.m02() + this.m11() * m.m12() + this.m12(), 0, 0, 1, Types.AFFINE);\n      }\n      return this.rowMajor(this.m00() * m.m00() + this.m01() * m.m10() + this.m02() * m.m20(), this.m00() * m.m01() + this.m01() * m.m11() + this.m02() * m.m21(), this.m00() * m.m02() + this.m01() * m.m12() + this.m02() * m.m22(), this.m10() * m.m00() + this.m11() * m.m10() + this.m12() * m.m20(), this.m10() * m.m01() + this.m11() * m.m11() + this.m12() * m.m21(), this.m10() * m.m02() + this.m11() * m.m12() + this.m12() * m.m22(), this.m20() * m.m00() + this.m21() * m.m10() + this.m22() * m.m20(), this.m20() * m.m01() + this.m21() * m.m11() + this.m22() * m.m21(), this.m20() * m.m02() + this.m21() * m.m12() + this.m22() * m.m22());\n    },\n    multiplyVector2: function (v) {\n      var x = this.m00() * v.x + this.m01() * v.y + this.m02();\n      var y = this.m10() * v.x + this.m11() * v.y + this.m12();\n      v.setX(x);\n      v.setY(y);\n      return v;\n    },\n    multiplyVector3: function (v) {\n      var x = this.m00() * v.x + this.m01() * v.y + this.m02() * v.z;\n      var y = this.m10() * v.x + this.m11() * v.y + this.m12() * v.z;\n      var z = this.m20() * v.x + this.m21() * v.y + this.m22() * v.z;\n      v.setX(x);\n      v.setY(y);\n      v.setZ(z);\n      return v;\n    },\n    multiplyTransposeVector2: function (v) {\n      var x = this.m00() * v.x + this.m10() * v.y;\n      var y = this.m01() * v.x + this.m11() * v.y;\n      v.setX(x);\n      v.setY(y);\n      return v;\n    },\n    multiplyRelativeVector2: function (v) {\n      var x = this.m00() * v.x + this.m01() * v.y;\n      var y = this.m10() * v.y + this.m11() * v.y;\n      v.setX(x);\n      v.setY(y);\n      return v;\n    },\n    canvasSetTransform: function (context) {\n      context.setTransform(this.entries[0], this.entries[1], this.entries[3], this.entries[4], this.entries[6], this.entries[7]);\n    },\n    canvasAppendTransform: function (context) {\n      if (this.type !== Types.IDENTITY) {\n        context.transform(this.entries[0], this.entries[1], this.entries[3], this.entries[4], this.entries[6], this.entries[7]);\n      }\n    }\n  };\n  Matrix3.IDENTITY = new Matrix3(1, 0, 0, 0, 1, 0, 0, 0, 1, Types.IDENTITY);\n  Matrix3.IDENTITY.makeImmutable();\n  Matrix3.X_REFLECTION = new Matrix3(-1, 0, 0, 0, 1, 0, 0, 0, 1, Types.AFFINE);\n  Matrix3.X_REFLECTION.makeImmutable();\n  Matrix3.Y_REFLECTION = new Matrix3(1, 0, 0, 0, -1, 0, 0, 0, 1, Types.AFFINE);\n  Matrix3.Y_REFLECTION.makeImmutable();\n  Matrix3.translationTimesMatrix = function (x, y, m) {\n    var type;\n    if (m.type === Types.IDENTITY || m.type === Types.TRANSLATION_2D) {\n      return new Matrix3(1, 0, m.m02() + x, 0, 1, m.m12() + y, 0, 0, 1, Types.TRANSLATION_2D);\n    } else if (m.type === Types.OTHER) {\n      type = Types.OTHER;\n    } else {\n      type = Types.AFFINE;\n    }\n    return new Matrix3(m.m00(), m.m01(), m.m02() + x, m.m10(), m.m11(), m.m12() + y, m.m20(), m.m21(), m.m22(), type);\n  };\n  Matrix3.printer = {\n    print: function (matrix) {\n      console.log(matrix.toString());\n    }\n  };\n  return Matrix3;\n});",
    "\ndefine('DOT/Transform3',['require','DOT/dot','DOT/Matrix3','DOT/Vector2','DOT/Ray2'],function (require) {\n  'use strict';\n  var dot = require('DOT/dot');\n  require('DOT/Matrix3');\n  require('DOT/Vector2');\n  require('DOT/Ray2');\n  dot.Transform3 = function Transform3(matrix) {\n    this.listeners = [];\n    this.set(matrix === undefined ? dot.Matrix3.IDENTITY : matrix);\n    phetAllocation && phetAllocation('Transform3');\n  };\n  var Transform3 = dot.Transform3;\n  Transform3.prototype = {\n    constructor: Transform3,\n    set: function (matrix) {\n      null;\n      var oldMatrix = this.matrix;\n      var length = this.listeners.length;\n      var i;\n      for (i = 0; i < length; i++) {\n        this.listeners[i].before(matrix, oldMatrix);\n      }\n      this.matrix = matrix;\n      this.inverse = null;\n      this.matrixTransposed = null;\n      this.inverseTransposed = null;\n      for (i = 0; i < length; i++) {\n        this.listeners[i].after(matrix, oldMatrix);\n      }\n    },\n    prepend: function (matrix) {\n      this.set(matrix.timesMatrix(this.matrix));\n    },\n    prependTranslation: function (x, y) {\n      this.set(dot.Matrix3.translationTimesMatrix(x, y, this.matrix));\n    },\n    append: function (matrix) {\n      this.set(this.matrix.timesMatrix(matrix));\n    },\n    prependTransform: function (transform) {\n      this.prepend(transform.matrix);\n    },\n    appendTransform: function (transform) {\n      this.append(transform.matrix);\n    },\n    applyToCanvasContext: function (context) {\n      context.setTransform(this.matrix.m00(), this.matrix.m10(), this.matrix.m01(), this.matrix.m11(), this.matrix.m02(), this.matrix.m12());\n    },\n    copy: function () {\n      var transform = new Transform3(this.matrix);\n      transform.inverse = this.inverse;\n      transform.matrixTransposed = this.matrixTransposed;\n      transform.inverseTransposed = this.inverseTransposed;\n    },\n    deepCopy: function () {\n      var transform = new Transform3(this.matrix.copy());\n      transform.inverse = this.inverse ? this.inverse.copy() : null;\n      transform.matrixTransposed = this.matrixTransposed ? this.matrixTransposed.copy() : null;\n      transform.inverseTransposed = this.inverseTransposed ? this.inverseTransposed.copy() : null;\n    },\n    getMatrix: function () {\n      return this.matrix;\n    },\n    getInverse: function () {\n      if (this.inverse === null) {\n        this.inverse = this.matrix.inverted();\n      }\n      return this.inverse;\n    },\n    getMatrixTransposed: function () {\n      if (this.matrixTransposed === null) {\n        this.matrixTransposed = this.matrix.transposed();\n      }\n      return this.matrixTransposed;\n    },\n    getInverseTransposed: function () {\n      if (this.inverseTransposed === null) {\n        this.inverseTransposed = this.getInverse().transposed();\n      }\n      return this.inverseTransposed;\n    },\n    isIdentity: function () {\n      return this.matrix.type === dot.Matrix3.Types.IDENTITY;\n    },\n    isFinite: function () {\n      return this.matrix.isFinite();\n    },\n    transformPosition2: function (vec2) {\n      return this.matrix.timesVector2(vec2);\n    },\n    transformDelta2: function (vec2) {\n      var m = this.getMatrix();\n      return new dot.Vector2(m.m00() * vec2.x + m.m01() * vec2.y, m.m10() * vec2.x + m.m11() * vec2.y);\n    },\n    transformNormal2: function (vec2) {\n      return this.getInverse().timesTransposeVector2(vec2);\n    },\n    transformX: function (x) {\n      var m = this.getMatrix();\n      null;\n      return m.m00() * x + m.m02();\n    },\n    transformY: function (y) {\n      var m = this.getMatrix();\n      null;\n      return m.m11() * y + m.m12();\n    },\n    transformDeltaX: function (x) {\n      var m = this.getMatrix();\n      null;\n      return m.m00() * x;\n    },\n    transformDeltaY: function (y) {\n      var m = this.getMatrix();\n      null;\n      return m.m11() * y;\n    },\n    transformBounds2: function (bounds2) {\n      return bounds2.transformed(this.matrix);\n    },\n    transformShape: function (shape) {\n      return shape.transformed(this.matrix);\n    },\n    transformRay2: function (ray) {\n      return new dot.Ray2(this.transformPosition2(ray.pos), this.transformDelta2(ray.dir).normalized());\n    },\n    inversePosition2: function (vec2) {\n      return this.getInverse().timesVector2(vec2);\n    },\n    inverseDelta2: function (vec2) {\n      var m = this.getInverse();\n      return new dot.Vector2(m.m00() * vec2.x + m.m01() * vec2.y, m.m10() * vec2.x + m.m11() * vec2.y);\n    },\n    inverseNormal2: function (vec2) {\n      return this.matrix.timesTransposeVector2(vec2);\n    },\n    inverseX: function (x) {\n      var m = this.getInverse();\n      null;\n      return m.m00() * x + m.m02();\n    },\n    inverseY: function (y) {\n      var m = this.getInverse();\n      null;\n      return m.m11() * y + m.m12();\n    },\n    inverseDeltaX: function (x) {\n      var m = this.getInverse();\n      null;\n      return m.m00() * x;\n    },\n    inverseDeltaY: function (y) {\n      var m = this.getInverse();\n      null;\n      return m.m11() * y;\n    },\n    inverseBounds2: function (bounds2) {\n      return bounds2.transformed(this.getInverse());\n    },\n    inverseShape: function (shape) {\n      return shape.transformed(this.getInverse());\n    },\n    inverseRay2: function (ray) {\n      return new dot.Ray2(this.inversePosition2(ray.pos), this.inverseDelta2(ray.dir).normalized());\n    },\n    addTransformListener: function (listener) {\n      null;\n      this.listeners.push(listener);\n    },\n    prependTransformListener: function (listener) {\n      null;\n      this.listeners.unshift(listener);\n    },\n    removeTransformListener: function (listener) {\n      null;\n      this.listeners.splice(_.indexOf(this.listeners, listener), 1);\n    }\n  };\n  return Transform3;\n});",
    "\ndefine('KITE/segments/Segment',['require','KITE/kite','DOT/Util'],function (require) {\n  'use strict';\n  var kite = require('KITE/kite');\n  var DotUtil = require('DOT/Util');\n  kite.Segment = function Segment() {\n  };\n  var Segment = kite.Segment;\n  Segment.prototype = {\n    constructor: Segment,\n    subdivisions: function (tList, skipComputation) {\n      var right = this;\n      var result = [];\n      for (var i = 0; i < tList.length; i++) {\n        var t = tList[i];\n        var arr = right.subdivided(t, skipComputation);\n        null;\n        result.push(arr[0]);\n        right = arr[1];\n        for (var j = i + 1; j < tList.length; j++) {\n          tList[j] = DotUtil.linear(t, 1, 0, 1, tList[j]);\n        }\n      }\n      result.push(right);\n      return result;\n    },\n    subdividedIntoMonotone: function () {\n      return this.subdivisions(this.getInteriorExtremaTs());\n    }\n  };\n  return Segment;\n});",
    "\ndefine('KITE/segments/Line',['require','KITE/kite','PHET_CORE/inherit','DOT/Bounds2','DOT/Util','KITE/segments/Segment'],function (require) {\n  'use strict';\n  var kite = require('KITE/kite');\n  var inherit = require('PHET_CORE/inherit');\n  var Bounds2 = require('DOT/Bounds2');\n  var lineLineIntersection = require('DOT/Util').lineLineIntersection;\n  var Segment = require('KITE/segments/Segment');\n  Segment.Line = function Line(start, end) {\n    this.start = start;\n    this.end = end;\n    if (start.equals(end, 0)) {\n      this.invalid = true;\n      return;\n    }\n    this.startTangent = end.minus(start).normalized();\n    this.endTangent = this.startTangent;\n    this.bounds = Bounds2.NOTHING.withPoint(start).withPoint(end);\n  };\n  inherit(Segment, Segment.Line, {\n    positionAt: function (t) {\n      return this.start.plus(this.end.minus(this.start).times(t));\n    },\n    tangentAt: function (t) {\n      return this.startTangent;\n    },\n    curvatureAt: function (t) {\n      return 0;\n    },\n    getSVGPathFragment: function () {\n      return 'L ' + this.end.x + ' ' + this.end.y;\n    },\n    strokeLeft: function (lineWidth) {\n      var offset = this.endTangent.perpendicular().negated().times(lineWidth / 2);\n      return [new Segment.Line(this.start.plus(offset), this.end.plus(offset))];\n    },\n    strokeRight: function (lineWidth) {\n      var offset = this.startTangent.perpendicular().times(lineWidth / 2);\n      return [new Segment.Line(this.end.plus(offset), this.start.plus(offset))];\n    },\n    getInteriorExtremaTs: function () {\n      return [];\n    },\n    subdivided: function (t) {\n      var pt = this.positionAt(t);\n      return [\n        new Segment.Line(this.start, pt),\n        new Segment.Line(pt, this.end)\n      ];\n    },\n    intersectsBounds: function (bounds) {\n      throw new Error('Segment.Line.intersectsBounds unimplemented');\n    },\n    intersection: function (ray) {\n      var result = [];\n      var start = this.start;\n      var end = this.end;\n      var intersection = lineLineIntersection(start, end, ray.pos, ray.pos.plus(ray.dir));\n      if (!isFinite(intersection.x) || !isFinite(intersection.y)) {\n        return result;\n      }\n      if (start.x !== end.x && (start.x > end.x ? intersection.x >= start.x || intersection.x < end.x : intersection.x <= start.x || intersection.x > end.x)) {\n        return result;\n      }\n      if (start.y !== end.y && (start.y > end.y ? intersection.y >= start.y || intersection.y < end.y : intersection.y <= start.y || intersection.y > end.y)) {\n        return result;\n      }\n      var t = intersection.minus(ray.pos).dot(ray.dir);\n      if (t < 0) {\n        return result;\n      }\n      var diff = end.minus(start);\n      var perp = diff.perpendicular();\n      result.push({\n        distance: t,\n        point: ray.pointAtDistance(t),\n        normal: perp.dot(ray.dir) > 0 ? perp.negated() : perp,\n        wind: ray.dir.perpendicular().dot(diff) < 0 ? 1 : -1\n      });\n      return result;\n    },\n    windingIntersection: function (ray) {\n      var hits = this.intersection(ray);\n      if (hits.length) {\n        return hits[0].wind;\n      } else {\n        return 0;\n      }\n    },\n    writeToContext: function (context) {\n      context.lineTo(this.end.x, this.end.y);\n    },\n    transformed: function (matrix) {\n      return new Segment.Line(matrix.timesVector2(this.start), matrix.timesVector2(this.end));\n    }\n  });\n  return Segment.Line;\n});",
    "\ndefine('KITE/segments/Arc',['require','KITE/kite','PHET_CORE/inherit','DOT/Vector2','DOT/Bounds2','DOT/Util','KITE/segments/Segment'],function (require) {\n  'use strict';\n  var kite = require('KITE/kite');\n  var inherit = require('PHET_CORE/inherit');\n  var Vector2 = require('DOT/Vector2');\n  var Bounds2 = require('DOT/Bounds2');\n  var DotUtil = require('DOT/Util');\n  var Segment = require('KITE/segments/Segment');\n  Segment.Arc = function Arc(center, radius, startAngle, endAngle, anticlockwise) {\n    if (radius < 0) {\n      radius = -radius;\n      startAngle += Math.PI;\n      endAngle += Math.PI;\n    }\n    this.center = center;\n    this.radius = radius;\n    this.startAngle = startAngle;\n    this.endAngle = endAngle;\n    this.anticlockwise = anticlockwise;\n    this.start = this.positionAtAngle(startAngle);\n    this.end = this.positionAtAngle(endAngle);\n    this.startTangent = this.tangentAtAngle(startAngle);\n    this.endTangent = this.tangentAtAngle(endAngle);\n    if (radius <= 0 || startAngle === endAngle) {\n      this.invalid = true;\n      return;\n    }\n    if (this.anticlockwise) {\n      if (this.startAngle > this.endAngle) {\n        this.actualEndAngle = this.endAngle;\n      } else if (this.startAngle < this.endAngle) {\n        this.actualEndAngle = this.endAngle - 2 * Math.PI;\n      } else {\n        this.actualEndAngle = this.startAngle;\n      }\n    } else {\n      if (this.startAngle < this.endAngle) {\n        this.actualEndAngle = this.endAngle;\n      } else if (this.startAngle > this.endAngle) {\n        this.actualEndAngle = this.endAngle + Math.PI * 2;\n      } else {\n        this.actualEndAngle = this.startAngle;\n      }\n    }\n    null;\n    null;\n    var isFullPerimeter = !anticlockwise && endAngle - startAngle >= Math.PI * 2 || anticlockwise && startAngle - endAngle >= Math.PI * 2;\n    this.angleDifference = this.anticlockwise ? this.startAngle - this.endAngle : this.endAngle - this.startAngle;\n    if (this.angleDifference < 0) {\n      this.angleDifference += Math.PI * 2;\n    }\n    null;\n    this.bounds = Bounds2.NOTHING;\n    this.bounds = this.bounds.withPoint(this.start);\n    this.bounds = this.bounds.withPoint(this.end);\n    var that = this;\n    function boundsAtAngle(angle) {\n      if (that.containsAngle(angle)) {\n        that.bounds = that.bounds.withPoint(center.plus(Vector2.createPolar(radius, angle)));\n      }\n    }\n    if (startAngle !== endAngle) {\n      boundsAtAngle(0);\n      boundsAtAngle(Math.PI / 2);\n      boundsAtAngle(Math.PI);\n      boundsAtAngle(3 * Math.PI / 2);\n    }\n  };\n  inherit(Segment, Segment.Arc, {\n    mapAngle: function (angle) {\n      return this.startAngle > this.actualEndAngle ? DotUtil.moduloBetweenUp(angle, this.startAngle - 2 * Math.PI, this.startAngle) : DotUtil.moduloBetweenDown(angle, this.startAngle, this.startAngle + 2 * Math.PI);\n    },\n    tAtAngle: function (angle) {\n      return (this.mapAngle(angle) - this.startAngle) / (this.actualEndAngle - this.startAngle);\n    },\n    angleAt: function (t) {\n      return this.startAngle + (this.actualEndAngle - this.startAngle) * t;\n    },\n    positionAt: function (t) {\n      return this.positionAtAngle(this.angleAt(t));\n    },\n    tangentAt: function (t) {\n      return this.tangentAtAngle(this.angleAt(t));\n    },\n    curvatureAt: function (t) {\n      return (this.anticlockwise ? -1 : 1) / this.radius;\n    },\n    positionAtAngle: function (angle) {\n      return this.center.plus(Vector2.createPolar(this.radius, angle));\n    },\n    tangentAtAngle: function (angle) {\n      var normal = Vector2.createPolar(1, angle);\n      return this.anticlockwise ? normal.perpendicular() : normal.perpendicular().negated();\n    },\n    containsAngle: function (angle) {\n      var normalizedAngle = this.anticlockwise ? angle - this.endAngle : angle - this.startAngle;\n      var positiveMinAngle = DotUtil.moduloBetweenDown(normalizedAngle, 0, Math.PI * 2);\n      return positiveMinAngle <= this.angleDifference;\n    },\n    getSVGPathFragment: function () {\n      var epsilon = 0.01;\n      var sweepFlag = this.anticlockwise ? '0' : '1';\n      var largeArcFlag;\n      if (this.angleDifference < Math.PI * 2 - epsilon) {\n        largeArcFlag = this.angleDifference < Math.PI ? '0' : '1';\n        return 'A ' + this.radius + ' ' + this.radius + ' 0 ' + largeArcFlag + ' ' + sweepFlag + ' ' + this.end.x + ' ' + this.end.y;\n      } else {\n        var splitOppositeAngle = (this.startAngle + this.endAngle) / 2;\n        var splitPoint = this.center.plus(Vector2.createPolar(this.radius, splitOppositeAngle));\n        largeArcFlag = '0';\n        var firstArc = 'A ' + this.radius + ' ' + this.radius + ' 0 ' + largeArcFlag + ' ' + sweepFlag + ' ' + splitPoint.x + ' ' + splitPoint.y;\n        var secondArc = 'A ' + this.radius + ' ' + this.radius + ' 0 ' + largeArcFlag + ' ' + sweepFlag + ' ' + this.end.x + ' ' + this.end.y;\n        return firstArc + ' ' + secondArc;\n      }\n    },\n    strokeLeft: function (lineWidth) {\n      return [new Segment.Arc(this.center, this.radius + (this.anticlockwise ? 1 : -1) * lineWidth / 2, this.startAngle, this.endAngle, this.anticlockwise)];\n    },\n    strokeRight: function (lineWidth) {\n      return [new Segment.Arc(this.center, this.radius + (this.anticlockwise ? -1 : 1) * lineWidth / 2, this.endAngle, this.startAngle, !this.anticlockwise)];\n    },\n    getInteriorExtremaTs: function () {\n      var that = this;\n      var result = [];\n      _.each([\n        0,\n        Math.PI / 2,\n        Math.PI,\n        3 * Math.PI / 2\n      ], function (angle) {\n        if (that.containsAngle(angle)) {\n          var t = that.tAtAngle(angle);\n          var epsilon = 1e-10;\n          if (t > epsilon && t < 1 - epsilon) {\n            result.push(t);\n          }\n        }\n      });\n      return result.sort();\n    },\n    subdivided: function (t) {\n      var angle0 = this.angleAt(0);\n      var angleT = this.angleAt(t);\n      var angle1 = this.angleAt(1);\n      return [\n        new Segment.Arc(this.center, this.radius, angle0, angleT, this.anticlockwise),\n        new Segment.Arc(this.center, this.radius, angleT, angle1, this.anticlockwise)\n      ];\n    },\n    intersectsBounds: function (bounds) {\n      throw new Error('Segment.intersectsBounds unimplemented!');\n    },\n    intersection: function (ray) {\n      var result = [];\n      var epsilon = 0;\n      var centerToRay = ray.pos.minus(this.center);\n      var tmp = ray.dir.dot(centerToRay);\n      var centerToRayDistSq = centerToRay.magnitudeSquared();\n      var discriminant = 4 * tmp * tmp - 4 * (centerToRayDistSq - this.radius * this.radius);\n      if (discriminant < epsilon) {\n        return result;\n      }\n      var base = ray.dir.dot(this.center) - ray.dir.dot(ray.pos);\n      var sqt = Math.sqrt(discriminant) / 2;\n      var ta = base - sqt;\n      var tb = base + sqt;\n      if (tb < epsilon) {\n        return result;\n      }\n      var pointB = ray.pointAtDistance(tb);\n      var normalB = pointB.minus(this.center).normalized();\n      if (ta < epsilon) {\n        if (this.containsAngle(normalB.angle())) {\n          result.push({\n            distance: tb,\n            point: pointB,\n            normal: normalB.negated(),\n            wind: this.anticlockwise ? -1 : 1\n          });\n        }\n      } else {\n        var pointA = ray.pointAtDistance(ta);\n        var normalA = pointA.minus(this.center).normalized();\n        if (this.containsAngle(normalA.angle())) {\n          result.push({\n            distance: ta,\n            point: pointA,\n            normal: normalA,\n            wind: this.anticlockwise ? 1 : -1\n          });\n        }\n        if (this.containsAngle(normalB.angle())) {\n          result.push({\n            distance: tb,\n            point: pointB,\n            normal: normalB.negated(),\n            wind: this.anticlockwise ? -1 : 1\n          });\n        }\n      }\n      return result;\n    },\n    windingIntersection: function (ray) {\n      var wind = 0;\n      var hits = this.intersection(ray);\n      _.each(hits, function (hit) {\n        wind += hit.wind;\n      });\n      return wind;\n    },\n    writeToContext: function (context) {\n      context.arc(this.center.x, this.center.y, this.radius, this.startAngle, this.endAngle, this.anticlockwise);\n    },\n    transformed: function (matrix) {\n      var startAngle = matrix.timesVector2(Vector2.createPolar(1, this.startAngle)).minus(matrix.timesVector2(Vector2.ZERO)).angle();\n      var endAngle = matrix.timesVector2(Vector2.createPolar(1, this.endAngle)).minus(matrix.timesVector2(Vector2.ZERO)).angle();\n      var anticlockwise = matrix.getDeterminant() >= 0 ? this.anticlockwise : !this.anticlockwise;\n      var scaleVector = matrix.getScaleVector();\n      if (scaleVector.x !== scaleVector.y) {\n        var radiusX = scaleVector.x * this.radius;\n        var radiusY = scaleVector.y * this.radius;\n        return new Segment.EllipticalArc(matrix.timesVector2(this.center), radiusX, radiusY, 0, startAngle, endAngle, anticlockwise);\n      } else {\n        var radius = scaleVector.x * this.radius;\n        return new Segment.Arc(matrix.timesVector2(this.center), radius, startAngle, endAngle, anticlockwise);\n      }\n    }\n  });\n  return Segment.Arc;\n});",
    "\ndefine('KITE/util/Subpath',['require','DOT/Vector2','DOT/Bounds2','DOT/Util','KITE/kite','KITE/segments/Line','KITE/segments/Arc'],function (require) {\n  'use strict';\n  var Vector2 = require('DOT/Vector2');\n  var Bounds2 = require('DOT/Bounds2');\n  var lineLineIntersection = require('DOT/Util').lineLineIntersection;\n  var kite = require('KITE/kite');\n  require('KITE/segments/Line');\n  require('KITE/segments/Arc');\n  kite.Subpath = function Subpath(segments, points, closed) {\n    this.segments = segments || [];\n    this.points = points || (segments && segments.length ? _.map(segments, function (segment) {\n      return segment.start;\n    }).concat(segments[segments.length - 1].end) : []);\n    this.closed = !!closed;\n    this._strokedSubpaths = null;\n    this._strokedSubpathsComputed = false;\n    this._strokedStyles = null;\n  };\n  var Subpath = kite.Subpath;\n  Subpath.prototype = {\n    copy: function () {\n      return new Subpath(this.segments.slice(0), this.points.slice(0), this.closed);\n    },\n    invalidate: function () {\n      this._strokedSubpathsComputed = false;\n    },\n    addPoint: function (point) {\n      this.points.push(point);\n      return this;\n    },\n    addSegment: function (segment) {\n      if (!segment.invalid) {\n        null;\n        null;\n        null;\n        null;\n        null;\n        this.segments.push(segment);\n        this.invalidate();\n      }\n      return this;\n    },\n    close: function () {\n      this.closed = true;\n    },\n    getLength: function () {\n      return this.points.length;\n    },\n    getFirstPoint: function () {\n      return _.first(this.points);\n    },\n    getLastPoint: function () {\n      return _.last(this.points);\n    },\n    getFirstSegment: function () {\n      return _.first(this.segments);\n    },\n    getLastSegment: function () {\n      return _.last(this.segments);\n    },\n    isDrawable: function () {\n      return this.segments.length > 0;\n    },\n    isClosed: function () {\n      return this.closed;\n    },\n    hasClosingSegment: function () {\n      return !this.getFirstPoint().equalsEpsilon(this.getLastPoint(), 1e-9);\n    },\n    getClosingSegment: function () {\n      null;\n      return new kite.Segment.Line(this.getLastPoint(), this.getFirstPoint());\n    },\n    writeToContext: function (context) {\n      if (this.isDrawable()) {\n        var startPoint = this.getFirstSegment().start;\n        context.moveTo(startPoint.x, startPoint.y);\n        var len = this.segments.length;\n        for (var i = 0; i < len; i++) {\n          this.segments[i].writeToContext(context);\n        }\n        if (this.closed) {\n          context.closePath();\n        }\n      }\n    },\n    transformed: function (matrix) {\n      return new Subpath(_.map(this.segments, function (segment) {\n        return segment.transformed(matrix);\n      }), _.map(this.points, function (point) {\n        return matrix.timesVector2(point);\n      }), this.closed);\n    },\n    computeBounds: function () {\n      var bounds = Bounds2.NOTHING.copy();\n      var len = this.segments.length;\n      for (var i = 0; i < len; i++) {\n        bounds.includeBounds(this.segments[i].bounds);\n      }\n      return bounds;\n    },\n    stroked: function (lineStyles) {\n      if (!this.isDrawable()) {\n        return [];\n      }\n      if (lineStyles === undefined) {\n        lineStyles = new kite.LineStyles();\n      }\n      if (this._strokedSubpathsComputed && this._strokedStyles.equals(lineStyles)) {\n        return this._strokedSubpaths;\n      }\n      var lineWidth = lineStyles.lineWidth;\n      function join(center, fromTangent, toTangent) {\n        var fromPoint = center.plus(fromTangent.perpendicular().negated().times(lineWidth / 2));\n        var toPoint = center.plus(toTangent.perpendicular().negated().times(lineWidth / 2));\n        var bevel = fromPoint.equals(toPoint) ? [] : [new kite.Segment.Line(fromPoint, toPoint)];\n        if (fromTangent.perpendicular().dot(toTangent) > 0) {\n          switch (lineStyles.lineJoin) {\n          case 'round':\n            var fromAngle = fromTangent.angle() + Math.PI / 2;\n            var toAngle = toTangent.angle() + Math.PI / 2;\n            return [new kite.Segment.Arc(center, lineWidth / 2, fromAngle, toAngle, true)];\n          case 'miter':\n            var theta = fromTangent.angleBetween(toTangent.negated());\n            var notStraight = theta < Math.PI - 0.00001;\n            if (1 / Math.sin(theta / 2) <= lineStyles.miterLimit && theta < Math.PI - 0.00001) {\n              var miterPoint = lineLineIntersection(fromPoint, fromPoint.plus(fromTangent), toPoint, toPoint.plus(toTangent));\n              return [\n                new kite.Segment.Line(fromPoint, miterPoint),\n                new kite.Segment.Line(miterPoint, toPoint)\n              ];\n            } else {\n              return bevel;\n            }\n            break;\n          case 'bevel':\n            return bevel;\n          }\n        } else {\n          return bevel;\n        }\n      }\n      function cap(center, tangent) {\n        var fromPoint = center.plus(tangent.perpendicular().times(-lineWidth / 2));\n        var toPoint = center.plus(tangent.perpendicular().times(lineWidth / 2));\n        switch (lineStyles.lineCap) {\n        case 'butt':\n          return [new kite.Segment.Line(fromPoint, toPoint)];\n        case 'round':\n          var tangentAngle = tangent.angle();\n          return [new kite.Segment.Arc(center, lineWidth / 2, tangentAngle + Math.PI / 2, tangentAngle - Math.PI / 2, true)];\n        case 'square':\n          var toLeft = tangent.perpendicular().negated().times(lineWidth / 2);\n          var toRight = tangent.perpendicular().times(lineWidth / 2);\n          var toFront = tangent.times(lineWidth / 2);\n          var left = center.plus(toLeft).plus(toFront);\n          var right = center.plus(toRight).plus(toFront);\n          return [\n            new kite.Segment.Line(fromPoint, left),\n            new kite.Segment.Line(left, right),\n            new kite.Segment.Line(right, toPoint)\n          ];\n        }\n      }\n      var i;\n      var leftSegments = [];\n      var rightSegments = [];\n      var firstSegment = this.getFirstSegment();\n      var lastSegment = this.getLastSegment();\n      function addLeftSegments(segments) {\n        leftSegments = leftSegments.concat(segments);\n      }\n      function addRightSegments(segments) {\n        rightSegments = rightSegments.concat(segments);\n      }\n      var alreadyClosed = lastSegment.end.equals(firstSegment.start);\n      var closingSegment = alreadyClosed ? null : new kite.Segment.Line(this.segments[this.segments.length - 1].end, this.segments[0].start);\n      for (i = 0; i < this.segments.length; i++) {\n        if (i > 0) {\n          addLeftSegments(join(this.segments[i].start, this.segments[i - 1].endTangent, this.segments[i].startTangent, true));\n        }\n        addLeftSegments(this.segments[i].strokeLeft(lineWidth));\n      }\n      for (i = this.segments.length - 1; i >= 0; i--) {\n        if (i < this.segments.length - 1) {\n          addRightSegments(join(this.segments[i].end, this.segments[i + 1].startTangent.negated(), this.segments[i].endTangent.negated(), false));\n        }\n        addRightSegments(this.segments[i].strokeRight(lineWidth));\n      }\n      var subpaths;\n      if (this.closed) {\n        if (alreadyClosed) {\n          addLeftSegments(join(lastSegment.end, lastSegment.endTangent, firstSegment.startTangent));\n          addRightSegments(join(lastSegment.end, firstSegment.startTangent.negated(), lastSegment.endTangent.negated()));\n        } else {\n          addLeftSegments(join(closingSegment.start, lastSegment.endTangent, closingSegment.startTangent));\n          addLeftSegments(closingSegment.strokeLeft(lineWidth));\n          addLeftSegments(join(closingSegment.end, closingSegment.endTangent, firstSegment.startTangent));\n          addRightSegments(join(closingSegment.end, firstSegment.startTangent.negated(), closingSegment.endTangent.negated()));\n          addRightSegments(closingSegment.strokeRight(lineWidth));\n          addRightSegments(join(closingSegment.start, closingSegment.startTangent.negated(), lastSegment.endTangent.negated()));\n        }\n        subpaths = [\n          new Subpath(leftSegments, null, true),\n          new Subpath(rightSegments, null, true)\n        ];\n      } else {\n        subpaths = [new Subpath(leftSegments.concat(cap(lastSegment.end, lastSegment.endTangent)).concat(rightSegments).concat(cap(firstSegment.start, firstSegment.startTangent.negated())), null, true)];\n      }\n      this._strokedSubpaths = subpaths;\n      this._strokedSubpathsComputed = true;\n      this._strokedStyles = new kite.LineStyles(lineStyles);\n      return subpaths;\n    }\n  };\n  function segmentStartLeft(segment, lineWidth) {\n    null;\n    return segment.start.plus(segment.startTangent.perpendicular().negated().times(lineWidth / 2));\n  }\n  function segmentEndLeft(segment, lineWidth) {\n    null;\n    return segment.end.plus(segment.endTangent.perpendicular().negated().times(lineWidth / 2));\n  }\n  function segmentStartRight(segment, lineWidth) {\n    null;\n    return segment.start.plus(segment.startTangent.perpendicular().times(lineWidth / 2));\n  }\n  function segmentEndRight(segment, lineWidth) {\n    null;\n    return segment.end.plus(segment.endTangent.perpendicular().times(lineWidth / 2));\n  }\n  return kite.Subpath;\n});",
    "\ndefine('KITE/../parser/svgPath',['require','KITE/kite'],function (require) {\n  var kite = require('KITE/kite');\n  function quote(s) {\n    return '\"' + s.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"').replace(/\\x08/g, '\\\\b').replace(/\\t/g, '\\\\t').replace(/\\n/g, '\\\\n').replace(/\\f/g, '\\\\f').replace(/\\r/g, '\\\\r').replace(/[\\x00-\\x07\\x0B\\x0E-\\x1F\\x80-\\uFFFF]/g, escape) + '\"';\n  }\n  kite.svgPath = {\n    parse: function (input, startRule) {\n      var parseFunctions = {\n          'svgPath': parse_svgPath,\n          'movetoDrawtoCommandGroups': parse_movetoDrawtoCommandGroups,\n          'movetoDrawtoCommandGroup': parse_movetoDrawtoCommandGroup,\n          'drawtoCommands': parse_drawtoCommands,\n          'drawtoCommand': parse_drawtoCommand,\n          'moveto': parse_moveto,\n          'movetoArgumentSequence': parse_movetoArgumentSequence,\n          'closepath': parse_closepath,\n          'lineto': parse_lineto,\n          'linetoArgumentSequence': parse_linetoArgumentSequence,\n          'horizontalLineto': parse_horizontalLineto,\n          'horizontalLinetoArgumentSequence': parse_horizontalLinetoArgumentSequence,\n          'verticalLineto': parse_verticalLineto,\n          'verticalLinetoArgumentSequence': parse_verticalLinetoArgumentSequence,\n          'curveto': parse_curveto,\n          'curvetoArgumentSequence': parse_curvetoArgumentSequence,\n          'curvetoArgument': parse_curvetoArgument,\n          'smoothCurveto': parse_smoothCurveto,\n          'smoothCurvetoArgumentSequence': parse_smoothCurvetoArgumentSequence,\n          'smoothCurvetoArgument': parse_smoothCurvetoArgument,\n          'quadraticBezierCurveto': parse_quadraticBezierCurveto,\n          'quadraticBezierCurvetoArgumentSequence': parse_quadraticBezierCurvetoArgumentSequence,\n          'quadraticBezierCurvetoArgument': parse_quadraticBezierCurvetoArgument,\n          'smoothQuadraticBezierCurveto': parse_smoothQuadraticBezierCurveto,\n          'smoothQuadraticBezierCurvetoArgumentSequence': parse_smoothQuadraticBezierCurvetoArgumentSequence,\n          'ellipticalArc': parse_ellipticalArc,\n          'ellipticalArcArgumentSequence': parse_ellipticalArcArgumentSequence,\n          'ellipticalArcArgument': parse_ellipticalArcArgument,\n          'coordinatePair': parse_coordinatePair,\n          'nonnegativeNumber': parse_nonnegativeNumber,\n          'number': parse_number,\n          'flag': parse_flag,\n          'commaWsp': parse_commaWsp,\n          'comma': parse_comma,\n          'floatingPointConstant': parse_floatingPointConstant,\n          'fractionalConstant': parse_fractionalConstant,\n          'exponent': parse_exponent,\n          'sign': parse_sign,\n          'digitSequence': parse_digitSequence,\n          'digit': parse_digit,\n          'wsp': parse_wsp\n        };\n      if (startRule !== undefined) {\n        if (parseFunctions[startRule] === undefined) {\n          throw new Error('Invalid rule name: ' + quote(startRule) + '.');\n        }\n      } else {\n        startRule = 'svgPath';\n      }\n      var pos = 0;\n      var reportFailures = 0;\n      var rightmostFailuresPos = 0;\n      var rightmostFailuresExpected = [];\n      function padLeft(input, padding, length) {\n        var result = input;\n        var padLength = length - input.length;\n        for (var i = 0; i < padLength; i++) {\n          result = padding + result;\n        }\n        return result;\n      }\n      function escape(ch) {\n        var charCode = ch.charCodeAt(0);\n        var escapeChar;\n        var length;\n        if (charCode <= 255) {\n          escapeChar = 'x';\n          length = 2;\n        } else {\n          escapeChar = 'u';\n          length = 4;\n        }\n        return '\\\\' + escapeChar + padLeft(charCode.toString(16).toUpperCase(), '0', length);\n      }\n      function matchFailed(failure) {\n        if (pos < rightmostFailuresPos) {\n          return;\n        }\n        if (pos > rightmostFailuresPos) {\n          rightmostFailuresPos = pos;\n          rightmostFailuresExpected = [];\n        }\n        rightmostFailuresExpected.push(failure);\n      }\n      function parse_svgPath() {\n        var result0, result1, result2, result3;\n        var pos0, pos1;\n        pos0 = pos;\n        pos1 = pos;\n        result0 = [];\n        result1 = parse_wsp();\n        while (result1 !== null) {\n          result0.push(result1);\n          result1 = parse_wsp();\n        }\n        if (result0 !== null) {\n          result1 = parse_movetoDrawtoCommandGroups();\n          result1 = result1 !== null ? result1 : '';\n          if (result1 !== null) {\n            result2 = [];\n            result3 = parse_wsp();\n            while (result3 !== null) {\n              result2.push(result3);\n              result3 = parse_wsp();\n            }\n            if (result2 !== null) {\n              result0 = [\n                result0,\n                result1,\n                result2\n              ];\n            } else {\n              result0 = null;\n              pos = pos1;\n            }\n          } else {\n            result0 = null;\n            pos = pos1;\n          }\n        } else {\n          result0 = null;\n          pos = pos1;\n        }\n        if (result0 !== null) {\n          result0 = function (offset, path) {\n            return path ? path : [];\n          }(pos0, result0[1]);\n        }\n        if (result0 === null) {\n          pos = pos0;\n        }\n        return result0;\n      }\n      function parse_movetoDrawtoCommandGroups() {\n        var result0, result1, result2;\n        var pos0, pos1;\n        pos0 = pos;\n        pos1 = pos;\n        result0 = parse_movetoDrawtoCommandGroup();\n        if (result0 !== null) {\n          result1 = [];\n          result2 = parse_wsp();\n          while (result2 !== null) {\n            result1.push(result2);\n            result2 = parse_wsp();\n          }\n          if (result1 !== null) {\n            result2 = parse_movetoDrawtoCommandGroups();\n            if (result2 !== null) {\n              result0 = [\n                result0,\n                result1,\n                result2\n              ];\n            } else {\n              result0 = null;\n              pos = pos1;\n            }\n          } else {\n            result0 = null;\n            pos = pos1;\n          }\n        } else {\n          result0 = null;\n          pos = pos1;\n        }\n        if (result0 !== null) {\n          result0 = function (offset, a, b) {\n            return a.concat(b);\n          }(pos0, result0[0], result0[2]);\n        }\n        if (result0 === null) {\n          pos = pos0;\n        }\n        if (result0 === null) {\n          pos0 = pos;\n          result0 = parse_movetoDrawtoCommandGroup();\n          if (result0 !== null) {\n            result0 = function (offset, a) {\n              return a;\n            }(pos0, result0);\n          }\n          if (result0 === null) {\n            pos = pos0;\n          }\n        }\n        return result0;\n      }\n      function parse_movetoDrawtoCommandGroup() {\n        var result0, result1, result2;\n        var pos0, pos1;\n        pos0 = pos;\n        pos1 = pos;\n        result0 = parse_moveto();\n        if (result0 !== null) {\n          result1 = [];\n          result2 = parse_wsp();\n          while (result2 !== null) {\n            result1.push(result2);\n            result2 = parse_wsp();\n          }\n          if (result1 !== null) {\n            result2 = parse_drawtoCommands();\n            result2 = result2 !== null ? result2 : '';\n            if (result2 !== null) {\n              result0 = [\n                result0,\n                result1,\n                result2\n              ];\n            } else {\n              result0 = null;\n              pos = pos1;\n            }\n          } else {\n            result0 = null;\n            pos = pos1;\n          }\n        } else {\n          result0 = null;\n          pos = pos1;\n        }\n        if (result0 !== null) {\n          result0 = function (offset, m, c) {\n            return c.length ? m.concat(c) : m;\n          }(pos0, result0[0], result0[2]);\n        }\n        if (result0 === null) {\n          pos = pos0;\n        }\n        return result0;\n      }\n      function parse_drawtoCommands() {\n        var result0, result1, result2;\n        var pos0, pos1;\n        pos0 = pos;\n        pos1 = pos;\n        result0 = parse_drawtoCommand();\n        if (result0 !== null) {\n          result1 = [];\n          result2 = parse_wsp();\n          while (result2 !== null) {\n            result1.push(result2);\n            result2 = parse_wsp();\n          }\n          if (result1 !== null) {\n            result2 = parse_drawtoCommands();\n            if (result2 !== null) {\n              result0 = [\n                result0,\n                result1,\n                result2\n              ];\n            } else {\n              result0 = null;\n              pos = pos1;\n            }\n          } else {\n            result0 = null;\n            pos = pos1;\n          }\n        } else {\n          result0 = null;\n          pos = pos1;\n        }\n        if (result0 !== null) {\n          result0 = function (offset, cmd, cmds) {\n            return cmd.concat(cmds);\n          }(pos0, result0[0], result0[2]);\n        }\n        if (result0 === null) {\n          pos = pos0;\n        }\n        if (result0 === null) {\n          pos0 = pos;\n          result0 = parse_drawtoCommand();\n          if (result0 !== null) {\n            result0 = function (offset, cmd) {\n              return cmd;\n            }(pos0, result0);\n          }\n          if (result0 === null) {\n            pos = pos0;\n          }\n        }\n        return result0;\n      }\n      function parse_drawtoCommand() {\n        var result0;\n        result0 = parse_closepath();\n        if (result0 === null) {\n          result0 = parse_lineto();\n          if (result0 === null) {\n            result0 = parse_horizontalLineto();\n            if (result0 === null) {\n              result0 = parse_verticalLineto();\n              if (result0 === null) {\n                result0 = parse_curveto();\n                if (result0 === null) {\n                  result0 = parse_smoothCurveto();\n                  if (result0 === null) {\n                    result0 = parse_quadraticBezierCurveto();\n                    if (result0 === null) {\n                      result0 = parse_smoothQuadraticBezierCurveto();\n                      if (result0 === null) {\n                        result0 = parse_ellipticalArc();\n                      }\n                    }\n                  }\n                }\n              }\n            }\n          }\n        }\n        return result0;\n      }\n      function parse_moveto() {\n        var result0, result1, result2;\n        var pos0, pos1;\n        pos0 = pos;\n        pos1 = pos;\n        if (input.charCodeAt(pos) === 77) {\n          result0 = 'M';\n          pos++;\n        } else {\n          result0 = null;\n          if (reportFailures === 0) {\n            matchFailed('\"M\"');\n          }\n        }\n        if (result0 !== null) {\n          result1 = [];\n          result2 = parse_wsp();\n          while (result2 !== null) {\n            result1.push(result2);\n            result2 = parse_wsp();\n          }\n          if (result1 !== null) {\n            result2 = parse_movetoArgumentSequence();\n            if (result2 !== null) {\n              result0 = [\n                result0,\n                result1,\n                result2\n              ];\n            } else {\n              result0 = null;\n              pos = pos1;\n            }\n          } else {\n            result0 = null;\n            pos = pos1;\n          }\n        } else {\n          result0 = null;\n          pos = pos1;\n        }\n        if (result0 !== null) {\n          result0 = function (offset, args) {\n            return createMoveTo(args, false);\n          }(pos0, result0[2]);\n        }\n        if (result0 === null) {\n          pos = pos0;\n        }\n        if (result0 === null) {\n          pos0 = pos;\n          pos1 = pos;\n          if (input.charCodeAt(pos) === 109) {\n            result0 = 'm';\n            pos++;\n          } else {\n            result0 = null;\n            if (reportFailures === 0) {\n              matchFailed('\"m\"');\n            }\n          }\n          if (result0 !== null) {\n            result1 = [];\n            result2 = parse_wsp();\n            while (result2 !== null) {\n              result1.push(result2);\n              result2 = parse_wsp();\n            }\n            if (result1 !== null) {\n              result2 = parse_movetoArgumentSequence();\n              if (result2 !== null) {\n                result0 = [\n                  result0,\n                  result1,\n                  result2\n                ];\n              } else {\n                result0 = null;\n                pos = pos1;\n              }\n            } else {\n              result0 = null;\n              pos = pos1;\n            }\n          } else {\n            result0 = null;\n            pos = pos1;\n          }\n          if (result0 !== null) {\n            result0 = function (offset, args) {\n              return createMoveTo(args, true);\n            }(pos0, result0[2]);\n          }\n          if (result0 === null) {\n            pos = pos0;\n          }\n        }\n        return result0;\n      }\n      function parse_movetoArgumentSequence() {\n        var result0, result1, result2;\n        var pos0, pos1;\n        pos0 = pos;\n        pos1 = pos;\n        result0 = parse_coordinatePair();\n        if (result0 !== null) {\n          result1 = parse_commaWsp();\n          result1 = result1 !== null ? result1 : '';\n          if (result1 !== null) {\n            result2 = parse_linetoArgumentSequence();\n            if (result2 !== null) {\n              result0 = [\n                result0,\n                result1,\n                result2\n              ];\n            } else {\n              result0 = null;\n              pos = pos1;\n            }\n          } else {\n            result0 = null;\n            pos = pos1;\n          }\n        } else {\n          result0 = null;\n          pos = pos1;\n        }\n        if (result0 !== null) {\n          result0 = function (offset, pair, list) {\n            return [pair].concat(list);\n          }(pos0, result0[0], result0[2]);\n        }\n        if (result0 === null) {\n          pos = pos0;\n        }\n        if (result0 === null) {\n          pos0 = pos;\n          result0 = parse_coordinatePair();\n          if (result0 !== null) {\n            result0 = function (offset, pair) {\n              return [pair];\n            }(pos0, result0);\n          }\n          if (result0 === null) {\n            pos = pos0;\n          }\n        }\n        return result0;\n      }\n      function parse_closepath() {\n        var result0;\n        var pos0;\n        pos0 = pos;\n        if (input.charCodeAt(pos) === 90) {\n          result0 = 'Z';\n          pos++;\n        } else {\n          result0 = null;\n          if (reportFailures === 0) {\n            matchFailed('\"Z\"');\n          }\n        }\n        if (result0 === null) {\n          if (input.charCodeAt(pos) === 122) {\n            result0 = 'z';\n            pos++;\n          } else {\n            result0 = null;\n            if (reportFailures === 0) {\n              matchFailed('\"z\"');\n            }\n          }\n        }\n        if (result0 !== null) {\n          result0 = function (offset, command) {\n            return { cmd: 'close' };\n          }(pos0, result0);\n        }\n        if (result0 === null) {\n          pos = pos0;\n        }\n        return result0;\n      }\n      function parse_lineto() {\n        var result0, result1, result2;\n        var pos0, pos1;\n        pos0 = pos;\n        pos1 = pos;\n        if (input.charCodeAt(pos) === 76) {\n          result0 = 'L';\n          pos++;\n        } else {\n          result0 = null;\n          if (reportFailures === 0) {\n            matchFailed('\"L\"');\n          }\n        }\n        if (result0 !== null) {\n          result1 = [];\n          result2 = parse_wsp();\n          while (result2 !== null) {\n            result1.push(result2);\n            result2 = parse_wsp();\n          }\n          if (result1 !== null) {\n            result2 = parse_linetoArgumentSequence();\n            if (result2 !== null) {\n              result0 = [\n                result0,\n                result1,\n                result2\n              ];\n            } else {\n              result0 = null;\n              pos = pos1;\n            }\n          } else {\n            result0 = null;\n            pos = pos1;\n          }\n        } else {\n          result0 = null;\n          pos = pos1;\n        }\n        if (result0 !== null) {\n          result0 = function (offset, args) {\n            return args.map(function (arg) {\n              return {\n                cmd: 'lineTo',\n                args: [\n                  arg.x,\n                  arg.y\n                ]\n              };\n            });\n          }(pos0, result0[2]);\n        }\n        if (result0 === null) {\n          pos = pos0;\n        }\n        if (result0 === null) {\n          pos0 = pos;\n          pos1 = pos;\n          if (input.charCodeAt(pos) === 108) {\n            result0 = 'l';\n            pos++;\n          } else {\n            result0 = null;\n            if (reportFailures === 0) {\n              matchFailed('\"l\"');\n            }\n          }\n          if (result0 !== null) {\n            result1 = [];\n            result2 = parse_wsp();\n            while (result2 !== null) {\n              result1.push(result2);\n              result2 = parse_wsp();\n            }\n            if (result1 !== null) {\n              result2 = parse_linetoArgumentSequence();\n              if (result2 !== null) {\n                result0 = [\n                  result0,\n                  result1,\n                  result2\n                ];\n              } else {\n                result0 = null;\n                pos = pos1;\n              }\n            } else {\n              result0 = null;\n              pos = pos1;\n            }\n          } else {\n            result0 = null;\n            pos = pos1;\n          }\n          if (result0 !== null) {\n            result0 = function (offset, args) {\n              return args.map(function (arg) {\n                return {\n                  cmd: 'lineToRelative',\n                  args: [\n                    arg.x,\n                    arg.y\n                  ]\n                };\n              });\n            }(pos0, result0[2]);\n          }\n          if (result0 === null) {\n            pos = pos0;\n          }\n        }\n        return result0;\n      }\n      function parse_linetoArgumentSequence() {\n        var result0, result1, result2;\n        var pos0, pos1;\n        pos0 = pos;\n        pos1 = pos;\n        result0 = parse_coordinatePair();\n        if (result0 !== null) {\n          result1 = parse_commaWsp();\n          result1 = result1 !== null ? result1 : '';\n          if (result1 !== null) {\n            result2 = parse_linetoArgumentSequence();\n            if (result2 !== null) {\n              result0 = [\n                result0,\n                result1,\n                result2\n              ];\n            } else {\n              result0 = null;\n              pos = pos1;\n            }\n          } else {\n            result0 = null;\n            pos = pos1;\n          }\n        } else {\n          result0 = null;\n          pos = pos1;\n        }\n        if (result0 !== null) {\n          result0 = function (offset, a, b) {\n            return [a].concat(b);\n          }(pos0, result0[0], result0[2]);\n        }\n        if (result0 === null) {\n          pos = pos0;\n        }\n        if (result0 === null) {\n          pos0 = pos;\n          result0 = parse_coordinatePair();\n          if (result0 !== null) {\n            result0 = function (offset, a) {\n              return [a];\n            }(pos0, result0);\n          }\n          if (result0 === null) {\n            pos = pos0;\n          }\n        }\n        return result0;\n      }\n      function parse_horizontalLineto() {\n        var result0, result1, result2;\n        var pos0, pos1;\n        pos0 = pos;\n        pos1 = pos;\n        if (input.charCodeAt(pos) === 72) {\n          result0 = 'H';\n          pos++;\n        } else {\n          result0 = null;\n          if (reportFailures === 0) {\n            matchFailed('\"H\"');\n          }\n        }\n        if (result0 !== null) {\n          result1 = [];\n          result2 = parse_wsp();\n          while (result2 !== null) {\n            result1.push(result2);\n            result2 = parse_wsp();\n          }\n          if (result1 !== null) {\n            result2 = parse_horizontalLinetoArgumentSequence();\n            if (result2 !== null) {\n              result0 = [\n                result0,\n                result1,\n                result2\n              ];\n            } else {\n              result0 = null;\n              pos = pos1;\n            }\n          } else {\n            result0 = null;\n            pos = pos1;\n          }\n        } else {\n          result0 = null;\n          pos = pos1;\n        }\n        if (result0 !== null) {\n          result0 = function (offset, args) {\n            return args.map(function (arg) {\n              return {\n                cmd: 'horizontalLineTo',\n                args: [arg]\n              };\n            });\n          }(pos0, result0[2]);\n        }\n        if (result0 === null) {\n          pos = pos0;\n        }\n        if (result0 === null) {\n          pos0 = pos;\n          pos1 = pos;\n          if (input.charCodeAt(pos) === 104) {\n            result0 = 'h';\n            pos++;\n          } else {\n            result0 = null;\n            if (reportFailures === 0) {\n              matchFailed('\"h\"');\n            }\n          }\n          if (result0 !== null) {\n            result1 = [];\n            result2 = parse_wsp();\n            while (result2 !== null) {\n              result1.push(result2);\n              result2 = parse_wsp();\n            }\n            if (result1 !== null) {\n              result2 = parse_horizontalLinetoArgumentSequence();\n              if (result2 !== null) {\n                result0 = [\n                  result0,\n                  result1,\n                  result2\n                ];\n              } else {\n                result0 = null;\n                pos = pos1;\n              }\n            } else {\n              result0 = null;\n              pos = pos1;\n            }\n          } else {\n            result0 = null;\n            pos = pos1;\n          }\n          if (result0 !== null) {\n            result0 = function (offset, args) {\n              return args.map(function (arg) {\n                return {\n                  cmd: 'horizontalLineToRelative',\n                  args: [arg]\n                };\n              });\n            }(pos0, result0[2]);\n          }\n          if (result0 === null) {\n            pos = pos0;\n          }\n        }\n        return result0;\n      }\n      function parse_horizontalLinetoArgumentSequence() {\n        var result0, result1, result2;\n        var pos0, pos1;\n        pos0 = pos;\n        pos1 = pos;\n        result0 = parse_number();\n        if (result0 !== null) {\n          result1 = parse_commaWsp();\n          result1 = result1 !== null ? result1 : '';\n          if (result1 !== null) {\n            result2 = parse_horizontalLinetoArgumentSequence();\n            if (result2 !== null) {\n              result0 = [\n                result0,\n                result1,\n                result2\n              ];\n            } else {\n              result0 = null;\n              pos = pos1;\n            }\n          } else {\n            result0 = null;\n            pos = pos1;\n          }\n        } else {\n          result0 = null;\n          pos = pos1;\n        }\n        if (result0 !== null) {\n          result0 = function (offset, a, b) {\n            return [a].concat(b);\n          }(pos0, result0[0], result0[2]);\n        }\n        if (result0 === null) {\n          pos = pos0;\n        }\n        if (result0 === null) {\n          pos0 = pos;\n          result0 = parse_number();\n          if (result0 !== null) {\n            result0 = function (offset, a) {\n              return [a];\n            }(pos0, result0);\n          }\n          if (result0 === null) {\n            pos = pos0;\n          }\n        }\n        return result0;\n      }\n      function parse_verticalLineto() {\n        var result0, result1, result2;\n        var pos0, pos1;\n        pos0 = pos;\n        pos1 = pos;\n        if (input.charCodeAt(pos) === 86) {\n          result0 = 'V';\n          pos++;\n        } else {\n          result0 = null;\n          if (reportFailures === 0) {\n            matchFailed('\"V\"');\n          }\n        }\n        if (result0 !== null) {\n          result1 = [];\n          result2 = parse_wsp();\n          while (result2 !== null) {\n            result1.push(result2);\n            result2 = parse_wsp();\n          }\n          if (result1 !== null) {\n            result2 = parse_verticalLinetoArgumentSequence();\n            if (result2 !== null) {\n              result0 = [\n                result0,\n                result1,\n                result2\n              ];\n            } else {\n              result0 = null;\n              pos = pos1;\n            }\n          } else {\n            result0 = null;\n            pos = pos1;\n          }\n        } else {\n          result0 = null;\n          pos = pos1;\n        }\n        if (result0 !== null) {\n          result0 = function (offset, args) {\n            return args.map(function (arg) {\n              return {\n                cmd: 'verticalLineTo',\n                args: [arg]\n              };\n            });\n          }(pos0, result0[2]);\n        }\n        if (result0 === null) {\n          pos = pos0;\n        }\n        if (result0 === null) {\n          pos0 = pos;\n          pos1 = pos;\n          if (input.charCodeAt(pos) === 118) {\n            result0 = 'v';\n            pos++;\n          } else {\n            result0 = null;\n            if (reportFailures === 0) {\n              matchFailed('\"v\"');\n            }\n          }\n          if (result0 !== null) {\n            result1 = [];\n            result2 = parse_wsp();\n            while (result2 !== null) {\n              result1.push(result2);\n              result2 = parse_wsp();\n            }\n            if (result1 !== null) {\n              result2 = parse_verticalLinetoArgumentSequence();\n              if (result2 !== null) {\n                result0 = [\n                  result0,\n                  result1,\n                  result2\n                ];\n              } else {\n                result0 = null;\n                pos = pos1;\n              }\n            } else {\n              result0 = null;\n              pos = pos1;\n            }\n          } else {\n            result0 = null;\n            pos = pos1;\n          }\n          if (result0 !== null) {\n            result0 = function (offset, args) {\n              return args.map(function (arg) {\n                return {\n                  cmd: 'verticalLineToRelative',\n                  args: [arg]\n                };\n              });\n            }(pos0, result0[2]);\n          }\n          if (result0 === null) {\n            pos = pos0;\n          }\n        }\n        return result0;\n      }\n      function parse_verticalLinetoArgumentSequence() {\n        var result0, result1, result2;\n        var pos0, pos1;\n        pos0 = pos;\n        pos1 = pos;\n        result0 = parse_number();\n        if (result0 !== null) {\n          result1 = parse_commaWsp();\n          result1 = result1 !== null ? result1 : '';\n          if (result1 !== null) {\n            result2 = parse_verticalLinetoArgumentSequence();\n            if (result2 !== null) {\n              result0 = [\n                result0,\n                result1,\n                result2\n              ];\n            } else {\n              result0 = null;\n              pos = pos1;\n            }\n          } else {\n            result0 = null;\n            pos = pos1;\n          }\n        } else {\n          result0 = null;\n          pos = pos1;\n        }\n        if (result0 !== null) {\n          result0 = function (offset, a, b) {\n            return [a].concat(b);\n          }(pos0, result0[0], result0[2]);\n        }\n        if (result0 === null) {\n          pos = pos0;\n        }\n        if (result0 === null) {\n          pos0 = pos;\n          result0 = parse_number();\n          if (result0 !== null) {\n            result0 = function (offset, a) {\n              return [a];\n            }(pos0, result0);\n          }\n          if (result0 === null) {\n            pos = pos0;\n          }\n        }\n        return result0;\n      }\n      function parse_curveto() {\n        var result0, result1, result2;\n        var pos0, pos1;\n        pos0 = pos;\n        pos1 = pos;\n        if (input.charCodeAt(pos) === 67) {\n          result0 = 'C';\n          pos++;\n        } else {\n          result0 = null;\n          if (reportFailures === 0) {\n            matchFailed('\"C\"');\n          }\n        }\n        if (result0 !== null) {\n          result1 = [];\n          result2 = parse_wsp();\n          while (result2 !== null) {\n            result1.push(result2);\n            result2 = parse_wsp();\n          }\n          if (result1 !== null) {\n            result2 = parse_curvetoArgumentSequence();\n            if (result2 !== null) {\n              result0 = [\n                result0,\n                result1,\n                result2\n              ];\n            } else {\n              result0 = null;\n              pos = pos1;\n            }\n          } else {\n            result0 = null;\n            pos = pos1;\n          }\n        } else {\n          result0 = null;\n          pos = pos1;\n        }\n        if (result0 !== null) {\n          result0 = function (offset, args) {\n            return args.map(function (arg) {\n              return {\n                cmd: 'cubicCurveTo',\n                args: arg\n              };\n            });\n          }(pos0, result0[2]);\n        }\n        if (result0 === null) {\n          pos = pos0;\n        }\n        if (result0 === null) {\n          pos0 = pos;\n          pos1 = pos;\n          if (input.charCodeAt(pos) === 99) {\n            result0 = 'c';\n            pos++;\n          } else {\n            result0 = null;\n            if (reportFailures === 0) {\n              matchFailed('\"c\"');\n            }\n          }\n          if (result0 !== null) {\n            result1 = [];\n            result2 = parse_wsp();\n            while (result2 !== null) {\n              result1.push(result2);\n              result2 = parse_wsp();\n            }\n            if (result1 !== null) {\n              result2 = parse_curvetoArgumentSequence();\n              if (result2 !== null) {\n                result0 = [\n                  result0,\n                  result1,\n                  result2\n                ];\n              } else {\n                result0 = null;\n                pos = pos1;\n              }\n            } else {\n              result0 = null;\n              pos = pos1;\n            }\n          } else {\n            result0 = null;\n            pos = pos1;\n          }\n          if (result0 !== null) {\n            result0 = function (offset, args) {\n              return args.map(function (arg) {\n                return {\n                  cmd: 'cubicCurveToRelative',\n                  args: arg\n                };\n              });\n            }(pos0, result0[2]);\n          }\n          if (result0 === null) {\n            pos = pos0;\n          }\n        }\n        return result0;\n      }\n      function parse_curvetoArgumentSequence() {\n        var result0, result1, result2;\n        var pos0, pos1;\n        pos0 = pos;\n        pos1 = pos;\n        result0 = parse_curvetoArgument();\n        if (result0 !== null) {\n          result1 = parse_commaWsp();\n          result1 = result1 !== null ? result1 : '';\n          if (result1 !== null) {\n            result2 = parse_curvetoArgumentSequence();\n            if (result2 !== null) {\n              result0 = [\n                result0,\n                result1,\n                result2\n              ];\n            } else {\n              result0 = null;\n              pos = pos1;\n            }\n          } else {\n            result0 = null;\n            pos = pos1;\n          }\n        } else {\n          result0 = null;\n          pos = pos1;\n        }\n        if (result0 !== null) {\n          result0 = function (offset, a, list) {\n            return [a].concat(list);\n          }(pos0, result0[0], result0[2]);\n        }\n        if (result0 === null) {\n          pos = pos0;\n        }\n        if (result0 === null) {\n          pos0 = pos;\n          result0 = parse_curvetoArgument();\n          if (result0 !== null) {\n            result0 = function (offset, a) {\n              return [a];\n            }(pos0, result0);\n          }\n          if (result0 === null) {\n            pos = pos0;\n          }\n        }\n        return result0;\n      }\n      function parse_curvetoArgument() {\n        var result0, result1, result2, result3, result4;\n        var pos0, pos1;\n        pos0 = pos;\n        pos1 = pos;\n        result0 = parse_coordinatePair();\n        if (result0 !== null) {\n          result1 = parse_commaWsp();\n          result1 = result1 !== null ? result1 : '';\n          if (result1 !== null) {\n            result2 = parse_coordinatePair();\n            if (result2 !== null) {\n              result3 = parse_commaWsp();\n              result3 = result3 !== null ? result3 : '';\n              if (result3 !== null) {\n                result4 = parse_coordinatePair();\n                if (result4 !== null) {\n                  result0 = [\n                    result0,\n                    result1,\n                    result2,\n                    result3,\n                    result4\n                  ];\n                } else {\n                  result0 = null;\n                  pos = pos1;\n                }\n              } else {\n                result0 = null;\n                pos = pos1;\n              }\n            } else {\n              result0 = null;\n              pos = pos1;\n            }\n          } else {\n            result0 = null;\n            pos = pos1;\n          }\n        } else {\n          result0 = null;\n          pos = pos1;\n        }\n        if (result0 !== null) {\n          result0 = function (offset, a, b, c) {\n            return [\n              a.x,\n              a.y,\n              b.x,\n              b.y,\n              c.x,\n              c.y\n            ];\n          }(pos0, result0[0], result0[2], result0[4]);\n        }\n        if (result0 === null) {\n          pos = pos0;\n        }\n        return result0;\n      }\n      function parse_smoothCurveto() {\n        var result0, result1, result2;\n        var pos0, pos1;\n        pos0 = pos;\n        pos1 = pos;\n        if (input.charCodeAt(pos) === 83) {\n          result0 = 'S';\n          pos++;\n        } else {\n          result0 = null;\n          if (reportFailures === 0) {\n            matchFailed('\"S\"');\n          }\n        }\n        if (result0 !== null) {\n          result1 = [];\n          result2 = parse_wsp();\n          while (result2 !== null) {\n            result1.push(result2);\n            result2 = parse_wsp();\n          }\n          if (result1 !== null) {\n            result2 = parse_smoothCurvetoArgumentSequence();\n            if (result2 !== null) {\n              result0 = [\n                result0,\n                result1,\n                result2\n              ];\n            } else {\n              result0 = null;\n              pos = pos1;\n            }\n          } else {\n            result0 = null;\n            pos = pos1;\n          }\n        } else {\n          result0 = null;\n          pos = pos1;\n        }\n        if (result0 !== null) {\n          result0 = function (offset, args) {\n            return args.map(function (arg) {\n              return {\n                cmd: 'smoothCubicCurveTo',\n                args: arg\n              };\n            });\n          }(pos0, result0[2]);\n        }\n        if (result0 === null) {\n          pos = pos0;\n        }\n        if (result0 === null) {\n          pos0 = pos;\n          pos1 = pos;\n          if (input.charCodeAt(pos) === 115) {\n            result0 = 's';\n            pos++;\n          } else {\n            result0 = null;\n            if (reportFailures === 0) {\n              matchFailed('\"s\"');\n            }\n          }\n          if (result0 !== null) {\n            result1 = [];\n            result2 = parse_wsp();\n            while (result2 !== null) {\n              result1.push(result2);\n              result2 = parse_wsp();\n            }\n            if (result1 !== null) {\n              result2 = parse_smoothCurvetoArgumentSequence();\n              if (result2 !== null) {\n                result0 = [\n                  result0,\n                  result1,\n                  result2\n                ];\n              } else {\n                result0 = null;\n                pos = pos1;\n              }\n            } else {\n              result0 = null;\n              pos = pos1;\n            }\n          } else {\n            result0 = null;\n            pos = pos1;\n          }\n          if (result0 !== null) {\n            result0 = function (offset, args) {\n              return args.map(function (arg) {\n                return {\n                  cmd: 'smoothCubicCurveToRelative',\n                  args: arg\n                };\n              });\n            }(pos0, result0[2]);\n          }\n          if (result0 === null) {\n            pos = pos0;\n          }\n        }\n        return result0;\n      }\n      function parse_smoothCurvetoArgumentSequence() {\n        var result0, result1, result2;\n        var pos0, pos1;\n        pos0 = pos;\n        pos1 = pos;\n        result0 = parse_smoothCurvetoArgument();\n        if (result0 !== null) {\n          result1 = parse_commaWsp();\n          result1 = result1 !== null ? result1 : '';\n          if (result1 !== null) {\n            result2 = parse_smoothCurvetoArgumentSequence();\n            if (result2 !== null) {\n              result0 = [\n                result0,\n                result1,\n                result2\n              ];\n            } else {\n              result0 = null;\n              pos = pos1;\n            }\n          } else {\n            result0 = null;\n            pos = pos1;\n          }\n        } else {\n          result0 = null;\n          pos = pos1;\n        }\n        if (result0 !== null) {\n          result0 = function (offset, a, list) {\n            return [a].concat(list);\n          }(pos0, result0[0], result0[2]);\n        }\n        if (result0 === null) {\n          pos = pos0;\n        }\n        if (result0 === null) {\n          pos0 = pos;\n          result0 = parse_smoothCurvetoArgument();\n          if (result0 !== null) {\n            result0 = function (offset, a) {\n              return [a];\n            }(pos0, result0);\n          }\n          if (result0 === null) {\n            pos = pos0;\n          }\n        }\n        return result0;\n      }\n      function parse_smoothCurvetoArgument() {\n        var result0, result1, result2;\n        var pos0, pos1;\n        pos0 = pos;\n        pos1 = pos;\n        result0 = parse_coordinatePair();\n        if (result0 !== null) {\n          result1 = parse_commaWsp();\n          result1 = result1 !== null ? result1 : '';\n          if (result1 !== null) {\n            result2 = parse_coordinatePair();\n            if (result2 !== null) {\n              result0 = [\n                result0,\n                result1,\n                result2\n              ];\n            } else {\n              result0 = null;\n              pos = pos1;\n            }\n          } else {\n            result0 = null;\n            pos = pos1;\n          }\n        } else {\n          result0 = null;\n          pos = pos1;\n        }\n        if (result0 !== null) {\n          result0 = function (offset, a, b) {\n            return [\n              a.x,\n              a.y,\n              b.x,\n              b.y\n            ];\n          }(pos0, result0[0], result0[2]);\n        }\n        if (result0 === null) {\n          pos = pos0;\n        }\n        return result0;\n      }\n      function parse_quadraticBezierCurveto() {\n        var result0, result1, result2;\n        var pos0, pos1;\n        pos0 = pos;\n        pos1 = pos;\n        if (input.charCodeAt(pos) === 81) {\n          result0 = 'Q';\n          pos++;\n        } else {\n          result0 = null;\n          if (reportFailures === 0) {\n            matchFailed('\"Q\"');\n          }\n        }\n        if (result0 !== null) {\n          result1 = [];\n          result2 = parse_wsp();\n          while (result2 !== null) {\n            result1.push(result2);\n            result2 = parse_wsp();\n          }\n          if (result1 !== null) {\n            result2 = parse_quadraticBezierCurvetoArgumentSequence();\n            if (result2 !== null) {\n              result0 = [\n                result0,\n                result1,\n                result2\n              ];\n            } else {\n              result0 = null;\n              pos = pos1;\n            }\n          } else {\n            result0 = null;\n            pos = pos1;\n          }\n        } else {\n          result0 = null;\n          pos = pos1;\n        }\n        if (result0 !== null) {\n          result0 = function (offset, args) {\n            return args.map(function (arg) {\n              return {\n                cmd: 'quadraticCurveTo',\n                args: arg\n              };\n            });\n          }(pos0, result0[2]);\n        }\n        if (result0 === null) {\n          pos = pos0;\n        }\n        if (result0 === null) {\n          pos0 = pos;\n          pos1 = pos;\n          if (input.charCodeAt(pos) === 113) {\n            result0 = 'q';\n            pos++;\n          } else {\n            result0 = null;\n            if (reportFailures === 0) {\n              matchFailed('\"q\"');\n            }\n          }\n          if (result0 !== null) {\n            result1 = [];\n            result2 = parse_wsp();\n            while (result2 !== null) {\n              result1.push(result2);\n              result2 = parse_wsp();\n            }\n            if (result1 !== null) {\n              result2 = parse_quadraticBezierCurvetoArgumentSequence();\n              if (result2 !== null) {\n                result0 = [\n                  result0,\n                  result1,\n                  result2\n                ];\n              } else {\n                result0 = null;\n                pos = pos1;\n              }\n            } else {\n              result0 = null;\n              pos = pos1;\n            }\n          } else {\n            result0 = null;\n            pos = pos1;\n          }\n          if (result0 !== null) {\n            result0 = function (offset, args) {\n              return args.map(function (arg) {\n                return {\n                  cmd: 'quadraticCurveToRelative',\n                  args: arg\n                };\n              });\n            }(pos0, result0[2]);\n          }\n          if (result0 === null) {\n            pos = pos0;\n          }\n        }\n        return result0;\n      }\n      function parse_quadraticBezierCurvetoArgumentSequence() {\n        var result0, result1, result2;\n        var pos0, pos1;\n        pos0 = pos;\n        pos1 = pos;\n        result0 = parse_quadraticBezierCurvetoArgument();\n        if (result0 !== null) {\n          result1 = parse_commaWsp();\n          result1 = result1 !== null ? result1 : '';\n          if (result1 !== null) {\n            result2 = parse_quadraticBezierCurvetoArgumentSequence();\n            if (result2 !== null) {\n              result0 = [\n                result0,\n                result1,\n                result2\n              ];\n            } else {\n              result0 = null;\n              pos = pos1;\n            }\n          } else {\n            result0 = null;\n            pos = pos1;\n          }\n        } else {\n          result0 = null;\n          pos = pos1;\n        }\n        if (result0 !== null) {\n          result0 = function (offset, a, list) {\n            return [a].concat(list);\n          }(pos0, result0[0], result0[2]);\n        }\n        if (result0 === null) {\n          pos = pos0;\n        }\n        if (result0 === null) {\n          pos0 = pos;\n          result0 = parse_quadraticBezierCurvetoArgument();\n          if (result0 !== null) {\n            result0 = function (offset, a) {\n              return [a];\n            }(pos0, result0);\n          }\n          if (result0 === null) {\n            pos = pos0;\n          }\n        }\n        return result0;\n      }\n      function parse_quadraticBezierCurvetoArgument() {\n        var result0, result1, result2;\n        var pos0, pos1;\n        pos0 = pos;\n        pos1 = pos;\n        result0 = parse_coordinatePair();\n        if (result0 !== null) {\n          result1 = parse_commaWsp();\n          result1 = result1 !== null ? result1 : '';\n          if (result1 !== null) {\n            result2 = parse_coordinatePair();\n            if (result2 !== null) {\n              result0 = [\n                result0,\n                result1,\n                result2\n              ];\n            } else {\n              result0 = null;\n              pos = pos1;\n            }\n          } else {\n            result0 = null;\n            pos = pos1;\n          }\n        } else {\n          result0 = null;\n          pos = pos1;\n        }\n        if (result0 !== null) {\n          result0 = function (offset, a, b) {\n            return [\n              a.x,\n              a.y,\n              b.x,\n              b.y\n            ];\n          }(pos0, result0[0], result0[2]);\n        }\n        if (result0 === null) {\n          pos = pos0;\n        }\n        return result0;\n      }\n      function parse_smoothQuadraticBezierCurveto() {\n        var result0, result1, result2;\n        var pos0, pos1;\n        pos0 = pos;\n        pos1 = pos;\n        if (input.charCodeAt(pos) === 84) {\n          result0 = 'T';\n          pos++;\n        } else {\n          result0 = null;\n          if (reportFailures === 0) {\n            matchFailed('\"T\"');\n          }\n        }\n        if (result0 !== null) {\n          result1 = [];\n          result2 = parse_wsp();\n          while (result2 !== null) {\n            result1.push(result2);\n            result2 = parse_wsp();\n          }\n          if (result1 !== null) {\n            result2 = parse_smoothQuadraticBezierCurvetoArgumentSequence();\n            if (result2 !== null) {\n              result0 = [\n                result0,\n                result1,\n                result2\n              ];\n            } else {\n              result0 = null;\n              pos = pos1;\n            }\n          } else {\n            result0 = null;\n            pos = pos1;\n          }\n        } else {\n          result0 = null;\n          pos = pos1;\n        }\n        if (result0 !== null) {\n          result0 = function (offset, args) {\n            return args.map(function (arg) {\n              return {\n                cmd: 'smoothQuadraticCurveTo',\n                args: [\n                  arg.x,\n                  arg.y\n                ]\n              };\n            });\n          }(pos0, result0[2]);\n        }\n        if (result0 === null) {\n          pos = pos0;\n        }\n        if (result0 === null) {\n          pos0 = pos;\n          pos1 = pos;\n          if (input.charCodeAt(pos) === 116) {\n            result0 = 't';\n            pos++;\n          } else {\n            result0 = null;\n            if (reportFailures === 0) {\n              matchFailed('\"t\"');\n            }\n          }\n          if (result0 !== null) {\n            result1 = [];\n            result2 = parse_wsp();\n            while (result2 !== null) {\n              result1.push(result2);\n              result2 = parse_wsp();\n            }\n            if (result1 !== null) {\n              result2 = parse_smoothQuadraticBezierCurvetoArgumentSequence();\n              if (result2 !== null) {\n                result0 = [\n                  result0,\n                  result1,\n                  result2\n                ];\n              } else {\n                result0 = null;\n                pos = pos1;\n              }\n            } else {\n              result0 = null;\n              pos = pos1;\n            }\n          } else {\n            result0 = null;\n            pos = pos1;\n          }\n          if (result0 !== null) {\n            result0 = function (offset, args) {\n              return args.map(function (arg) {\n                return {\n                  cmd: 'smoothQuadraticCurveToRelative',\n                  args: [\n                    arg.x,\n                    arg.y\n                  ]\n                };\n              });\n            }(pos0, result0[2]);\n          }\n          if (result0 === null) {\n            pos = pos0;\n          }\n        }\n        return result0;\n      }\n      function parse_smoothQuadraticBezierCurvetoArgumentSequence() {\n        var result0, result1, result2;\n        var pos0, pos1;\n        pos0 = pos;\n        pos1 = pos;\n        result0 = parse_coordinatePair();\n        if (result0 !== null) {\n          result1 = parse_commaWsp();\n          result1 = result1 !== null ? result1 : '';\n          if (result1 !== null) {\n            result2 = parse_smoothQuadraticBezierCurvetoArgumentSequence();\n            if (result2 !== null) {\n              result0 = [\n                result0,\n                result1,\n                result2\n              ];\n            } else {\n              result0 = null;\n              pos = pos1;\n            }\n          } else {\n            result0 = null;\n            pos = pos1;\n          }\n        } else {\n          result0 = null;\n          pos = pos1;\n        }\n        if (result0 !== null) {\n          result0 = function (offset, a, list) {\n            return [a].concat(list);\n          }(pos0, result0[0], result0[2]);\n        }\n        if (result0 === null) {\n          pos = pos0;\n        }\n        if (result0 === null) {\n          pos0 = pos;\n          result0 = parse_coordinatePair();\n          if (result0 !== null) {\n            result0 = function (offset, a) {\n              return [a];\n            }(pos0, result0);\n          }\n          if (result0 === null) {\n            pos = pos0;\n          }\n        }\n        return result0;\n      }\n      function parse_ellipticalArc() {\n        var result0, result1, result2;\n        var pos0, pos1;\n        pos0 = pos;\n        pos1 = pos;\n        if (input.charCodeAt(pos) === 65) {\n          result0 = 'A';\n          pos++;\n        } else {\n          result0 = null;\n          if (reportFailures === 0) {\n            matchFailed('\"A\"');\n          }\n        }\n        if (result0 !== null) {\n          result1 = [];\n          result2 = parse_wsp();\n          while (result2 !== null) {\n            result1.push(result2);\n            result2 = parse_wsp();\n          }\n          if (result1 !== null) {\n            result2 = parse_ellipticalArcArgumentSequence();\n            if (result2 !== null) {\n              result0 = [\n                result0,\n                result1,\n                result2\n              ];\n            } else {\n              result0 = null;\n              pos = pos1;\n            }\n          } else {\n            result0 = null;\n            pos = pos1;\n          }\n        } else {\n          result0 = null;\n          pos = pos1;\n        }\n        if (result0 !== null) {\n          result0 = function (offset, args) {\n            return args.map(function (arg) {\n              return {\n                cmd: 'ellipticalArcTo',\n                args: arg\n              };\n            });\n          }(pos0, result0[2]);\n        }\n        if (result0 === null) {\n          pos = pos0;\n        }\n        if (result0 === null) {\n          pos0 = pos;\n          pos1 = pos;\n          if (input.charCodeAt(pos) === 97) {\n            result0 = 'a';\n            pos++;\n          } else {\n            result0 = null;\n            if (reportFailures === 0) {\n              matchFailed('\"a\"');\n            }\n          }\n          if (result0 !== null) {\n            result1 = [];\n            result2 = parse_wsp();\n            while (result2 !== null) {\n              result1.push(result2);\n              result2 = parse_wsp();\n            }\n            if (result1 !== null) {\n              result2 = parse_ellipticalArcArgumentSequence();\n              if (result2 !== null) {\n                result0 = [\n                  result0,\n                  result1,\n                  result2\n                ];\n              } else {\n                result0 = null;\n                pos = pos1;\n              }\n            } else {\n              result0 = null;\n              pos = pos1;\n            }\n          } else {\n            result0 = null;\n            pos = pos1;\n          }\n          if (result0 !== null) {\n            result0 = function (offset, args) {\n              return args.map(function (arg) {\n                return {\n                  cmd: 'ellipticalArcToRelative',\n                  args: arg\n                };\n              });\n            }(pos0, result0[2]);\n          }\n          if (result0 === null) {\n            pos = pos0;\n          }\n        }\n        return result0;\n      }\n      function parse_ellipticalArcArgumentSequence() {\n        var result0, result1, result2;\n        var pos0, pos1;\n        pos0 = pos;\n        pos1 = pos;\n        result0 = parse_ellipticalArcArgument();\n        if (result0 !== null) {\n          result1 = parse_commaWsp();\n          result1 = result1 !== null ? result1 : '';\n          if (result1 !== null) {\n            result2 = parse_ellipticalArcArgumentSequence();\n            if (result2 !== null) {\n              result0 = [\n                result0,\n                result1,\n                result2\n              ];\n            } else {\n              result0 = null;\n              pos = pos1;\n            }\n          } else {\n            result0 = null;\n            pos = pos1;\n          }\n        } else {\n          result0 = null;\n          pos = pos1;\n        }\n        if (result0 !== null) {\n          result0 = function (offset, a, list) {\n            return [a].concat(list);\n          }(pos0, result0[0], result0[2]);\n        }\n        if (result0 === null) {\n          pos = pos0;\n        }\n        if (result0 === null) {\n          pos0 = pos;\n          result0 = parse_ellipticalArcArgument();\n          if (result0 !== null) {\n            result0 = function (offset, a) {\n              return [a];\n            }(pos0, result0);\n          }\n          if (result0 === null) {\n            pos = pos0;\n          }\n        }\n        return result0;\n      }\n      function parse_ellipticalArcArgument() {\n        var result0, result1, result2, result3, result4, result5, result6, result7, result8, result9, result10;\n        var pos0, pos1;\n        pos0 = pos;\n        pos1 = pos;\n        result0 = parse_nonnegativeNumber();\n        if (result0 !== null) {\n          result1 = parse_commaWsp();\n          result1 = result1 !== null ? result1 : '';\n          if (result1 !== null) {\n            result2 = parse_nonnegativeNumber();\n            if (result2 !== null) {\n              result3 = parse_commaWsp();\n              result3 = result3 !== null ? result3 : '';\n              if (result3 !== null) {\n                result4 = parse_number();\n                if (result4 !== null) {\n                  result5 = parse_commaWsp();\n                  if (result5 !== null) {\n                    result6 = parse_flag();\n                    if (result6 !== null) {\n                      result7 = parse_commaWsp();\n                      result7 = result7 !== null ? result7 : '';\n                      if (result7 !== null) {\n                        result8 = parse_flag();\n                        if (result8 !== null) {\n                          result9 = parse_commaWsp();\n                          result9 = result9 !== null ? result9 : '';\n                          if (result9 !== null) {\n                            result10 = parse_coordinatePair();\n                            if (result10 !== null) {\n                              result0 = [\n                                result0,\n                                result1,\n                                result2,\n                                result3,\n                                result4,\n                                result5,\n                                result6,\n                                result7,\n                                result8,\n                                result9,\n                                result10\n                              ];\n                            } else {\n                              result0 = null;\n                              pos = pos1;\n                            }\n                          } else {\n                            result0 = null;\n                            pos = pos1;\n                          }\n                        } else {\n                          result0 = null;\n                          pos = pos1;\n                        }\n                      } else {\n                        result0 = null;\n                        pos = pos1;\n                      }\n                    } else {\n                      result0 = null;\n                      pos = pos1;\n                    }\n                  } else {\n                    result0 = null;\n                    pos = pos1;\n                  }\n                } else {\n                  result0 = null;\n                  pos = pos1;\n                }\n              } else {\n                result0 = null;\n                pos = pos1;\n              }\n            } else {\n              result0 = null;\n              pos = pos1;\n            }\n          } else {\n            result0 = null;\n            pos = pos1;\n          }\n        } else {\n          result0 = null;\n          pos = pos1;\n        }\n        if (result0 !== null) {\n          result0 = function (offset, rx, ry, rot, largeArc, sweep, to) {\n            return [\n              rx,\n              ry,\n              rot,\n              largeArc,\n              sweep,\n              to.x,\n              to.y\n            ];\n          }(pos0, result0[0], result0[2], result0[4], result0[6], result0[8], result0[10]);\n        }\n        if (result0 === null) {\n          pos = pos0;\n        }\n        return result0;\n      }\n      function parse_coordinatePair() {\n        var result0, result1, result2;\n        var pos0, pos1;\n        pos0 = pos;\n        pos1 = pos;\n        result0 = parse_number();\n        if (result0 !== null) {\n          result1 = parse_commaWsp();\n          result1 = result1 !== null ? result1 : '';\n          if (result1 !== null) {\n            result2 = parse_number();\n            if (result2 !== null) {\n              result0 = [\n                result0,\n                result1,\n                result2\n              ];\n            } else {\n              result0 = null;\n              pos = pos1;\n            }\n          } else {\n            result0 = null;\n            pos = pos1;\n          }\n        } else {\n          result0 = null;\n          pos = pos1;\n        }\n        if (result0 !== null) {\n          result0 = function (offset, a, b) {\n            return {\n              x: a,\n              y: b\n            };\n          }(pos0, result0[0], result0[2]);\n        }\n        if (result0 === null) {\n          pos = pos0;\n        }\n        return result0;\n      }\n      function parse_nonnegativeNumber() {\n        var result0;\n        var pos0;\n        pos0 = pos;\n        result0 = parse_floatingPointConstant();\n        if (result0 !== null) {\n          result0 = function (offset, number) {\n            return parseFloat(number, 10);\n          }(pos0, result0);\n        }\n        if (result0 === null) {\n          pos = pos0;\n        }\n        if (result0 === null) {\n          pos0 = pos;\n          result0 = parse_digitSequence();\n          if (result0 !== null) {\n            result0 = function (offset, number) {\n              return parseInt(number, 10);\n            }(pos0, result0);\n          }\n          if (result0 === null) {\n            pos = pos0;\n          }\n        }\n        return result0;\n      }\n      function parse_number() {\n        var result0, result1;\n        var pos0, pos1;\n        pos0 = pos;\n        pos1 = pos;\n        result0 = parse_sign();\n        result0 = result0 !== null ? result0 : '';\n        if (result0 !== null) {\n          result1 = parse_floatingPointConstant();\n          if (result1 !== null) {\n            result0 = [\n              result0,\n              result1\n            ];\n          } else {\n            result0 = null;\n            pos = pos1;\n          }\n        } else {\n          result0 = null;\n          pos = pos1;\n        }\n        if (result0 !== null) {\n          result0 = function (offset, sign, number) {\n            return parseFloat(sign + number, 10);\n          }(pos0, result0[0], result0[1]);\n        }\n        if (result0 === null) {\n          pos = pos0;\n        }\n        if (result0 === null) {\n          pos0 = pos;\n          pos1 = pos;\n          result0 = parse_sign();\n          result0 = result0 !== null ? result0 : '';\n          if (result0 !== null) {\n            result1 = parse_digitSequence();\n            if (result1 !== null) {\n              result0 = [\n                result0,\n                result1\n              ];\n            } else {\n              result0 = null;\n              pos = pos1;\n            }\n          } else {\n            result0 = null;\n            pos = pos1;\n          }\n          if (result0 !== null) {\n            result0 = function (offset, sign, number) {\n              return parseInt(sign + number, 10);\n            }(pos0, result0[0], result0[1]);\n          }\n          if (result0 === null) {\n            pos = pos0;\n          }\n        }\n        return result0;\n      }\n      function parse_flag() {\n        var result0;\n        var pos0;\n        pos0 = pos;\n        if (input.charCodeAt(pos) === 48) {\n          result0 = '0';\n          pos++;\n        } else {\n          result0 = null;\n          if (reportFailures === 0) {\n            matchFailed('\"0\"');\n          }\n        }\n        if (result0 !== null) {\n          result0 = function (offset) {\n            return false;\n          }(pos0);\n        }\n        if (result0 === null) {\n          pos = pos0;\n        }\n        if (result0 === null) {\n          pos0 = pos;\n          if (input.charCodeAt(pos) === 49) {\n            result0 = '1';\n            pos++;\n          } else {\n            result0 = null;\n            if (reportFailures === 0) {\n              matchFailed('\"1\"');\n            }\n          }\n          if (result0 !== null) {\n            result0 = function (offset) {\n              return true;\n            }(pos0);\n          }\n          if (result0 === null) {\n            pos = pos0;\n          }\n        }\n        return result0;\n      }\n      function parse_commaWsp() {\n        var result0, result1, result2, result3;\n        var pos0;\n        pos0 = pos;\n        result1 = parse_wsp();\n        if (result1 !== null) {\n          result0 = [];\n          while (result1 !== null) {\n            result0.push(result1);\n            result1 = parse_wsp();\n          }\n        } else {\n          result0 = null;\n        }\n        if (result0 !== null) {\n          result1 = parse_comma();\n          result1 = result1 !== null ? result1 : '';\n          if (result1 !== null) {\n            result2 = [];\n            result3 = parse_wsp();\n            while (result3 !== null) {\n              result2.push(result3);\n              result3 = parse_wsp();\n            }\n            if (result2 !== null) {\n              result0 = [\n                result0,\n                result1,\n                result2\n              ];\n            } else {\n              result0 = null;\n              pos = pos0;\n            }\n          } else {\n            result0 = null;\n            pos = pos0;\n          }\n        } else {\n          result0 = null;\n          pos = pos0;\n        }\n        if (result0 === null) {\n          pos0 = pos;\n          result0 = parse_comma();\n          if (result0 !== null) {\n            result1 = [];\n            result2 = parse_wsp();\n            while (result2 !== null) {\n              result1.push(result2);\n              result2 = parse_wsp();\n            }\n            if (result1 !== null) {\n              result0 = [\n                result0,\n                result1\n              ];\n            } else {\n              result0 = null;\n              pos = pos0;\n            }\n          } else {\n            result0 = null;\n            pos = pos0;\n          }\n        }\n        return result0;\n      }\n      function parse_comma() {\n        var result0;\n        if (input.charCodeAt(pos) === 44) {\n          result0 = ',';\n          pos++;\n        } else {\n          result0 = null;\n          if (reportFailures === 0) {\n            matchFailed('\",\"');\n          }\n        }\n        return result0;\n      }\n      function parse_floatingPointConstant() {\n        var result0, result1;\n        var pos0, pos1;\n        pos0 = pos;\n        pos1 = pos;\n        result0 = parse_fractionalConstant();\n        if (result0 !== null) {\n          result1 = parse_exponent();\n          result1 = result1 !== null ? result1 : '';\n          if (result1 !== null) {\n            result0 = [\n              result0,\n              result1\n            ];\n          } else {\n            result0 = null;\n            pos = pos1;\n          }\n        } else {\n          result0 = null;\n          pos = pos1;\n        }\n        if (result0 !== null) {\n          result0 = function (offset, a, b) {\n            return a + b;\n          }(pos0, result0[0], result0[1]);\n        }\n        if (result0 === null) {\n          pos = pos0;\n        }\n        if (result0 === null) {\n          pos0 = pos;\n          pos1 = pos;\n          result0 = parse_digitSequence();\n          if (result0 !== null) {\n            result1 = parse_exponent();\n            if (result1 !== null) {\n              result0 = [\n                result0,\n                result1\n              ];\n            } else {\n              result0 = null;\n              pos = pos1;\n            }\n          } else {\n            result0 = null;\n            pos = pos1;\n          }\n          if (result0 !== null) {\n            result0 = function (offset, a, b) {\n              return a + b;\n            }(pos0, result0[0], result0[1]);\n          }\n          if (result0 === null) {\n            pos = pos0;\n          }\n        }\n        return result0;\n      }\n      function parse_fractionalConstant() {\n        var result0, result1, result2;\n        var pos0, pos1;\n        pos0 = pos;\n        pos1 = pos;\n        result0 = parse_digitSequence();\n        result0 = result0 !== null ? result0 : '';\n        if (result0 !== null) {\n          if (input.charCodeAt(pos) === 46) {\n            result1 = '.';\n            pos++;\n          } else {\n            result1 = null;\n            if (reportFailures === 0) {\n              matchFailed('\".\"');\n            }\n          }\n          if (result1 !== null) {\n            result2 = parse_digitSequence();\n            if (result2 !== null) {\n              result0 = [\n                result0,\n                result1,\n                result2\n              ];\n            } else {\n              result0 = null;\n              pos = pos1;\n            }\n          } else {\n            result0 = null;\n            pos = pos1;\n          }\n        } else {\n          result0 = null;\n          pos = pos1;\n        }\n        if (result0 !== null) {\n          result0 = function (offset, a, b) {\n            return a + '.' + b;\n          }(pos0, result0[0], result0[2]);\n        }\n        if (result0 === null) {\n          pos = pos0;\n        }\n        if (result0 === null) {\n          pos0 = pos;\n          pos1 = pos;\n          result0 = parse_digitSequence();\n          if (result0 !== null) {\n            if (input.charCodeAt(pos) === 46) {\n              result1 = '.';\n              pos++;\n            } else {\n              result1 = null;\n              if (reportFailures === 0) {\n                matchFailed('\".\"');\n              }\n            }\n            if (result1 !== null) {\n              result0 = [\n                result0,\n                result1\n              ];\n            } else {\n              result0 = null;\n              pos = pos1;\n            }\n          } else {\n            result0 = null;\n            pos = pos1;\n          }\n          if (result0 !== null) {\n            result0 = function (offset, a) {\n              return a;\n            }(pos0, result0[0]);\n          }\n          if (result0 === null) {\n            pos = pos0;\n          }\n        }\n        return result0;\n      }\n      function parse_exponent() {\n        var result0, result1, result2;\n        var pos0, pos1;\n        pos0 = pos;\n        pos1 = pos;\n        if (input.charCodeAt(pos) === 101) {\n          result0 = 'e';\n          pos++;\n        } else {\n          result0 = null;\n          if (reportFailures === 0) {\n            matchFailed('\"e\"');\n          }\n        }\n        if (result0 === null) {\n          if (input.charCodeAt(pos) === 69) {\n            result0 = 'E';\n            pos++;\n          } else {\n            result0 = null;\n            if (reportFailures === 0) {\n              matchFailed('\"E\"');\n            }\n          }\n        }\n        if (result0 !== null) {\n          result1 = parse_sign();\n          result1 = result1 !== null ? result1 : '';\n          if (result1 !== null) {\n            result2 = parse_digitSequence();\n            if (result2 !== null) {\n              result0 = [\n                result0,\n                result1,\n                result2\n              ];\n            } else {\n              result0 = null;\n              pos = pos1;\n            }\n          } else {\n            result0 = null;\n            pos = pos1;\n          }\n        } else {\n          result0 = null;\n          pos = pos1;\n        }\n        if (result0 !== null) {\n          result0 = function (offset, a, b, c) {\n            return a + b + c;\n          }(pos0, result0[0], result0[1], result0[2]);\n        }\n        if (result0 === null) {\n          pos = pos0;\n        }\n        return result0;\n      }\n      function parse_sign() {\n        var result0;\n        if (input.charCodeAt(pos) === 43) {\n          result0 = '+';\n          pos++;\n        } else {\n          result0 = null;\n          if (reportFailures === 0) {\n            matchFailed('\"+\"');\n          }\n        }\n        if (result0 === null) {\n          if (input.charCodeAt(pos) === 45) {\n            result0 = '-';\n            pos++;\n          } else {\n            result0 = null;\n            if (reportFailures === 0) {\n              matchFailed('\"-\"');\n            }\n          }\n        }\n        return result0;\n      }\n      function parse_digitSequence() {\n        var result0, result1;\n        var pos0, pos1;\n        pos0 = pos;\n        pos1 = pos;\n        result0 = parse_digit();\n        if (result0 !== null) {\n          result1 = parse_digitSequence();\n          if (result1 !== null) {\n            result0 = [\n              result0,\n              result1\n            ];\n          } else {\n            result0 = null;\n            pos = pos1;\n          }\n        } else {\n          result0 = null;\n          pos = pos1;\n        }\n        if (result0 !== null) {\n          result0 = function (offset, a, b) {\n            return a + b;\n          }(pos0, result0[0], result0[1]);\n        }\n        if (result0 === null) {\n          pos = pos0;\n        }\n        if (result0 === null) {\n          result0 = parse_digit();\n        }\n        return result0;\n      }\n      function parse_digit() {\n        var result0;\n        if (/^[0-9]/.test(input.charAt(pos))) {\n          result0 = input.charAt(pos);\n          pos++;\n        } else {\n          result0 = null;\n          if (reportFailures === 0) {\n            matchFailed('[0-9]');\n          }\n        }\n        return result0;\n      }\n      function parse_wsp() {\n        var result0;\n        if (input.charCodeAt(pos) === 32) {\n          result0 = ' ';\n          pos++;\n        } else {\n          result0 = null;\n          if (reportFailures === 0) {\n            matchFailed('\" \"');\n          }\n        }\n        if (result0 === null) {\n          if (input.charCodeAt(pos) === 9) {\n            result0 = '\\t';\n            pos++;\n          } else {\n            result0 = null;\n            if (reportFailures === 0) {\n              matchFailed('\"\\\\t\"');\n            }\n          }\n          if (result0 === null) {\n            if (input.charCodeAt(pos) === 13) {\n              result0 = '\\r';\n              pos++;\n            } else {\n              result0 = null;\n              if (reportFailures === 0) {\n                matchFailed('\"\\\\r\"');\n              }\n            }\n            if (result0 === null) {\n              if (input.charCodeAt(pos) === 10) {\n                result0 = '\\n';\n                pos++;\n              } else {\n                result0 = null;\n                if (reportFailures === 0) {\n                  matchFailed('\"\\\\n\"');\n                }\n              }\n            }\n          }\n        }\n        return result0;\n      }\n      function cleanupExpected(expected) {\n        expected.sort();\n        var lastExpected = null;\n        var cleanExpected = [];\n        for (var i = 0; i < expected.length; i++) {\n          if (expected[i] !== lastExpected) {\n            cleanExpected.push(expected[i]);\n            lastExpected = expected[i];\n          }\n        }\n        return cleanExpected;\n      }\n      function computeErrorPosition() {\n        var line = 1;\n        var column = 1;\n        var seenCR = false;\n        for (var i = 0; i < Math.max(pos, rightmostFailuresPos); i++) {\n          var ch = input.charAt(i);\n          if (ch === '\\n') {\n            if (!seenCR) {\n              line++;\n            }\n            column = 1;\n            seenCR = false;\n          } else if (ch === '\\r' || ch === '\\u2028' || ch === '\\u2029') {\n            line++;\n            column = 1;\n            seenCR = true;\n          } else {\n            column++;\n            seenCR = false;\n          }\n        }\n        return {\n          line: line,\n          column: column\n        };\n      }\n      function createMoveTo(args, isRelative) {\n        var result = [{\n              cmd: isRelative ? 'moveToRelative' : 'moveTo',\n              args: [\n                args[0].x,\n                args[0].y\n              ]\n            }];\n        if (args.length > 1) {\n          for (var i = 1; i < args.length; i++) {\n            result.push({\n              cmd: isRelative ? 'lineToRelative' : 'lineTo',\n              args: [\n                args[i].x,\n                args[i].y\n              ]\n            });\n          }\n        }\n        return result;\n      }\n      var result = parseFunctions[startRule]();\n      if (result === null || pos !== input.length) {\n        var offset = Math.max(pos, rightmostFailuresPos);\n        var found = offset < input.length ? input.charAt(offset) : null;\n        var errorPosition = computeErrorPosition();\n        throw new this.SyntaxError(cleanupExpected(rightmostFailuresExpected), found, offset, errorPosition.line, errorPosition.column);\n      }\n      return result;\n    },\n    toSource: function () {\n      return this._source;\n    }\n  };\n  var result = kite.svgPath;\n  result.SyntaxError = function (expected, found, offset, line, column) {\n    function buildMessage(expected, found) {\n      var expectedHumanized, foundHumanized;\n      switch (expected.length) {\n      case 0:\n        expectedHumanized = 'end of input';\n        break;\n      case 1:\n        expectedHumanized = expected[0];\n        break;\n      default:\n        expectedHumanized = expected.slice(0, expected.length - 1).join(', ') + ' or ' + expected[expected.length - 1];\n      }\n      foundHumanized = found ? quote(found) : 'end of input';\n      return 'Expected ' + expectedHumanized + ' but ' + foundHumanized + ' found.';\n    }\n    this.name = 'SyntaxError';\n    this.expected = expected;\n    this.found = found;\n    this.message = buildMessage(expected, found);\n    this.offset = offset;\n    this.line = line;\n    this.column = column;\n  };\n  result.SyntaxError.prototype = Error.prototype;\n  return result;\n});",
    "\ndefine('KITE/util/LineStyles',['require','KITE/kite'],function (require) {\n  'use strict';\n  var kite = require('KITE/kite');\n  kite.LineStyles = function (args) {\n    if (args === undefined) {\n      args = {};\n    }\n    this.lineWidth = args.lineWidth !== undefined ? args.lineWidth : 1;\n    this.lineCap = args.lineCap !== undefined ? args.lineCap : 'butt';\n    this.lineJoin = args.lineJoin !== undefined ? args.lineJoin : 'miter';\n    this.lineDash = args.lineDash ? args.lineDash : [];\n    this.lineDashOffset = args.lineDashOffset !== undefined ? args.lineDashOffset : 0;\n    this.miterLimit = args.miterLimit !== undefined ? args.miterLimit : 10;\n    null;\n  };\n  var LineStyles = kite.LineStyles;\n  LineStyles.prototype = {\n    constructor: LineStyles,\n    equals: function (other) {\n      var typical = this.lineWidth === other.lineWidth && this.lineCap === other.lineCap && this.lineJoin === other.lineJoin && this.miterLimit === other.miterLimit && this.lineDashOffset === other.lineDashOffset;\n      if (!typical) {\n        return false;\n      }\n      if (this.lineDash.length === other.lineDash.length) {\n        for (var i = 0; i < this.lineDash.length; i++) {\n          if (this.lineDash[i] !== other.lineDash[i]) {\n            return false;\n          }\n        }\n      } else {\n        return false;\n      }\n      return true;\n    }\n  };\n  return kite.LineStyles;\n});",
    "\ndefine('KITE/segments/Quadratic',['require','KITE/kite','PHET_CORE/inherit','DOT/Bounds2','DOT/Matrix3','DOT/Util','KITE/segments/Segment'],function (require) {\n  'use strict';\n  var kite = require('KITE/kite');\n  var inherit = require('PHET_CORE/inherit');\n  var Bounds2 = require('DOT/Bounds2');\n  var Matrix3 = require('DOT/Matrix3');\n  var solveQuadraticRootsReal = require('DOT/Util').solveQuadraticRootsReal;\n  var Segment = require('KITE/segments/Segment');\n  Segment.Quadratic = function Quadratic(start, control, end, skipComputations) {\n    this.start = start;\n    this.control = control;\n    this.end = end;\n    if (start.equals(end) && start.equals(control)) {\n      this.invalid = true;\n      return;\n    }\n    var t;\n    if (skipComputations) {\n      return;\n    }\n    var controlIsStart = start.equals(control);\n    var controlIsEnd = end.equals(control);\n    null;\n    this.startTangent = controlIsStart ? end.minus(start).normalized() : control.minus(start).normalized();\n    this.endTangent = controlIsEnd ? end.minus(start).normalized() : end.minus(control).normalized();\n    this.bounds = new Bounds2(Math.min(start.x, end.x), Math.min(start.y, end.y), Math.max(start.x, end.x), Math.max(start.y, end.y));\n    var divisorX = 2 * (end.x - 2 * control.x + start.x);\n    if (divisorX !== 0) {\n      this.tCriticalX = -2 * (control.x - start.x) / divisorX;\n      if (t > 0 && t < 1) {\n        this.bounds = this.bounds.withPoint(this.positionAt(this.tCriticalX));\n      }\n    }\n    var divisorY = 2 * (end.y - 2 * control.y + start.y);\n    if (divisorY !== 0) {\n      this.tCriticalY = -2 * (control.y - start.y) / divisorY;\n      if (t > 0 && t < 1) {\n        this.bounds = this.bounds.withPoint(this.positionAt(this.tCriticalY));\n      }\n    }\n  };\n  inherit(Segment, Segment.Quadratic, {\n    degree: 2,\n    positionAt: function (t) {\n      var mt = 1 - t;\n      return this.start.times(mt * mt).plus(this.control.times(2 * mt * t)).plus(this.end.times(t * t));\n    },\n    tangentAt: function (t) {\n      return this.control.minus(this.start).times(2 * (1 - t)).plus(this.end.minus(this.control).times(2 * t));\n    },\n    curvatureAt: function (t) {\n      var epsilon = 1e-7;\n      if (Math.abs(t - 0.5) > 0.5 - epsilon) {\n        var isZero = t < 0.5;\n        var p0 = isZero ? this.start : this.end;\n        var p1 = this.control;\n        var p2 = isZero ? this.end : this.start;\n        var d10 = p1.minus(p0);\n        var a = d10.magnitude();\n        var h = (isZero ? -1 : 1) * d10.perpendicular().normalized().dot(p2.minus(p1));\n        return h * (this.degree - 1) / (this.degree * a * a);\n      } else {\n        return this.subdivided(t, true)[0].curvatureAt(1);\n      }\n    },\n    offsetTo: function (r, reverse) {\n      var curves = [this];\n      var depth = 5;\n      for (var i = 0; i < depth; i++) {\n        curves = _.flatten(_.map(curves, function (curve) {\n          return curve.subdivided(0.5, true);\n        }));\n      }\n      var offsetCurves = _.map(curves, function (curve) {\n          return curve.approximateOffset(r);\n        });\n      if (reverse) {\n        offsetCurves.reverse();\n        offsetCurves = _.map(offsetCurves, function (curve) {\n          return curve.reversed(true);\n        });\n      }\n      return offsetCurves;\n    },\n    subdivided: function (t, skipComputations) {\n      var leftMid = this.start.blend(this.control, t);\n      var rightMid = this.control.blend(this.end, t);\n      var mid = leftMid.blend(rightMid, t);\n      return [\n        new Segment.Quadratic(this.start, leftMid, mid, skipComputations),\n        new Segment.Quadratic(mid, rightMid, this.end, skipComputations)\n      ];\n    },\n    reversed: function (skipComputations) {\n      return new Segment.Quadratic(this.end, this.control, this.start);\n    },\n    approximateOffset: function (r) {\n      return new Segment.Quadratic(this.start.plus((this.start.equals(this.control) ? this.end.minus(this.start) : this.control.minus(this.start)).perpendicular().normalized().times(r)), this.control.plus(this.end.minus(this.start).perpendicular().normalized().times(r)), this.end.plus((this.end.equals(this.control) ? this.end.minus(this.start) : this.end.minus(this.control)).perpendicular().normalized().times(r)));\n    },\n    getSVGPathFragment: function () {\n      return 'Q ' + this.control.x + ' ' + this.control.y + ' ' + this.end.x + ' ' + this.end.y;\n    },\n    strokeLeft: function (lineWidth) {\n      return this.offsetTo(-lineWidth / 2, false);\n    },\n    strokeRight: function (lineWidth) {\n      return this.offsetTo(lineWidth / 2, true);\n    },\n    getInteriorExtremaTs: function () {\n      var result = [];\n      var epsilon = 1e-10;\n      if (this.tCriticalX !== undefined && this.tCriticalX > epsilon && this.tCriticalX < 1 - epsilon) {\n        result.push(this.tCriticalX);\n      }\n      if (this.tCriticalY !== undefined && this.tCriticalY > epsilon && this.tCriticalY < 1 - epsilon) {\n        result.push(this.tCriticalY);\n      }\n      return result.sort();\n    },\n    intersectsBounds: function (bounds) {\n      throw new Error('Segment.Quadratic.intersectsBounds unimplemented');\n    },\n    intersection: function (ray) {\n      var self = this;\n      var result = [];\n      var inverseMatrix = Matrix3.rotation2(-ray.dir.angle()).timesMatrix(Matrix3.translation(-ray.pos.x, -ray.pos.y));\n      var p0 = inverseMatrix.timesVector2(this.start);\n      var p1 = inverseMatrix.timesVector2(this.control);\n      var p2 = inverseMatrix.timesVector2(this.end);\n      var a = p0.y - 2 * p1.y + p2.y;\n      var b = -2 * p0.y + 2 * p1.y;\n      var c = p0.y;\n      var ts = solveQuadraticRootsReal(a, b, c);\n      _.each(ts, function (t) {\n        if (t >= 0 && t <= 1) {\n          var hitPoint = self.positionAt(t);\n          var unitTangent = self.tangentAt(t).normalized();\n          var perp = unitTangent.perpendicular();\n          var toHit = hitPoint.minus(ray.pos);\n          if (toHit.dot(ray.dir) > 0) {\n            result.push({\n              distance: toHit.magnitude(),\n              point: hitPoint,\n              normal: perp.dot(ray.dir) > 0 ? perp.negated() : perp,\n              wind: ray.dir.perpendicular().dot(unitTangent) < 0 ? 1 : -1\n            });\n          }\n        }\n      });\n      return result;\n    },\n    windingIntersection: function (ray) {\n      var wind = 0;\n      var hits = this.intersection(ray);\n      _.each(hits, function (hit) {\n        wind += hit.wind;\n      });\n      return wind;\n    },\n    writeToContext: function (context) {\n      context.quadraticCurveTo(this.control.x, this.control.y, this.end.x, this.end.y);\n    },\n    transformed: function (matrix) {\n      return new Segment.Quadratic(matrix.timesVector2(this.start), matrix.timesVector2(this.control), matrix.timesVector2(this.end));\n    }\n  });\n  return Segment.Quadratic;\n});",
    "\ndefine('KITE/segments/Cubic',['require','KITE/kite','PHET_CORE/inherit','DOT/Bounds2','DOT/Vector2','DOT/Matrix3','DOT/Util','DOT/Util','KITE/segments/Segment','KITE/segments/Quadratic'],function (require) {\n  'use strict';\n  var kite = require('KITE/kite');\n  var inherit = require('PHET_CORE/inherit');\n  var Bounds2 = require('DOT/Bounds2');\n  var Vector2 = require('DOT/Vector2');\n  var Matrix3 = require('DOT/Matrix3');\n  var solveQuadraticRootsReal = require('DOT/Util').solveQuadraticRootsReal;\n  var solveCubicRootsReal = require('DOT/Util').solveCubicRootsReal;\n  var Segment = require('KITE/segments/Segment');\n  require('KITE/segments/Quadratic');\n  Segment.Cubic = function Cubic(start, control1, control2, end, skipComputations) {\n    this.start = start;\n    this.control1 = control1;\n    this.control2 = control2;\n    this.end = end;\n    if (skipComputations) {\n      return;\n    }\n    if (start.equals(end, 0) && start.equals(control1, 0) && start.equals(control2, 0)) {\n      this.invalid = true;\n      return;\n    }\n    this.startTangent = this.tangentAt(0).normalized();\n    this.endTangent = this.tangentAt(1).normalized();\n    this.r = control1.minus(start).normalized();\n    this.s = this.r.perpendicular();\n    var a = start.times(-1).plus(control1.times(3)).plus(control2.times(-3)).plus(end);\n    var b = start.times(3).plus(control1.times(-6)).plus(control2.times(3));\n    var c = start.times(-3).plus(control1.times(3));\n    var d = start;\n    var aPerp = a.perpendicular();\n    var bPerp = b.perpendicular();\n    var aPerpDotB = aPerp.dot(b);\n    this.tCusp = -0.5 * (aPerp.dot(c) / aPerpDotB);\n    this.tDeterminant = this.tCusp * this.tCusp - 1 / 3 * (bPerp.dot(c) / aPerpDotB);\n    if (this.tDeterminant >= 0) {\n      var sqrtDet = Math.sqrt(this.tDeterminant);\n      this.tInflection1 = this.tCusp - sqrtDet;\n      this.tInflection2 = this.tCusp + sqrtDet;\n    }\n    if (this.hasCusp()) {\n      var subdividedAtCusp = this.subdivided(this.tCusp, true);\n      this.startQuadratic = new Segment.Quadratic(subdividedAtCusp[0].start, subdividedAtCusp[0].control1, subdividedAtCusp[0].end, false);\n      this.endQuadratic = new Segment.Quadratic(subdividedAtCusp[1].start, subdividedAtCusp[1].control2, subdividedAtCusp[1].end, false);\n    }\n    this.bounds = Bounds2.NOTHING;\n    this.bounds = this.bounds.withPoint(this.start);\n    this.bounds = this.bounds.withPoint(this.end);\n    function extremaT(v0, v1, v2, v3) {\n      var a = -3 * v0 + 9 * v1 - 9 * v2 + 3 * v3;\n      var b = 6 * v0 - 12 * v1 + 6 * v2;\n      var c = -3 * v0 + 3 * v1;\n      return solveQuadraticRootsReal(a, b, c);\n    }\n    var cubic = this;\n    this.xExtremaT = extremaT(this.start.x, this.control1.x, this.control2.x, this.end.x);\n    _.each(this.xExtremaT, function (t) {\n      if (t >= 0 && t <= 1) {\n        cubic.bounds = cubic.bounds.withPoint(cubic.positionAt(t));\n      }\n    });\n    this.yExtremaT = extremaT(this.start.y, this.control1.y, this.control2.y, this.end.y);\n    _.each(this.yExtremaT, function (t) {\n      if (t >= 0 && t <= 1) {\n        cubic.bounds = cubic.bounds.withPoint(cubic.positionAt(t));\n      }\n    });\n    if (this.hasCusp()) {\n      this.bounds = this.bounds.withPoint(this.positionAt(this.tCusp));\n    }\n  };\n  inherit(Segment, Segment.Cubic, {\n    degree: 3,\n    hasCusp: function () {\n      var epsilon = 0.000001;\n      return this.tangentAt(this.tCusp).magnitude() < epsilon && this.tCusp >= 0 && this.tCusp <= 1;\n    },\n    positionAt: function (t) {\n      var mt = 1 - t;\n      return this.start.times(mt * mt * mt).plus(this.control1.times(3 * mt * mt * t)).plus(this.control2.times(3 * mt * t * t)).plus(this.end.times(t * t * t));\n    },\n    tangentAt: function (t) {\n      var mt = 1 - t;\n      return this.start.times(-3 * mt * mt).plus(this.control1.times(3 * mt * mt - 6 * mt * t)).plus(this.control2.times(6 * mt * t - 3 * t * t)).plus(this.end.times(3 * t * t));\n    },\n    curvatureAt: function (t) {\n      var epsilon = 1e-7;\n      if (Math.abs(t - 0.5) > 0.5 - epsilon) {\n        var isZero = t < 0.5;\n        var p0 = isZero ? this.start : this.end;\n        var p1 = isZero ? this.control1 : this.control2;\n        var p2 = isZero ? this.control2 : this.control1;\n        var d10 = p1.minus(p0);\n        var a = d10.magnitude();\n        var h = (isZero ? -1 : 1) * d10.perpendicular().normalized().dot(p2.minus(p1));\n        return h * (this.degree - 1) / (this.degree * a * a);\n      } else {\n        return this.subdivided(t, true)[0].curvatureAt(1);\n      }\n    },\n    toRS: function (point) {\n      var firstVector = point.minus(this.start);\n      return new Vector2(firstVector.dot(this.r), firstVector.dot(this.s));\n    },\n    subdivided: function (t, skipComputations) {\n      var left = this.start.blend(this.control1, t);\n      var right = this.control2.blend(this.end, t);\n      var middle = this.control1.blend(this.control2, t);\n      var leftMid = left.blend(middle, t);\n      var rightMid = middle.blend(right, t);\n      var mid = leftMid.blend(rightMid, t);\n      return [\n        new Segment.Cubic(this.start, left, leftMid, mid, skipComputations),\n        new Segment.Cubic(mid, rightMid, right, this.end, skipComputations)\n      ];\n    },\n    offsetTo: function (r, reverse) {\n      var quantity = 32;\n      var points = [];\n      var result = [];\n      for (var i = 0; i < quantity; i++) {\n        var t = i / (quantity - 1);\n        if (reverse) {\n          t = 1 - t;\n        }\n        points.push(this.positionAt(t).plus(this.tangentAt(t).perpendicular().normalized().times(r)));\n        if (i > 0) {\n          result.push(new Segment.Line(points[i - 1], points[i]));\n        }\n      }\n      return result;\n    },\n    getSVGPathFragment: function () {\n      return 'C ' + this.control1.x + ' ' + this.control1.y + ' ' + this.control2.x + ' ' + this.control2.y + ' ' + this.end.x + ' ' + this.end.y;\n    },\n    strokeLeft: function (lineWidth) {\n      return this.offsetTo(-lineWidth / 2, false);\n    },\n    strokeRight: function (lineWidth) {\n      return this.offsetTo(lineWidth / 2, true);\n    },\n    getInteriorExtremaTs: function () {\n      var ts = this.xExtremaT.concat(this.yExtremaT);\n      var result = [];\n      _.each(ts, function (t) {\n        var epsilon = 1e-10;\n        if (t > epsilon && t < 1 - epsilon) {\n          if (_.every(result, function (otherT) {\n              return Math.abs(t - otherT) > epsilon;\n            })) {\n            result.push(t);\n          }\n        }\n      });\n      return result.sort();\n    },\n    intersectsBounds: function (bounds) {\n      throw new Error('Segment.Cubic.intersectsBounds unimplemented');\n    },\n    intersection: function (ray) {\n      var self = this;\n      var result = [];\n      var inverseMatrix = Matrix3.rotation2(-ray.dir.angle()).timesMatrix(Matrix3.translation(-ray.pos.x, -ray.pos.y));\n      var p0 = inverseMatrix.timesVector2(this.start);\n      var p1 = inverseMatrix.timesVector2(this.control1);\n      var p2 = inverseMatrix.timesVector2(this.control2);\n      var p3 = inverseMatrix.timesVector2(this.end);\n      var a = -p0.y + 3 * p1.y - 3 * p2.y + p3.y;\n      var b = 3 * p0.y - 6 * p1.y + 3 * p2.y;\n      var c = -3 * p0.y + 3 * p1.y;\n      var d = p0.y;\n      var ts = solveCubicRootsReal(a, b, c, d);\n      _.each(ts, function (t) {\n        if (t >= 0 && t <= 1) {\n          var hitPoint = self.positionAt(t);\n          var unitTangent = self.tangentAt(t).normalized();\n          var perp = unitTangent.perpendicular();\n          var toHit = hitPoint.minus(ray.pos);\n          if (toHit.dot(ray.dir) > 0) {\n            result.push({\n              distance: toHit.magnitude(),\n              point: hitPoint,\n              normal: perp.dot(ray.dir) > 0 ? perp.negated() : perp,\n              wind: ray.dir.perpendicular().dot(unitTangent) < 0 ? 1 : -1\n            });\n          }\n        }\n      });\n      return result;\n    },\n    windingIntersection: function (ray) {\n      var wind = 0;\n      var hits = this.intersection(ray);\n      _.each(hits, function (hit) {\n        wind += hit.wind;\n      });\n      return wind;\n    },\n    writeToContext: function (context) {\n      context.bezierCurveTo(this.control1.x, this.control1.y, this.control2.x, this.control2.y, this.end.x, this.end.y);\n    },\n    transformed: function (matrix) {\n      return new Segment.Cubic(matrix.timesVector2(this.start), matrix.timesVector2(this.control1), matrix.timesVector2(this.control2), matrix.timesVector2(this.end));\n    }\n  });\n  return Segment.Cubic;\n});",
    "\ndefine('KITE/segments/EllipticalArc',['require','KITE/kite','PHET_CORE/inherit','DOT/Vector2','DOT/Bounds2','DOT/Matrix3','DOT/Transform3','DOT/Util','DOT/Util','KITE/segments/Segment','KITE/util/Subpath'],function (require) {\n  'use strict';\n  var kite = require('KITE/kite');\n  var inherit = require('PHET_CORE/inherit');\n  var Vector2 = require('DOT/Vector2');\n  var Bounds2 = require('DOT/Bounds2');\n  var Matrix3 = require('DOT/Matrix3');\n  var Transform3 = require('DOT/Transform3');\n  var toDegrees = require('DOT/Util').toDegrees;\n  var DotUtil = require('DOT/Util');\n  var Segment = require('KITE/segments/Segment');\n  require('KITE/util/Subpath');\n  Segment.EllipticalArc = function EllipticalArc(center, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise) {\n    if (radiusX < 0) {\n      radiusX = -radiusX;\n      startAngle = Math.PI - startAngle;\n      endAngle = Math.PI - endAngle;\n      anticlockwise = !anticlockwise;\n    }\n    if (radiusY < 0) {\n      radiusY = -radiusY;\n      startAngle = -startAngle;\n      endAngle = -endAngle;\n      anticlockwise = !anticlockwise;\n    }\n    if (radiusX < radiusY) {\n      rotation += Math.PI / 2;\n      startAngle -= Math.PI / 2;\n      endAngle -= Math.PI / 2;\n      var tmpR = radiusX;\n      radiusX = radiusY;\n      radiusY = tmpR;\n    }\n    this.center = center;\n    this.radiusX = radiusX;\n    this.radiusY = radiusY;\n    this.rotation = rotation;\n    this.startAngle = startAngle;\n    this.endAngle = endAngle;\n    this.anticlockwise = anticlockwise;\n    this.unitTransform = Segment.EllipticalArc.computeUnitTransform(center, radiusX, radiusY, rotation);\n    this.start = this.positionAtAngle(startAngle);\n    this.end = this.positionAtAngle(endAngle);\n    this.startTangent = this.tangentAtAngle(startAngle).normalized();\n    this.endTangent = this.tangentAtAngle(endAngle).normalized();\n    if (radiusX === 0 || radiusY === 0 || startAngle === endAngle) {\n      this.invalid = true;\n      return;\n    }\n    if (radiusX < radiusY) {\n      throw new Error('Not verified to work if radiusX < radiusY');\n    }\n    if (this.anticlockwise) {\n      if (this.startAngle > this.endAngle) {\n        this.actualEndAngle = this.endAngle;\n      } else if (this.startAngle < this.endAngle) {\n        this.actualEndAngle = this.endAngle - 2 * Math.PI;\n      } else {\n        this.actualEndAngle = this.startAngle;\n      }\n    } else {\n      if (this.startAngle < this.endAngle) {\n        this.actualEndAngle = this.endAngle;\n      } else if (this.startAngle > this.endAngle) {\n        this.actualEndAngle = this.endAngle + Math.PI * 2;\n      } else {\n        this.actualEndAngle = this.startAngle;\n      }\n    }\n    null;\n    null;\n    var isFullPerimeter = !anticlockwise && endAngle - startAngle >= Math.PI * 2 || anticlockwise && startAngle - endAngle >= Math.PI * 2;\n    this.angleDifference = this.anticlockwise ? this.startAngle - this.endAngle : this.endAngle - this.startAngle;\n    if (this.angleDifference < 0) {\n      this.angleDifference += Math.PI * 2;\n    }\n    null;\n    this.unitArcSegment = new Segment.Arc(Vector2.ZERO, 1, startAngle, endAngle, anticlockwise);\n    this.bounds = Bounds2.NOTHING;\n    this.bounds = this.bounds.withPoint(this.start);\n    this.bounds = this.bounds.withPoint(this.end);\n    var that = this;\n    function boundsAtAngle(angle) {\n      if (that.containsAngle(angle)) {\n        that.bounds = that.bounds.withPoint(that.positionAtAngle(angle));\n      }\n    }\n    if (startAngle !== endAngle) {\n      var xAngle = Math.atan(-(radiusY / radiusX) * Math.tan(rotation));\n      var yAngle = Math.atan(radiusY / radiusX / Math.tan(rotation));\n      this.possibleExtremaAngles = [\n        xAngle,\n        xAngle + Math.PI,\n        yAngle,\n        yAngle + Math.PI\n      ];\n      _.each(this.possibleExtremaAngles, boundsAtAngle);\n    }\n  };\n  inherit(Segment, Segment.EllipticalArc, {\n    mapAngle: function (angle) {\n      return this.startAngle > this.actualEndAngle ? DotUtil.moduloBetweenUp(angle, this.startAngle - 2 * Math.PI, this.startAngle) : DotUtil.moduloBetweenDown(angle, this.startAngle, this.startAngle + 2 * Math.PI);\n    },\n    tAtAngle: function (angle) {\n      return (this.mapAngle(angle) - this.startAngle) / (this.actualEndAngle - this.startAngle);\n    },\n    angleAt: function (t) {\n      return this.startAngle + (this.actualEndAngle - this.startAngle) * t;\n    },\n    positionAt: function (t) {\n      return this.positionAtAngle(this.angleAt(t));\n    },\n    tangentAt: function (t) {\n      return this.tangentAtAngle(this.angleAt(t));\n    },\n    curvatureAt: function (t) {\n      var angle = this.angleAt(t);\n      var aq = this.radiusX * Math.sin(angle);\n      var bq = this.radiusY * Math.cos(angle);\n      var denominator = Math.pow(bq * bq + aq * aq, 3 / 2);\n      return (this.anticlockwise ? -1 : 1) * this.radiusX * this.radiusY / denominator;\n    },\n    positionAtAngle: function (angle) {\n      return this.unitTransform.transformPosition2(Vector2.createPolar(1, angle));\n    },\n    tangentAtAngle: function (angle) {\n      var normal = this.unitTransform.transformNormal2(Vector2.createPolar(1, angle));\n      return this.anticlockwise ? normal.perpendicular() : normal.perpendicular().negated();\n    },\n    containsAngle: function (angle) {\n      var normalizedAngle = this.anticlockwise ? angle - this.endAngle : angle - this.startAngle;\n      var positiveMinAngle = normalizedAngle % (Math.PI * 2);\n      if (positiveMinAngle < 0) {\n        positiveMinAngle += Math.PI * 2;\n      }\n      return positiveMinAngle <= this.angleDifference;\n    },\n    offsetTo: function (r, reverse) {\n      var quantity = 32;\n      var points = [];\n      var result = [];\n      for (var i = 0; i < quantity; i++) {\n        var ratio = i / (quantity - 1);\n        if (reverse) {\n          ratio = 1 - ratio;\n        }\n        var angle = this.angleAt(ratio);\n        points.push(this.positionAtAngle(angle).plus(this.tangentAtAngle(angle).perpendicular().normalized().times(r)));\n        if (i > 0) {\n          result.push(new Segment.Line(points[i - 1], points[i]));\n        }\n      }\n      return result;\n    },\n    getSVGPathFragment: function () {\n      var epsilon = 0.01;\n      var sweepFlag = this.anticlockwise ? '0' : '1';\n      var largeArcFlag;\n      var degreesRotation = toDegrees(this.rotation);\n      if (this.angleDifference < Math.PI * 2 - epsilon) {\n        largeArcFlag = this.angleDifference < Math.PI ? '0' : '1';\n        return 'A ' + this.radiusX + ' ' + this.radiusY + ' ' + degreesRotation + ' ' + largeArcFlag + ' ' + sweepFlag + ' ' + this.end.x + ' ' + this.end.y;\n      } else {\n        var splitOppositeAngle = (this.startAngle + this.endAngle) / 2;\n        var splitPoint = this.positionAtAngle(splitOppositeAngle);\n        largeArcFlag = '0';\n        var firstArc = 'A ' + this.radiusX + ' ' + this.radiusY + ' ' + degreesRotation + ' ' + largeArcFlag + ' ' + sweepFlag + ' ' + splitPoint.x + ' ' + splitPoint.y;\n        var secondArc = 'A ' + this.radiusX + ' ' + this.radiusY + ' ' + degreesRotation + ' ' + largeArcFlag + ' ' + sweepFlag + ' ' + this.end.x + ' ' + this.end.y;\n        return firstArc + ' ' + secondArc;\n      }\n    },\n    strokeLeft: function (lineWidth) {\n      return this.offsetTo(-lineWidth / 2, false);\n    },\n    strokeRight: function (lineWidth) {\n      return this.offsetTo(lineWidth / 2, true);\n    },\n    getInteriorExtremaTs: function () {\n      var that = this;\n      var result = [];\n      _.each(this.possibleExtremaAngles, function (angle) {\n        if (that.containsAngle(angle)) {\n          var t = that.tAtAngle(angle);\n          var epsilon = 1e-10;\n          if (t > epsilon && t < 1 - epsilon) {\n            result.push(t);\n          }\n        }\n      });\n      return result.sort();\n    },\n    subdivided: function (t) {\n      var angle0 = this.angleAt(0);\n      var angleT = this.angleAt(t);\n      var angle1 = this.angleAt(1);\n      return [\n        new Segment.EllipticalArc(this.center, this.radiusX, this.radiusY, this.rotation, angle0, angleT, this.anticlockwise),\n        new Segment.EllipticalArc(this.center, this.radiusX, this.radiusY, this.rotation, angleT, angle1, this.anticlockwise)\n      ];\n    },\n    intersectsBounds: function (bounds) {\n      throw new Error('Segment.EllipticalArc.intersectsBounds unimplemented');\n    },\n    intersection: function (ray) {\n      var unitTransform = this.unitTransform;\n      var rayInUnitCircleSpace = unitTransform.inverseRay2(ray);\n      var hits = this.unitArcSegment.intersection(rayInUnitCircleSpace);\n      return _.map(hits, function (hit) {\n        var transformedPoint = unitTransform.transformPosition2(hit.point);\n        return {\n          distance: ray.pos.distance(transformedPoint),\n          point: transformedPoint,\n          normal: unitTransform.inverseNormal2(hit.normal),\n          wind: hit.wind\n        };\n      });\n    },\n    windingIntersection: function (ray) {\n      var rayInUnitCircleSpace = this.unitTransform.inverseRay2(ray);\n      return this.unitArcSegment.windingIntersection(rayInUnitCircleSpace);\n    },\n    writeToContext: function (context) {\n      if (context.ellipse) {\n        context.ellipse(this.center.x, this.center.y, this.radiusX, this.radiusY, this.rotation, this.startAngle, this.endAngle, this.anticlockwise);\n      } else {\n        this.unitTransform.getMatrix().canvasAppendTransform(context);\n        context.arc(0, 0, 1, this.startAngle, this.endAngle, this.anticlockwise);\n        this.unitTransform.getInverse().canvasAppendTransform(context);\n      }\n    },\n    transformed: function (matrix) {\n      var transformedSemiMajorAxis = matrix.timesVector2(Vector2.createPolar(this.radiusX, this.rotation)).minus(matrix.timesVector2(Vector2.ZERO));\n      var transformedSemiMinorAxis = matrix.timesVector2(Vector2.createPolar(this.radiusY, this.rotation + Math.PI / 2)).minus(matrix.timesVector2(Vector2.ZERO));\n      var rotation = transformedSemiMajorAxis.angle();\n      var radiusX = transformedSemiMajorAxis.magnitude();\n      var radiusY = transformedSemiMinorAxis.magnitude();\n      var reflected = matrix.getDeterminant() < 0;\n      var anticlockwise = reflected ? !this.anticlockwise : this.anticlockwise;\n      var startAngle = reflected ? -this.startAngle : this.startAngle;\n      var endAngle = reflected ? -this.endAngle : this.endAngle;\n      return new Segment.EllipticalArc(matrix.timesVector2(this.center), radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise);\n    }\n  });\n  Segment.EllipticalArc.computeUnitTransform = function (center, radiusX, radiusY, rotation) {\n    return new Transform3(Matrix3.translation(center.x, center.y).timesMatrix(Matrix3.rotation2(rotation)).timesMatrix(Matrix3.scaling(radiusX, radiusY)));\n  };\n  return Segment.EllipticalArc;\n});",
    "\ndefine('KITE/Shape',['require','ASSERT/assert','KITE/kite','DOT/Vector2','DOT/Bounds2','DOT/Ray2','DOT/Matrix3','DOT/Transform3','DOT/Util','DOT/Util','KITE/util/Subpath','KITE/../parser/svgPath','KITE/util/LineStyles','KITE/segments/Arc','KITE/segments/Cubic','KITE/segments/EllipticalArc','KITE/segments/Line','KITE/segments/Quadratic'],function (require) {\n  'use strict';\n  var assertExtra = require('ASSERT/assert')('kite.extra', true);\n  var kite = require('KITE/kite');\n  var Vector2 = require('DOT/Vector2');\n  var Bounds2 = require('DOT/Bounds2');\n  var Ray2 = require('DOT/Ray2');\n  var Matrix3 = require('DOT/Matrix3');\n  var Transform3 = require('DOT/Transform3');\n  var toDegrees = require('DOT/Util').toDegrees;\n  var lineLineIntersection = require('DOT/Util').lineLineIntersection;\n  var Subpath = require('KITE/util/Subpath');\n  var svgPath = require('KITE/../parser/svgPath');\n  require('KITE/util/LineStyles');\n  require('KITE/segments/Arc');\n  require('KITE/segments/Cubic');\n  require('KITE/segments/EllipticalArc');\n  require('KITE/segments/Line');\n  require('KITE/segments/Quadratic');\n  function p(x, y) {\n    return new Vector2(x, y);\n  }\n  function v(x, y) {\n    return new Vector2(x, y);\n  }\n  kite.Shape = function Shape(subpaths, bounds) {\n    this.subpaths = typeof subpaths === 'object' ? subpaths : [];\n    null;\n    this.bounds = bounds || Bounds2.NOTHING;\n    var that = this;\n    if (subpaths && typeof subpaths !== 'object') {\n      null;\n      _.each(svgPath.parse(subpaths), function (item) {\n        null;\n        that[item.cmd].apply(that, item.args);\n      });\n    }\n    phetAllocation && phetAllocation('Shape');\n  };\n  var Shape = kite.Shape;\n  Shape.prototype = {\n    constructor: Shape,\n    moveTo: function (x, y) {\n      return this.moveToPoint(v(x, y));\n    },\n    moveToRelative: function (x, y) {\n      return this.moveToPointRelative(v(x, y));\n    },\n    moveToPointRelative: function (point) {\n      return this.moveToPoint(this.getRelativePoint().plus(point));\n    },\n    moveToPoint: function (point) {\n      return this.addSubpath(new kite.Subpath().addPoint(point));\n    },\n    lineTo: function (x, y) {\n      return this.lineToPoint(v(x, y));\n    },\n    lineToRelative: function (x, y) {\n      return this.lineToPointRelative(v(x, y));\n    },\n    lineToPointRelative: function (point) {\n      return this.lineToPoint(this.getRelativePoint().plus(point));\n    },\n    lineToPoint: function (point) {\n      if (this.hasSubpaths()) {\n        var start = this.getLastSubpath().getLastPoint();\n        var end = point;\n        var line = new kite.Segment.Line(start, end);\n        this.getLastSubpath().addPoint(end);\n        if (!line.invalid) {\n          this.getLastSubpath().addSegment(line);\n          this.bounds = this.bounds.withPoint(start).withPoint(end);\n          null;\n        }\n      } else {\n        this.ensure(point);\n      }\n      return this;\n    },\n    horizontalLineTo: function (x) {\n      return this.lineTo(x, this.getRelativePoint().y);\n    },\n    horizontalLineToRelative: function (x) {\n      return this.lineToRelative(x, 0);\n    },\n    verticalLineTo: function (y) {\n      return this.lineTo(this.getRelativePoint().x, y);\n    },\n    verticalLineToRelative: function (y) {\n      return this.lineToRelative(0, y);\n    },\n    quadraticCurveTo: function (cpx, cpy, x, y) {\n      return this.quadraticCurveToPoint(v(cpx, cpy), v(x, y));\n    },\n    quadraticCurveToRelative: function (cpx, cpy, x, y) {\n      return this.quadraticCurveToPointRelative(v(cpx, cpy), v(x, y));\n    },\n    quadraticCurveToPointRelative: function (controlPoint, point) {\n      var relativePoint = this.getRelativePoint();\n      return this.quadraticCurveToPoint(relativePoint.plus(controlPoint), relativePoint.plus(point));\n    },\n    smoothQuadraticCurveTo: function (x, y) {\n      return this.quadraticCurveToPoint(this.getSmoothQuadraticControlPoint(), v(x, y));\n    },\n    smoothQuadraticCurveToRelative: function (x, y) {\n      return this.quadraticCurveToPoint(this.getSmoothQuadraticControlPoint(), v(x, y).plus(this.getRelativePoint()));\n    },\n    quadraticCurveToPoint: function (controlPoint, point) {\n      this.ensure(controlPoint);\n      var start = this.getLastSubpath().getLastPoint();\n      var quadratic = new kite.Segment.Quadratic(start, controlPoint, point);\n      this.getLastSubpath().addPoint(point);\n      if (!quadratic.invalid) {\n        this.getLastSubpath().addSegment(quadratic);\n        this.bounds = this.bounds.union(quadratic.bounds);\n      }\n      return this;\n    },\n    cubicCurveTo: function (cp1x, cp1y, cp2x, cp2y, x, y) {\n      return this.cubicCurveToPoint(v(cp1x, cp1y), v(cp2x, cp2y), v(x, y));\n    },\n    cubicCurveToRelative: function (cp1x, cp1y, cp2x, cp2y, x, y) {\n      return this.cubicCurveToPointRelative(v(cp1x, cp1y), v(cp2x, cp2y), v(x, y));\n    },\n    cubicCurveToPointRelative: function (control1, control2, point) {\n      var relativePoint = this.getRelativePoint();\n      return this.cubicCurveToPoint(relativePoint.plus(control1), relativePoint.plus(control2), relativePoint.plus(point));\n    },\n    smoothCubicCurveTo: function (cp2x, cp2y, x, y) {\n      return this.cubicCurveToPoint(this.getSmoothCubicControlPoint(), v(cp2x, cp2y), v(x, y));\n    },\n    smoothCubicCurveToRelative: function (cp2x, cp2y, x, y) {\n      return this.cubicCurveToPoint(this.getSmoothCubicControlPoint(), v(cp2x, cp2y).plus(this.getRelativePoint()), v(x, y).plus(this.getRelativePoint()));\n    },\n    cubicCurveToPoint: function (control1, control2, point) {\n      this.ensure(control1);\n      var start = this.getLastSubpath().getLastPoint();\n      var cubic = new kite.Segment.Cubic(start, control1, control2, point);\n      if (!cubic.invalid) {\n        if (cubic.hasCusp()) {\n          this.getLastSubpath().addSegment(cubic.startQuadratic);\n          this.getLastSubpath().addSegment(cubic.endQuadratic);\n        } else {\n          this.getLastSubpath().addSegment(cubic);\n        }\n        this.bounds = this.bounds.union(cubic.bounds);\n      }\n      this.getLastSubpath().addPoint(point);\n      return this;\n    },\n    arc: function (centerX, centerY, radius, startAngle, endAngle, anticlockwise) {\n      return this.arcPoint(v(centerX, centerY), radius, startAngle, endAngle, anticlockwise);\n    },\n    arcPoint: function (center, radius, startAngle, endAngle, anticlockwise) {\n      var arc = new kite.Segment.Arc(center, radius, startAngle, endAngle, anticlockwise);\n      var startPoint = arc.start;\n      var endPoint = arc.end;\n      if (this.hasSubpaths() && this.getLastSubpath().getLength() > 0 && !startPoint.equals(this.getLastSubpath().getLastPoint(), 0)) {\n        this.getLastSubpath().addSegment(new kite.Segment.Line(this.getLastSubpath().getLastPoint(), startPoint));\n      }\n      if (!this.hasSubpaths()) {\n        this.addSubpath(new kite.Subpath());\n      }\n      this.getLastSubpath().addPoint(startPoint);\n      this.getLastSubpath().addPoint(endPoint);\n      if (!arc.invalid) {\n        this.getLastSubpath().addSegment(arc);\n        this.bounds = this.bounds.union(arc.bounds);\n      }\n      return this;\n    },\n    ellipticalArc: function (centerX, centerY, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise) {\n      return this.ellipticalArcPoint(v(centerX, centerY), radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise);\n    },\n    ellipticalArcPoint: function (center, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise) {\n      var ellipticalArc = new kite.Segment.EllipticalArc(center, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise);\n      var startPoint = ellipticalArc.start;\n      var endPoint = ellipticalArc.end;\n      if (this.hasSubpaths() && this.getLastSubpath().getLength() > 0 && !startPoint.equals(this.getLastSubpath().getLastPoint(), 0)) {\n        this.getLastSubpath().addSegment(new kite.Segment.Line(this.getLastSubpath().getLastPoint(), startPoint));\n      }\n      if (!this.hasSubpaths()) {\n        this.addSubpath(new kite.Subpath());\n      }\n      this.getLastSubpath().addPoint(startPoint);\n      this.getLastSubpath().addPoint(endPoint);\n      if (!ellipticalArc.invalid) {\n        this.getLastSubpath().addSegment(ellipticalArc);\n        this.bounds = this.bounds.union(ellipticalArc.bounds);\n      }\n      return this;\n    },\n    close: function () {\n      if (this.hasSubpaths()) {\n        var previousPath = this.getLastSubpath();\n        var nextPath = new kite.Subpath();\n        previousPath.close();\n        this.addSubpath(nextPath);\n        nextPath.addPoint(previousPath.getFirstPoint());\n      }\n      return this;\n    },\n    ellipticalArcToRelative: function (radiusX, radiusY, rotation, largeArc, sweep, x, y) {\n      var relativePoint = this.getRelativePoint();\n      return this.ellipticalArcTo(radiusX, radiusY, rotation, largeArc, sweep, x + relativePoint.x, y + relativePoint.y);\n    },\n    ellipticalArcTo: function (radiusX, radiusY, rotation, largeArc, sweep, x, y) {\n      throw new Error('ellipticalArcTo unimplemented');\n    },\n    circle: function (centerX, centerY, radius) {\n      if (typeof centerX === 'object') {\n        var center = centerX;\n        radius = centerY;\n        return this.arcPoint(center, radius, 0, Math.PI * 2, false);\n      } else {\n        return this.arcPoint(p(centerX, centerY), radius, 0, Math.PI * 2, false);\n      }\n    },\n    ellipse: function (centerX, centerY, radiusX, radiusY, rotation) {\n      if (typeof centerX === 'object') {\n        var center = centerX;\n        rotation = radiusY;\n        radiusY = radiusX;\n        radiusX = centerY;\n        return this.ellipticalArcPoint(center, radiusX, radiusY, rotation || 0, 0, Math.PI * 2, false);\n      } else {\n        return this.ellipticalArcPoint(v(centerX, centerY), radiusX, radiusY, rotation || 0, 0, Math.PI * 2, false);\n      }\n    },\n    rect: function (x, y, width, height) {\n      var subpath = new kite.Subpath();\n      this.addSubpath(subpath);\n      subpath.addPoint(v(x, y));\n      subpath.addPoint(v(x + width, y));\n      subpath.addPoint(v(x + width, y + height));\n      subpath.addPoint(v(x, y + height));\n      subpath.addSegment(new kite.Segment.Line(subpath.points[0], subpath.points[1]));\n      subpath.addSegment(new kite.Segment.Line(subpath.points[1], subpath.points[2]));\n      subpath.addSegment(new kite.Segment.Line(subpath.points[2], subpath.points[3]));\n      subpath.close();\n      this.addSubpath(new kite.Subpath());\n      this.getLastSubpath().addPoint(v(x, y));\n      this.bounds = this.bounds.withCoordinates(x, y).withCoordinates(x + width, y + height);\n      null;\n      return this;\n    },\n    roundRect: function (x, y, width, height, arcw, arch) {\n      var lowX = x + arcw;\n      var highX = x + width - arcw;\n      var lowY = y + arch;\n      var highY = y + height - arch;\n      if (arcw === arch) {\n        this.arc(highX, lowY, arcw, -Math.PI / 2, 0, false).arc(highX, highY, arcw, 0, Math.PI / 2, false).arc(lowX, highY, arcw, Math.PI / 2, Math.PI, false).arc(lowX, lowY, arcw, Math.PI, Math.PI * 3 / 2, false).close();\n      } else {\n        this.ellipticalArc(highX, lowY, arcw, arch, 0, -Math.PI / 2, 0, false).ellipticalArc(highX, highY, arcw, arch, 0, 0, Math.PI / 2, false).ellipticalArc(lowX, highY, arcw, arch, 0, Math.PI / 2, Math.PI, false).ellipticalArc(lowX, lowY, arcw, arch, 0, Math.PI, Math.PI * 3 / 2, false).close();\n      }\n      return this;\n    },\n    polygon: function (vertices) {\n      var length = vertices.length;\n      if (length > 0) {\n        this.moveToPoint(vertices[0]);\n        for (var i = 1; i < length; i++) {\n          this.lineToPoint(vertices[i]);\n        }\n      }\n      return this.close();\n    },\n    copy: function () {\n      return new Shape(_.map(this.subpaths, function (subpath) {\n        return subpath.copy();\n      }), this.bounds);\n    },\n    writeToContext: function (context) {\n      var len = this.subpaths.length;\n      for (var i = 0; i < len; i++) {\n        this.subpaths[i].writeToContext(context);\n      }\n    },\n    getSVGPath: function () {\n      var subpathStrings = [];\n      var len = this.subpaths.length;\n      for (var i = 0; i < len; i++) {\n        var subpath = this.subpaths[i];\n        if (subpath.isDrawable()) {\n          var startPoint = subpath.getFirstSegment().start;\n          null;\n          var string = 'M ' + startPoint.x + ' ' + startPoint.y + ' ';\n          string += _.map(subpath.segments, function (segment) {\n            return segment.getSVGPathFragment();\n          }).join(' ');\n          if (subpath.isClosed()) {\n            string += ' Z';\n          }\n          subpathStrings.push(string);\n        }\n      }\n      return subpathStrings.join(' ');\n    },\n    transformed: function (matrix) {\n      var subpaths = _.map(this.subpaths, function (subpath) {\n          return subpath.transformed(matrix);\n        });\n      var bounds = _.reduce(subpaths, function (bounds, subpath) {\n          return bounds.union(subpath.computeBounds());\n        }, Bounds2.NOTHING);\n      return new Shape(subpaths, bounds);\n    },\n    computeBounds: function (lineStyles) {\n      if (lineStyles) {\n        return this.bounds.union(this.getStrokedShape(lineStyles).bounds);\n      } else {\n        return this.bounds;\n      }\n    },\n    containsPoint: function (point) {\n      var ray = new Ray2(point, Vector2.X_UNIT);\n      return this.windingIntersection(ray) !== 0;\n    },\n    intersection: function (ray) {\n      var hits = [];\n      var numSubpaths = this.subpaths.length;\n      for (var i = 0; i < numSubpaths; i++) {\n        var subpath = this.subpaths[i];\n        if (subpath.isDrawable()) {\n          var numSegments = subpath.segments.length;\n          for (var k = 0; k < numSegments; k++) {\n            var segment = subpath.segments[k];\n            hits = hits.concat(segment.intersection(ray));\n          }\n          if (subpath.hasClosingSegment()) {\n            hits = hits.concat(subpath.getClosingSegment().intersection(ray));\n          }\n        }\n      }\n      return _.sortBy(hits, function (hit) {\n        return hit.distance;\n      });\n    },\n    windingIntersection: function (ray) {\n      var wind = 0;\n      var numSubpaths = this.subpaths.length;\n      for (var i = 0; i < numSubpaths; i++) {\n        var subpath = this.subpaths[i];\n        if (subpath.isDrawable()) {\n          var numSegments = subpath.segments.length;\n          for (var k = 0; k < numSegments; k++) {\n            wind += subpath.segments[k].windingIntersection(ray);\n          }\n          if (subpath.hasClosingSegment()) {\n            wind += subpath.getClosingSegment().windingIntersection(ray);\n          }\n        }\n      }\n      return wind;\n    },\n    intersectsBounds: function (bounds) {\n      var numSubpaths = this.subpaths.length;\n      for (var i = 0; i < numSubpaths; i++) {\n        var subpath = this.subpaths[i];\n        if (subpath.isDrawable()) {\n          var numSegments = subpath.segments.length;\n          for (var k = 0; k < numSegments; k++) {\n            if (subpath.segments[k].intersectsBounds(bounds)) {\n              return true;\n            }\n          }\n          if (subpath.hasClosingSegment()) {\n            if (subpath.getClosingSegment().intersectsBounds(bounds)) {\n              return true;\n            }\n          }\n        }\n      }\n      return false;\n    },\n    getStrokedShape: function (lineStyles) {\n      var subpaths = [];\n      var bounds = Bounds2.NOTHING.copy();\n      var subLen = this.subpaths.length;\n      for (var i = 0; i < subLen; i++) {\n        var subpath = this.subpaths[i];\n        var strokedSubpath = subpath.stroked(lineStyles);\n        subpaths = subpaths.concat(strokedSubpath);\n      }\n      subLen = subpaths.length;\n      for (i = 0; i < subLen; i++) {\n        bounds.includeBounds(subpaths[i].computeBounds());\n      }\n      return new Shape(subpaths, bounds);\n    },\n    toString: function () {\n      return 'new kite.Shape( \\'' + this.getSVGPath() + '\\' )';\n    },\n    ensure: function (point) {\n      if (!this.hasSubpaths()) {\n        this.addSubpath(new Subpath());\n        this.getLastSubpath().addPoint(point);\n      }\n    },\n    addSubpath: function (subpath) {\n      this.subpaths.push(subpath);\n      return this;\n    },\n    hasSubpaths: function () {\n      return this.subpaths.length > 0;\n    },\n    getLastSubpath: function () {\n      return _.last(this.subpaths);\n    },\n    getLastPoint: function () {\n      return this.hasSubpaths() ? this.getLastSubpath().getLastPoint() : null;\n    },\n    getLastSegment: function () {\n      if (!this.hasSubpaths()) {\n        return null;\n      }\n      var subpath = this.getLastSubpath();\n      if (!subpath.isDrawable()) {\n        return null;\n      }\n      return subpath.getLastSegment();\n    },\n    getSmoothQuadraticControlPoint: function () {\n      var lastPoint = this.getLastPoint();\n      var segment = this.getLastSegment();\n      if (!segment || !(segment instanceof kite.Segment.Quadratic)) {\n        return lastPoint;\n      }\n      return lastPoint.plus(lastPoint.minus(segment.control));\n    },\n    getSmoothCubicControlPoint: function () {\n      var lastPoint = this.getLastPoint();\n      var segment = this.getLastSegment();\n      if (!segment || !(segment instanceof kite.Segment.Cubic)) {\n        return lastPoint;\n      }\n      return lastPoint.plus(lastPoint.minus(segment.control2));\n    },\n    getRelativePoint: function () {\n      var lastPoint = this.getLastPoint();\n      return lastPoint ? lastPoint : Vector2.ZERO;\n    }\n  };\n  Shape.rectangle = function (x, y, width, height) {\n    return new Shape().rect(x, y, width, height);\n  };\n  Shape.rect = Shape.rectangle;\n  Shape.roundRect = function (x, y, width, height, arcw, arch) {\n    return new Shape().roundRect(x, y, width, height, arcw, arch);\n  };\n  Shape.roundRectangle = Shape.roundRect;\n  Shape.polygon = function (vertices) {\n    return new Shape().polygon(vertices);\n  };\n  Shape.bounds = function (bounds) {\n    return new Shape().rect(bounds.minX, bounds.minY, bounds.maxX - bounds.minX, bounds.maxY - bounds.minY);\n  };\n  Shape.lineSegment = function (a, b, c, d) {\n    if (typeof a === 'number') {\n      return new Shape().moveTo(a, b).lineTo(c, d);\n    } else {\n      return new Shape().moveToPoint(a).lineToPoint(b);\n    }\n  };\n  Shape.regularPolygon = function (sides, radius) {\n    var shape = new Shape();\n    _.each(_.range(sides), function (k) {\n      var point = Vector2.createPolar(radius, 2 * Math.PI * k / sides);\n      k === 0 ? shape.moveToPoint(point) : shape.lineToPoint(point);\n    });\n    return shape.close();\n  };\n  Shape.circle = function (centerX, centerY, radius) {\n    if (centerY === undefined) {\n      return new Shape().circle(0, 0, centerX);\n    }\n    return new Shape().circle(centerX, centerY, radius).close();\n  };\n  Shape.ellipse = function (centerX, centerY, radiusX, radiusY) {\n    if (radiusX === undefined) {\n      return new Shape().ellipse(0, 0, centerX, centerY);\n    }\n    return new Shape().ellipse(centerX, centerY, radiusX, radiusY).close();\n  };\n  Shape.arc = function (centerX, centerY, radius, startAngle, endAngle, anticlockwise) {\n    return new Shape().arc(centerX, centerY, radius, startAngle, endAngle, anticlockwise);\n  };\n  return Shape;\n});",
    "\ndefine('PHETCOMMON/model/Bucket',['require','DOT/Vector2','DOT/Dimension2','KITE/Shape'],function (require) {\n  'use strict';\n  var Vector2 = require('DOT/Vector2');\n  var Dimension2 = require('DOT/Dimension2');\n  var Shape = require('KITE/Shape');\n  var HOLE_ELLIPSE_HEIGHT_PROPORTION = 0.25;\n  var Bucket = function (options) {\n    options = _.extend({\n      position: options.position || Vector2.ZERO,\n      size: new Dimension2(options.width || 200, options.height || 50),\n      baseColor: '#ff0000',\n      caption: 'Set a caption!',\n      captionColor: 'white'\n    }, options);\n    this.position = options.position;\n    this.baseColor = options.baseColor;\n    this.captionText = options.caption;\n    this.captionColor = options.captionColor;\n    this.size = options.size;\n    var size = this.size;\n    var holeRadiusX = size.width / 2;\n    var holeRadiusY = size.height * HOLE_ELLIPSE_HEIGHT_PROPORTION / 2;\n    this.holeShape = Shape.ellipse(0, 0, holeRadiusX, holeRadiusY);\n    var containerHeight = size.height * (1 - HOLE_ELLIPSE_HEIGHT_PROPORTION / 2);\n    this.containerShape = new Shape().moveTo(-size.width * 0.5, 0).lineTo(-size.width * 0.4, -containerHeight * 0.8).cubicCurveTo(-size.width * 0.3, -containerHeight * 0.8 - size.height * HOLE_ELLIPSE_HEIGHT_PROPORTION * 0.6, size.width * 0.3, -containerHeight * 0.8 - size.height * HOLE_ELLIPSE_HEIGHT_PROPORTION * 0.6, size.width * 0.4, -containerHeight * 0.8).lineTo(size.width * 0.5, 0).ellipticalArc(0, 0, holeRadiusX, holeRadiusY, 0, 0, Math.PI, true).close();\n  };\n  return Bucket;\n});",
    "\ndefine('PHETCOMMON/model/SphereBucket',['require','DOT/Vector2','PHET_CORE/inherit','PHETCOMMON/model/Bucket'],function (require) {\n  'use strict';\n  var Vector2 = require('DOT/Vector2');\n  var inherit = require('PHET_CORE/inherit');\n  var Bucket = require('PHETCOMMON/model/Bucket');\n  function SphereBucket(options) {\n    Bucket.call(this, options);\n    this._sphereRadius = options.sphereRadius || 10;\n    this._usableWidthProportion = options.usableWidthProportion || 1;\n    this._verticalParticleOffset = options.verticalParticleOffset === undefined ? -this._sphereRadius * 0.4 : options.verticalParticleOffset;\n    this._particles = [];\n  }\n  inherit(Bucket, SphereBucket);\n  SphereBucket.prototype.addParticleFirstOpen = function (particle, animate) {\n    particle.destination = this._getFirstOpenLocation();\n    if (!animate) {\n      particle.position = particle.destination;\n    }\n    this._particles.push(particle);\n    var thisBucket = this;\n    particle.userControlledProperty.once(function (userControlled) {\n      if (userControlled) {\n        thisBucket.removeParticle(particle);\n      }\n    });\n  };\n  SphereBucket.prototype.addParticleNearestOpen = function (particle, animate) {\n    particle.destination = this.getNearestOpenLocation(particle.destination);\n    if (!animate) {\n      particle.position = particle.destination;\n    }\n    this._particles.push(particle);\n    var thisBucket = this;\n    particle.userControlledProperty.once(function (userControlled) {\n      if (userControlled) {\n        thisBucket.removeParticle(particle);\n      }\n    });\n  };\n  SphereBucket.prototype.removeParticle = function (particle, skipLayout) {\n    if (this._particles.indexOf(particle) === -1) {\n      console.log('Error: Attempt to remove particle not contained in bucket, ignoring.');\n      return;\n    }\n    this._particles = _.without(this._particles, particle);\n    if (!skipLayout) {\n      this.relayoutBucketParticles();\n    }\n  };\n  SphereBucket.prototype.containsParticle = function (particle) {\n    return this._particles.indexOf(particle) !== -1;\n  };\n  SphereBucket.prototype.extractClosestParticle = function (location) {\n    var closestParticle = null;\n    this._particles.forEach(function (particle) {\n      if (closestParticle === null || closestParticle.position.distance(location) > particle.position.distance(location)) {\n        closestParticle = particle;\n      }\n    });\n    if (closestParticle !== null) {\n      closestParticle.userControlled = true;\n    }\n    return closestParticle;\n  };\n  SphereBucket.prototype.getParticleList = function () {\n    return this._particles;\n  };\n  SphereBucket.prototype._isPositionOpen = function (position) {\n    var positionOpen = true;\n    for (var i = 0; i < this._particles.length; i++) {\n      var particle = this._particles[i];\n      if (particle.destination.equals(position)) {\n        positionOpen = false;\n        break;\n      }\n    }\n    return positionOpen;\n  };\n  SphereBucket.prototype._getFirstOpenLocation = function () {\n    var openLocation = Vector2.ZERO;\n    var usableWidth = this.size.width * this._usableWidthProportion - 2 * this._sphereRadius;\n    var offsetFromBucketEdge = (this.size.width - usableWidth) / 2 + this._sphereRadius;\n    var numParticlesInLayer = Math.floor(usableWidth / (this._sphereRadius * 2));\n    var row = 0;\n    var positionInLayer = 0;\n    var found = false;\n    while (!found) {\n      var testLocation = new Vector2(this.position.x - this.size.width / 2 + offsetFromBucketEdge + positionInLayer * 2 * this._sphereRadius, this._getYPositionForLayer(row));\n      if (this._isPositionOpen(testLocation)) {\n        openLocation = testLocation;\n        found = true;\n        continue;\n      } else {\n        positionInLayer++;\n        if (positionInLayer >= numParticlesInLayer) {\n          row++;\n          positionInLayer = 0;\n          numParticlesInLayer--;\n          offsetFromBucketEdge += this._sphereRadius;\n          if (numParticlesInLayer === 0) {\n            numParticlesInLayer = 1;\n            offsetFromBucketEdge -= this._sphereRadius;\n          }\n        }\n      }\n    }\n    return openLocation;\n  };\n  SphereBucket.prototype._getLayerForYPosition = function (yPosition) {\n    return Math.abs(Math.round((yPosition - (this.position.y + this._verticalParticleOffset)) / (this._sphereRadius * 2 * 0.866)));\n  };\n  SphereBucket.prototype.getNearestOpenLocation = function (position) {\n    var highestOccupiedLayer = 0;\n    var self = this;\n    _.each(this._particles, function (particle) {\n      var layer = self._getLayerForYPosition(particle.destination.y);\n      if (layer > highestOccupiedLayer) {\n        highestOccupiedLayer = layer;\n      }\n    });\n    var openLocations = [];\n    var usableWidth = this.size.width * this._usableWidthProportion - 2 * this._sphereRadius;\n    var offsetFromBucketEdge = (this.size.width - usableWidth) / 2 + this._sphereRadius;\n    var numParticlesInLayer = Math.floor(usableWidth / (this._sphereRadius * 2));\n    for (var layer = 0; layer <= highestOccupiedLayer + 1; layer++) {\n      for (var positionInLayer = 0; positionInLayer < numParticlesInLayer; positionInLayer++) {\n        var testPosition = new Vector2(this.position.x - this.size.width / 2 + offsetFromBucketEdge + positionInLayer * 2 * this._sphereRadius, this._getYPositionForLayer(layer));\n        if (this._isPositionOpen(testPosition)) {\n          if (layer === 0 || this.countSupportingParticles(testPosition) === 2) {\n            openLocations.push(testPosition);\n          }\n        }\n      }\n      numParticlesInLayer--;\n      offsetFromBucketEdge += this._sphereRadius;\n      if (numParticlesInLayer === 0) {\n        numParticlesInLayer = 1;\n        offsetFromBucketEdge -= this._sphereRadius;\n      }\n    }\n    var closestOpenLocation = openLocations[0] || Vector2.ZERO;\n    _.each(openLocations, function (location) {\n      if (location.distance(position) < closestOpenLocation.distance(position)) {\n        closestOpenLocation = location;\n      }\n    });\n    return closestOpenLocation;\n  };\n  SphereBucket.prototype._getYPositionForLayer = function (layer) {\n    return this.position.y + this._verticalParticleOffset + layer * this._sphereRadius * 2 * 0.866;\n  };\n  SphereBucket.prototype._isDangling = function (particle) {\n    var onBottomRow = particle.destination.y === this.position.y + this._verticalParticleOffset;\n    return !onBottomRow && this.countSupportingParticles(particle.destination) < 2;\n  };\n  SphereBucket.prototype.countSupportingParticles = function (position) {\n    var count = 0;\n    for (var i = 0; i < this._particles.length; i++) {\n      var p = this._particles[i];\n      if (p.destination.y < position.y && p.destination.distance(position) < this._sphereRadius * 3) {\n        count++;\n      }\n    }\n    return count;\n  };\n  SphereBucket.prototype.relayoutBucketParticles = function () {\n    var particleMoved;\n    do {\n      for (var i = 0; i < this._particles.length; i++) {\n        particleMoved = false;\n        var particle = this._particles[i];\n        if (this._isDangling(particle)) {\n          particle.destination = this.getNearestOpenLocation(particle.destination);\n          particleMoved = true;\n          break;\n        }\n      }\n    } while (particleMoved);\n  };\n  return SphereBucket;\n});",
    "\ndefine('common/model/BuildAnAtomModel',['require','common/AtomIdentifier','PHET_CORE/callSuper','DOT/Dimension2','PHET_CORE/inherit','common/model/NumberAtom','common/model/Particle','common/model/ParticleAtom','AXON/PropertySet','common/SharedConstants','PHETCOMMON/model/SphereBucket','DOT/Vector2'],function (require) {\n  'use strict';\n  var AtomIdentifier = require('common/AtomIdentifier');\n  var callSuper = require('PHET_CORE/callSuper');\n  var Dimension2 = require('DOT/Dimension2');\n  var inherit = require('PHET_CORE/inherit');\n  var NumberAtom = require('common/model/NumberAtom');\n  var Particle = require('common/model/Particle');\n  var ParticleAtom = require('common/model/ParticleAtom');\n  var PropertySet = require('AXON/PropertySet');\n  var SharedConstants = require('common/SharedConstants');\n  var SphereBucket = require('PHETCOMMON/model/SphereBucket');\n  var Vector2 = require('DOT/Vector2');\n  var NUM_PROTONS = 10;\n  var NUM_NEUTRONS = 13;\n  var NUM_ELECTRONS = 10;\n  var NUCLEON_CAPTURE_RADIUS = 100;\n  var BUCKET_WIDTH = 120;\n  var BUCKET_HEIGHT = BUCKET_WIDTH * 0.45;\n  var BUCKET_Y_OFFSET = -225;\n  var NUCLEUS_JUMP_PERIOD = 0.1;\n  var MAX_NUCLEUS_JUMP = SharedConstants.NUCLEON_RADIUS * 0.5;\n  var JUMP_ANGLES = [\n      Math.PI * 0.1,\n      Math.PI * 1.6,\n      Math.PI * 0.7,\n      Math.PI * 1.1,\n      Math.PI * 0.3\n    ];\n  var JUMP_DISTANCES = [\n      MAX_NUCLEUS_JUMP * 0.4,\n      MAX_NUCLEUS_JUMP * 0.8,\n      MAX_NUCLEUS_JUMP * 0.2,\n      MAX_NUCLEUS_JUMP * 0.9\n    ];\n  function BuildAnAtomModel() {\n    PropertySet.call(this, {\n      showElementName: true,\n      showNeutralOrIon: true,\n      showStableOrUnstable: false,\n      electronShellDepiction: 'orbits'\n    });\n    var thisModel = this;\n    this.particleAtom = new ParticleAtom();\n    this.buckets = {\n      protonBucket: new SphereBucket({\n        position: new Vector2(-BUCKET_WIDTH * 1.1, BUCKET_Y_OFFSET),\n        size: new Dimension2(BUCKET_WIDTH, BUCKET_HEIGHT),\n        sphereRadius: SharedConstants.NUCLEON_RADIUS,\n        baseColor: 'red',\n        caption: 'Protons',\n        captionColor: 'white'\n      }),\n      neutronBucket: new SphereBucket({\n        position: new Vector2(0, BUCKET_Y_OFFSET),\n        size: new Dimension2(BUCKET_WIDTH, BUCKET_HEIGHT),\n        sphereRadius: SharedConstants.NUCLEON_RADIUS,\n        baseColor: 'rgb( 100, 100, 100 )',\n        caption: 'Neutrons',\n        captionColor: 'white'\n      }),\n      electronBucket: new SphereBucket({\n        position: new Vector2(BUCKET_WIDTH * 1.1, BUCKET_Y_OFFSET),\n        size: new Dimension2(BUCKET_WIDTH, BUCKET_HEIGHT),\n        sphereRadius: SharedConstants.ELECTRON_RADIUS,\n        usableWidthProportion: 0.8,\n        baseColor: 'blue',\n        caption: 'Electrons',\n        captionColor: 'white'\n      })\n    };\n    var placeNucleon = function (particle, bucket, atom) {\n      if (particle.position.distance(atom.position) < NUCLEON_CAPTURE_RADIUS) {\n        atom.addParticle(particle);\n      } else {\n        bucket.addParticleNearestOpen(particle, true);\n      }\n    };\n    this.nucleons = [];\n    this.electrons = [];\n    _.times(NUM_PROTONS, function () {\n      var proton = new Particle('proton');\n      thisModel.nucleons.push(proton);\n      thisModel.buckets.protonBucket.addParticleFirstOpen(proton, false);\n      proton.userControlledProperty.link(function (userControlled) {\n        if (!userControlled && !thisModel.buckets.protonBucket.containsParticle(proton)) {\n          placeNucleon(proton, thisModel.buckets.protonBucket, thisModel.particleAtom);\n        }\n      });\n    });\n    _.times(NUM_NEUTRONS, function () {\n      var neutron = new Particle('neutron');\n      thisModel.nucleons.push(neutron);\n      thisModel.buckets.neutronBucket.addParticleFirstOpen(neutron, false);\n      neutron.userControlledProperty.link(function (userControlled) {\n        if (!userControlled && !thisModel.buckets.neutronBucket.containsParticle(neutron)) {\n          placeNucleon(neutron, thisModel.buckets.neutronBucket, thisModel.particleAtom);\n        }\n      });\n    });\n    _.times(NUM_ELECTRONS, function () {\n      var electron = new Particle('electron');\n      thisModel.electrons.push(electron);\n      thisModel.buckets.electronBucket.addParticleFirstOpen(electron, false);\n      electron.userControlledProperty.link(function (userControlled) {\n        if (!userControlled && !thisModel.buckets.electronBucket.containsParticle(electron)) {\n          if (electron.position.distance(Vector2.ZERO) < thisModel.particleAtom.outerElectronShellRadius * 1.1) {\n            thisModel.particleAtom.addParticle(electron);\n          } else {\n            thisModel.buckets.electronBucket.addParticleNearestOpen(electron, true);\n          }\n        }\n      });\n    });\n    this.numberAtom = new NumberAtom();\n    var updateNumberAtom = function () {\n      thisModel.numberAtom.protonCount = thisModel.particleAtom.protons.length;\n      thisModel.numberAtom.neutronCount = thisModel.particleAtom.neutrons.length;\n      thisModel.numberAtom.electronCount = thisModel.particleAtom.electrons.length;\n    };\n    this.particleAtom.protons.lengthProperty.link(updateNumberAtom);\n    this.particleAtom.electrons.lengthProperty.link(updateNumberAtom);\n    this.particleAtom.neutrons.lengthProperty.link(updateNumberAtom);\n    this.nucleusStable = true;\n    this.nucleusJumpCountdown = NUCLEUS_JUMP_PERIOD;\n    this.nucleusOffset = Vector2.ZERO;\n    this.numberAtom.massNumberProperty.link(function (massNumber) {\n      var stable = massNumber > 0 ? AtomIdentifier.isStable(thisModel.numberAtom.protonCount, thisModel.numberAtom.neutronCount) : true;\n      if (thisModel.nucleusStable !== stable) {\n        thisModel.nucleusStable = stable;\n        if (stable) {\n          thisModel.nucleusJumpCountdown = NUCLEUS_JUMP_PERIOD;\n          thisModel.particleAtom.nucleusOffset = Vector2.ZERO;\n        }\n      }\n    });\n    this.showStableOrUnstableProperty.link(function (showStableOrUnstable) {\n      if (!showStableOrUnstable) {\n        thisModel.particleAtom.nucleusOffset = Vector2.ZERO;\n      }\n    });\n  }\n  inherit(PropertySet, BuildAnAtomModel, {\n    _nucleusJumpCount: 0,\n    step: function (dt) {\n      this.nucleons.forEach(function (nucleon) {\n        nucleon.step(dt);\n      });\n      this.electrons.forEach(function (electron) {\n        electron.step(dt);\n      });\n      if (this.nucleusStable === false && this.showStableOrUnstable) {\n        this.nucleusJumpCountdown -= dt;\n        if (this.nucleusJumpCountdown <= 0) {\n          this.nucleusJumpCountdown = NUCLEUS_JUMP_PERIOD;\n          if (this.particleAtom.nucleusOffset === Vector2.ZERO) {\n            this._nucleusJumpCount++;\n            var angle = JUMP_ANGLES[this._nucleusJumpCount % JUMP_ANGLES.length];\n            var distance = JUMP_DISTANCES[this._nucleusJumpCount % JUMP_DISTANCES.length];\n            this.particleAtom.nucleusOffset = new Vector2(Math.cos(angle) * distance, Math.sin(angle) * distance);\n          } else {\n            this.particleAtom.nucleusOffset = Vector2.ZERO;\n          }\n        }\n      }\n    },\n    _moveParticlesFromAtomToBucket: function (particleCollection, bucket) {\n      var particlesToRemove = [];\n      for (var i = 0; i < particleCollection.length; i++) {\n        particlesToRemove[i] = particleCollection.get(i);\n      }\n      particleCollection.clear();\n      _.each(particlesToRemove, function (particle) {\n        bucket.addParticleFirstOpen(particle);\n      }, this);\n    },\n    reset: function () {\n      callSuper(PropertySet, 'reset', this);\n      this._moveParticlesFromAtomToBucket(this.particleAtom.protons, this.buckets.protonBucket);\n      this._moveParticlesFromAtomToBucket(this.particleAtom.neutrons, this.buckets.neutronBucket);\n      this._moveParticlesFromAtomToBucket(this.particleAtom.electrons, this.buckets.electronBucket);\n      this.nucleons.forEach(function (nucleon) {\n        if (!nucleon.position.equals(nucleon.destination)) {\n          nucleon.moveImmediatelyToDestination();\n        }\n      });\n      this.electrons.forEach(function (electron) {\n        if (!electron.position.equals(electron.destination)) {\n          electron.moveImmediatelyToDestination();\n        }\n      });\n    },\n    setAtomConfiguration: function (numberAtom) {\n      var atomCenter = this.particleAtom.position;\n      var moveParticlesToAtom = function (currentCountInAtom, targetCountInAtom, particlesInAtom, bucket) {\n        while (currentCountInAtom < targetCountInAtom) {\n          var particle = bucket.extractClosestParticle(atomCenter);\n          particle.setPositionAndDestination(atomCenter);\n          particle.userControlled = false;\n          currentCountInAtom++;\n        }\n        while (currentCountInAtom > targetCountInAtom) {\n          this._moveParticlesFromAtomToBucket(particlesInAtom, bucket);\n          currentCountInAtom--;\n        }\n      };\n      moveParticlesToAtom(this.particleAtom.protons.length, numberAtom.protonCount, this.particleAtom.protons, this.buckets.protonBucket);\n      moveParticlesToAtom(this.particleAtom.neutrons.length, numberAtom.neutronCount, this.particleAtom.neutrons, this.buckets.neutronBucket);\n      moveParticlesToAtom(this.particleAtom.electrons.length, numberAtom.electronCount, this.particleAtom.electrons, this.buckets.electronBucket);\n      this.particleAtom.moveAllParticlesToDestination();\n    }\n  });\n  return BuildAnAtomModel;\n});",
    "\ndefine('SCENERY/scenery',['require','ASSERT/assert','PHET_CORE/phetAllocation'],function (require) {\n  'use strict';\n  window.sceneryAssert = null;\n  window.sceneryAssertExtra = require('ASSERT/assert')('scenery.extra');\n  window.sceneryLayerLog = null;\n  window.sceneryEventLog = null;\n  window.sceneryAccessibilityLog = null;\n  window.phetAllocation = require('PHET_CORE/phetAllocation');\n  var scratchCanvas = document.createElement('canvas');\n  var scratchContext = scratchCanvas.getContext('2d');\n  return {\n    assert: null,\n    scratchCanvas: scratchCanvas,\n    scratchContext: scratchContext,\n    enableLayerLogging: function () {\n      window.sceneryLayerLog = function (ob) {\n        console.log(ob);\n      };\n    },\n    disableLayerLogging: function () {\n      window.sceneryLayerLog = null;\n    },\n    enableEventLogging: function () {\n      window.sceneryEventLog = function (ob) {\n        console.log(ob);\n      };\n    },\n    disableEventLogging: function () {\n      window.sceneryEventLog = null;\n    },\n    enableAccessibilityLogging: function () {\n      window.sceneryAccessibilityLog = function (ob) {\n        console.log(ob);\n      };\n    },\n    disableAccessibilityLogging: function () {\n      window.sceneryAccessibilityLog = null;\n    }\n  };\n});",
    "\ndefine('SCENERY/util/FixedNodeEvents',['require','SCENERY/scenery'],function (require) {\n  'use strict';\n  var scenery = require('SCENERY/scenery');\n  var eventNames = [\n      'selfBounds',\n      'childBounds',\n      'bounds',\n      'resize',\n      'boundsAccuracy'\n    ];\n  scenery.FixedNodeEvents = function FixedNodeEvents(type) {\n    var proto = type.prototype;\n    proto.initializeNodeEvents = function () {\n      this._events = {};\n      var node = this;\n      var len = eventNames.length;\n      for (var i = 0; i < len; i++) {\n        node._events[eventNames[i]] = [];\n      }\n    };\n    proto.addEventListener = function (type, listener) {\n      sceneryAssert && sceneryAssert(type !== undefined && listener !== undefined, 'Both a type and listener are required for addEventListener');\n      sceneryAssert && sceneryAssert(_.indexOf(this._events[type], listener), 'Event listener was already there for addEventListener with type ' + type);\n      this._events[type].push(listener);\n      return this;\n    };\n    proto.removeEventListener = function (type, listener) {\n      sceneryAssert && sceneryAssert(type !== undefined && listener !== undefined, 'Both a type and listener are required for removeEventListener');\n      sceneryAssert && sceneryAssert(_.indexOf(this._events[type], listener) !== -1, 'Listener did not exist for type ' + type);\n      this._events[type].splice(_.indexOf(this._events[type], listener), 1);\n      return this;\n    };\n    proto.fireEvent = function (type, args) {\n      sceneryAssert && sceneryAssert(_.contains(eventNames, type), 'unknown event type: ' + type);\n      var events = this._events[type];\n      var len = events.length;\n      if (len) {\n        var copy = events.slice(0);\n        for (var i = 0; i < len; i++) {\n          copy[i](args);\n        }\n      }\n    };\n  };\n  var FixedNodeEvents = scenery.FixedNodeEvents;\n  return FixedNodeEvents;\n});",
    "\ndefine('SCENERY/layers/LayerStrategy',['require','SCENERY/scenery'],function (require) {\n  'use strict';\n  var scenery = require('SCENERY/scenery');\n  scenery.LayerStrategy = {\n    hasPreferredLayerType: function (pointer, layerBuilder) {\n      return pointer.trail.lastNode().hasRenderer();\n    },\n    getPreferredLayerType: function (pointer, layerBuilder) {\n      sceneryAssert && sceneryAssert(this.hasPreferredLayerType(pointer, layerBuilder));\n      var node = pointer.trail.lastNode();\n      var preferredLayerType;\n      if (node.hasRendererLayerType()) {\n        preferredLayerType = node.getRendererLayerType();\n      } else {\n        preferredLayerType = layerBuilder.bestPreferredLayerTypeFor([node.getRenderer()]);\n        if (!preferredLayerType) {\n          preferredLayerType = node.getRenderer().defaultLayerType;\n        }\n      }\n      return preferredLayerType;\n    },\n    enter: function (pointer, layerBuilder) {\n      var trail = pointer.trail;\n      var node = trail.lastNode();\n      var preferredLayerType;\n      if (node.hasRenderer()) {\n        preferredLayerType = this.getPreferredLayerType(pointer, layerBuilder);\n        layerBuilder.pushPreferredLayerType(preferredLayerType);\n        if (layerBuilder.getCurrentLayerType() !== preferredLayerType) {\n          layerBuilder.switchToType(pointer, preferredLayerType);\n        }\n      } else if (node.isPainted()) {\n        var supportedRenderers = node._supportedRenderers;\n        var currentType = layerBuilder.getCurrentLayerType();\n        preferredLayerType = layerBuilder.bestPreferredLayerTypeFor(supportedRenderers);\n        if (preferredLayerType) {\n          if (currentType !== preferredLayerType) {\n            layerBuilder.switchToType(pointer, preferredLayerType);\n          }\n        } else {\n          if (!currentType || !currentType.supportsNode(node)) {\n            layerBuilder.switchToType(pointer, supportedRenderers[0].defaultLayerType);\n          }\n        }\n      }\n      if (node.isLayerSplitBefore() || this.hasSplitFlags(node)) {\n        layerBuilder.switchToType(pointer, layerBuilder.getCurrentLayerType());\n      }\n      if (node.isPainted()) {\n        layerBuilder.markPainted(pointer);\n      }\n    },\n    exit: function (pointer, layerBuilder) {\n      var trail = pointer.trail;\n      var node = trail.lastNode();\n      if (node.hasRenderer()) {\n        layerBuilder.popPreferredLayerType();\n      }\n      if (node.isLayerSplitAfter() || this.hasSplitFlags(node)) {\n        layerBuilder.switchToType(pointer, layerBuilder.getCurrentLayerType());\n      }\n    },\n    hasSplitFlags: function (node) {\n      var rendererOptions = node.getRendererOptions();\n      return node.hasRenderer() && rendererOptions && (rendererOptions.cssTranslation || rendererOptions.cssRotation || rendererOptions.cssScale || rendererOptions.cssTransform);\n    }\n  };\n  var LayerStrategy = scenery.LayerStrategy;\n  return LayerStrategy;\n});",
    "\ndefine('SCENERY/nodes/Node',['require','DOT/Bounds2','DOT/Transform3','DOT/Matrix3','DOT/Vector2','DOT/Util','KITE/Shape','SCENERY/scenery','SCENERY/util/FixedNodeEvents','SCENERY/layers/LayerStrategy'],function (require) {\n  'use strict';\n  var Bounds2 = require('DOT/Bounds2');\n  var Transform3 = require('DOT/Transform3');\n  var Matrix3 = require('DOT/Matrix3');\n  var Vector2 = require('DOT/Vector2');\n  var clamp = require('DOT/Util').clamp;\n  var Shape = require('KITE/Shape');\n  var scenery = require('SCENERY/scenery');\n  var NodeEvents = require('SCENERY/util/FixedNodeEvents');\n  var LayerStrategy = require('SCENERY/layers/LayerStrategy');\n  var globalIdCounter = 1;\n  scenery.Node = function Node(options) {\n    var self = this;\n    this._id = globalIdCounter++;\n    this._instances = [];\n    this._visible = true;\n    this._opacity = 1;\n    this._pickable = true;\n    this._clipShape = null;\n    this._mouseArea = null;\n    this._touchArea = null;\n    this._cursor = null;\n    this._children = [];\n    this._parents = [];\n    this._peers = [];\n    this._liveRegions = [];\n    this._transform = new Transform3();\n    this._transformListener = {\n      before: function () {\n        self.beforeTransformChange();\n      },\n      after: function () {\n        self.afterTransformChange();\n      }\n    };\n    this._transform.addTransformListener(this._transformListener);\n    this._inputListeners = [];\n    this.initializeNodeEvents();\n    this._includeStrokeInHitRegion = false;\n    this._bounds = Bounds2.NOTHING;\n    this._selfBounds = Bounds2.NOTHING;\n    this._childBounds = Bounds2.NOTHING;\n    this._boundsDirty = true;\n    this._selfBoundsDirty = this.isPainted();\n    this._childBoundsDirty = true;\n    this._mouseBounds = null;\n    this._mouseBoundsDirty = true;\n    this._touchBounds = null;\n    this._touchBoundsDirty = true;\n    this._paintDirty = false;\n    this._subtreePaintDirty = false;\n    this._childPaintDirty = false;\n    this._renderer = null;\n    this._rendererOptions = null;\n    this._rendererLayerType = null;\n    this._layerSplitBefore = false;\n    this._layerSplitAfter = false;\n    if (options) {\n      this.mutate(options);\n    }\n    phetAllocation && phetAllocation('Node');\n  };\n  var Node = scenery.Node;\n  Node.prototype = {\n    constructor: Node,\n    insertChild: function (index, node) {\n      sceneryAssert && sceneryAssert(node !== null && node !== undefined, 'insertChild cannot insert a null/undefined child');\n      sceneryAssert && sceneryAssert(!_.contains(this._children, node), 'Parent already contains child');\n      sceneryAssert && sceneryAssert(node !== this, 'Cannot add self as a child');\n      node._parents.push(this);\n      this._children.splice(index, 0, node);\n      node.invalidateBounds();\n      this._boundsDirty = true;\n      this.markForInsertion(node, index);\n      this.notifyStitch(false);\n      node.invalidateSubtreePaint();\n    },\n    addChild: function (node) {\n      this.insertChild(this._children.length, node);\n    },\n    removeChild: function (node) {\n      sceneryAssert && sceneryAssert(node);\n      sceneryAssert && sceneryAssert(this.isChild(node));\n      var indexOfChild = _.indexOf(this._children, node);\n      this.removeChildWithIndex(node, indexOfChild);\n    },\n    removeChildAt: function (index) {\n      sceneryAssert && sceneryAssert(index >= 0);\n      sceneryAssert && sceneryAssert(index < this._children.length);\n      var node = this._children[index];\n      this.removeChildWithIndex(node, index);\n    },\n    removeChildWithIndex: function (node, indexOfChild) {\n      sceneryAssert && sceneryAssert(node);\n      sceneryAssert && sceneryAssert(this.isChild(node));\n      sceneryAssert && sceneryAssert(this._children[indexOfChild] === node);\n      node.markOldPaint(false);\n      var indexOfParent = _.indexOf(node._parents, this);\n      this.markForRemoval(node, indexOfChild);\n      node._parents.splice(indexOfParent, 1);\n      this._children.splice(indexOfChild, 1);\n      this.invalidateBounds();\n      this._childBoundsDirty = true;\n      this.notifyStitch(false);\n    },\n    removeAllChildren: function () {\n      this.setChildren([]);\n    },\n    setChildren: function (children) {\n      if (this._children !== children) {\n        while (this._children.length) {\n          this.removeChild(this._children[this._children.length - 1]);\n        }\n        var len = children.length;\n        for (var i = 0; i < len; i++) {\n          this.addChild(children[i]);\n        }\n      }\n    },\n    getChildren: function () {\n      return this._children.slice(0);\n    },\n    getChildrenCount: function () {\n      return this._children.length;\n    },\n    getParents: function () {\n      return this._parents.slice(0);\n    },\n    getParent: function () {\n      sceneryAssert && sceneryAssert(this._parents.length <= 1, 'Cannot call getParent on a node with multiple parents');\n      return this._parents.length ? this._parents[0] : null;\n    },\n    getChildAt: function (index) {\n      return this._children[index];\n    },\n    indexOfParent: function (parent) {\n      return _.indexOf(this._parents, parent);\n    },\n    indexOfChild: function (child) {\n      return _.indexOf(this._children, child);\n    },\n    moveToFront: function () {\n      var self = this;\n      _.each(this._parents.slice(0), function (parent) {\n        parent.moveChildToFront(self);\n      });\n    },\n    moveChildToFront: function (child) {\n      if (this.indexOfChild(child) !== this._children.length - 1) {\n        this.removeChild(child);\n        this.addChild(child);\n      }\n    },\n    moveToBack: function () {\n      var self = this;\n      _.each(this._parents.slice(0), function (parent) {\n        parent.moveChildToBack(self);\n      });\n    },\n    moveChildToBack: function (child) {\n      if (this.indexOfChild(child) !== 0) {\n        this.removeChild(child);\n        this.insertChild(0, child);\n      }\n    },\n    detach: function () {\n      var that = this;\n      _.each(this._parents.slice(0), function (parent) {\n        parent.removeChild(that);\n      });\n    },\n    addPeer: function (element, options) {\n      sceneryAssert && sceneryAssert(!this.instances.length, 'Cannot call addPeer after a node has instances (yet)');\n      this._peers.push({\n        element: element,\n        options: options\n      });\n    },\n    addLiveRegion: function (property, options) {\n      this._liveRegions.push({\n        property: property,\n        options: options\n      });\n    },\n    validateBounds: function () {\n      var that = this;\n      var i;\n      if (this._selfBoundsDirty) {\n        this._selfBoundsDirty = false;\n        this.fireEvent('selfBounds', this._selfBounds);\n      }\n      if (this._childBoundsDirty) {\n        i = this._children.length;\n        while (i--) {\n          this._children[i].validateBounds();\n        }\n        var oldChildBounds = this._childBounds;\n        this._childBounds = Bounds2.NOTHING.copy();\n        i = this._children.length;\n        while (i--) {\n          this._childBounds.includeBounds(this._children[i]._bounds);\n        }\n        this._childBoundsDirty = false;\n        if (!this._childBounds.equals(oldChildBounds)) {\n          this.fireEvent('childBounds', this._childBounds);\n        }\n      }\n      if (this._boundsDirty) {\n        this._boundsDirty = false;\n        var oldBounds = this._bounds;\n        var newBounds = this.transformBoundsFromLocalToParent(this._selfBounds.copy().includeBounds(this._childBounds));\n        var changed = !newBounds.equals(oldBounds);\n        if (changed) {\n          this._bounds = newBounds;\n          i = this._parents.length;\n          while (i--) {\n            this._parents[i].invalidateBounds();\n          }\n          this.fireEvent('bounds', this._bounds);\n        }\n      }\n      if (this._selfBoundsDirty || this._childBoundsDirty || this._boundsDirty) {\n        this.validateBounds();\n      }\n      if (sceneryAssertExtra) {\n        (function () {\n          var epsilon = 0.000001;\n          var childBounds = Bounds2.NOTHING.copy();\n          _.each(that.children, function (child) {\n            childBounds.includeBounds(child._bounds);\n          });\n          var fullBounds = that.localToParentBounds(that._selfBounds).union(that.localToParentBounds(childBounds));\n          sceneryAssertExtra && sceneryAssertExtra(that._childBounds.equalsEpsilon(childBounds, epsilon), 'Child bounds mismatch after validateBounds: ' + that._childBounds.toString() + ', expected: ' + childBounds.toString());\n          sceneryAssertExtra && sceneryAssertExtra(that._bounds.equalsEpsilon(fullBounds, epsilon), 'Bounds mismatch after validateBounds: ' + that._bounds.toString() + ', expected: ' + fullBounds.toString());\n        }());\n      }\n    },\n    validateMouseBounds: function () {\n      var that = this;\n      sceneryAssert && sceneryAssert(!this._selfBoundsDirty && !this._childBoundsDirty && !this._boundsDirty, 'Bounds must be validated before calling validateMouseBounds');\n      if (this._mouseBoundsDirty) {\n        var hasMouseAreas = false;\n        this._mouseBounds = this._selfBounds.copy();\n        var i = this._children.length;\n        while (i--) {\n          var child = this._children[i];\n          child.validateMouseBounds();\n          if (child._mouseBounds) {\n            hasMouseAreas = true;\n            that._mouseBounds.includeBounds(child._mouseBounds);\n          }\n        }\n        if (this._mouseArea) {\n          hasMouseAreas = true;\n          this._mouseBounds.includeBounds(this._mouseArea.bounds);\n        }\n        if (hasMouseAreas) {\n          this.transformBoundsFromLocalToParent(this._mouseBounds);\n          this._mouseBounds.includeBounds(this._bounds);\n        } else {\n          this._mouseBounds = null;\n        }\n        this._mouseBoundsDirty = false;\n      }\n    },\n    validateTouchBounds: function () {\n      var that = this;\n      sceneryAssert && sceneryAssert(!this._selfBoundsDirty && !this._childBoundsDirty && !this._boundsDirty, 'Bounds must be validated before calling validateTouchBounds');\n      if (this._touchBoundsDirty) {\n        var hasTouchAreas = false;\n        this._touchBounds = this._selfBounds.copy();\n        var i = this._children.length;\n        while (i--) {\n          var child = this._children[i];\n          child.validateTouchBounds();\n          if (child._touchBounds) {\n            hasTouchAreas = true;\n            that._touchBounds.includeBounds(child._touchBounds);\n          }\n        }\n        if (this._touchArea) {\n          hasTouchAreas = true;\n          this._touchBounds.includeBounds(this._touchArea.bounds);\n        }\n        if (hasTouchAreas) {\n          this.transformBoundsFromLocalToParent(this._touchBounds);\n          this._touchBounds.includeBounds(this._bounds);\n        } else {\n          this._touchBounds = null;\n        }\n        this._touchBoundsDirty = false;\n      }\n    },\n    validatePaint: function () {\n      if (this._paintDirty) {\n        sceneryAssert && sceneryAssert(this.isPainted(), 'Only painted nodes can have self dirty paint');\n        if (!this._subtreePaintDirty) {\n          this.notifyDirtySelfPaint();\n        }\n        this._paintDirty = false;\n      }\n      if (this._subtreePaintDirty) {\n        this.notifyDirtySubtreePaint();\n        this._subtreePaintDirty = false;\n      }\n      if (this._childPaintDirty) {\n        this._childPaintDirty = false;\n        var children = this._children;\n        var length = children.length;\n        for (var i = 0; i < length; i++) {\n          children[i].validatePaint();\n        }\n      }\n    },\n    invalidateBounds: function () {\n      this._boundsDirty = true;\n      this._mouseBoundsDirty = true;\n      this._touchBoundsDirty = true;\n      var i = this._parents.length;\n      while (i--) {\n        this._parents[i].invalidateChildBounds();\n      }\n    },\n    invalidateChildBounds: function () {\n      if (!this._childBoundsDirty) {\n        this._childBoundsDirty = true;\n        this._mouseBoundsDirty = true;\n        this._touchBoundsDirty = true;\n        var i = this._parents.length;\n        while (i--) {\n          this._parents[i].invalidateChildBounds();\n        }\n      }\n    },\n    invalidatePaint: function () {\n      sceneryAssert && sceneryAssert(this.isPainted(), 'Can only call invalidatePaint on a painted node');\n      this._paintDirty = true;\n      var i = this._parents.length;\n      while (i--) {\n        this._parents[i].invalidateChildPaint();\n      }\n    },\n    invalidateSubtreePaint: function () {\n      this._subtreePaintDirty = true;\n      var i = this._parents.length;\n      while (i--) {\n        this._parents[i].invalidateChildPaint();\n      }\n    },\n    invalidateChildPaint: function () {\n      if (!this._childPaintDirty) {\n        this._childPaintDirty = true;\n        var i = this._parents.length;\n        while (i--) {\n          this._parents[i].invalidateChildPaint();\n        }\n      }\n    },\n    invalidateSelf: function (newBounds) {\n      sceneryAssert && sceneryAssert(newBounds.isEmpty() || newBounds.isFinite(), 'Bounds must be empty or finite in invalidateSelf');\n      this.notifyBeforeSelfChange();\n      if (!this._selfBounds.equals(newBounds)) {\n        this._selfBoundsDirty = true;\n        this.invalidateBounds();\n        this._selfBounds = newBounds;\n      }\n      this.invalidatePaint();\n    },\n    markOldSelfPaint: function () {\n      this.notifyBeforeSelfChange();\n    },\n    markLayerRefreshNeeded: function () {\n      this.markForLayerRefresh();\n      this.notifyStitch(true);\n    },\n    markOldPaint: function (justSelf) {\n      if (justSelf) {\n        this.notifyBeforeSelfChange();\n      } else {\n        this.notifyBeforeSubtreeChange();\n      }\n    },\n    isChild: function (potentialChild) {\n      var ourChild = _.contains(this._children, potentialChild);\n      var itsParent = _.contains(potentialChild._parents, this);\n      sceneryAssert && sceneryAssert(ourChild === itsParent);\n      return ourChild;\n    },\n    getSelfBounds: function () {\n      return this._selfBounds;\n    },\n    getChildBounds: function () {\n      this.validateBounds();\n      return this._childBounds;\n    },\n    getBounds: function () {\n      this.validateBounds();\n      return this._bounds;\n    },\n    getVisibleBounds: function () {\n      var bounds = this._selfBounds.copy();\n      var i = this._children.length;\n      while (i--) {\n        var child = this._children[i];\n        if (child.isVisible()) {\n          bounds.includeBounds(child.getVisibleBounds());\n        }\n      }\n      sceneryAssert && sceneryAssert(bounds.isFinite() || bounds.isEmpty(), 'Visible bounds should not be infinite');\n      return this.localToParentBounds(bounds);\n    },\n    trailUnderPointer: function (pointer) {\n      var options = {};\n      if (pointer.isMouse) {\n        options.isMouse = true;\n      }\n      if (pointer.isTouch) {\n        options.isTouch = true;\n      }\n      if (pointer.isPen) {\n        options.isPen = true;\n      }\n      return this.trailUnderPoint(pointer.point, options);\n    },\n    trailUnderPoint: function (point, options, recursive) {\n      sceneryAssert && sceneryAssert(point, 'trailUnderPointer requires a point');\n      if (options === undefined) {\n        options = {};\n      }\n      var pruneInvisible = options.pruneInvisible === undefined ? true : options.pruneInvisible;\n      var pruneUnpickable = options.pruneUnpickable === undefined ? true : options.pruneUnpickable;\n      if (pruneInvisible && !this.isVisible()) {\n        return null;\n      }\n      if (pruneUnpickable && !this.isPickable()) {\n        return null;\n      }\n      this.validateBounds();\n      if (options.isMouse) {\n        this.validateMouseBounds();\n      }\n      if (options.isTouch) {\n        this.validateTouchBounds();\n      }\n      var hasHitAreas = options && (options.isMouse && this._mouseBounds || options.isTouch && this._touchBounds || options.isPen);\n      if (hasHitAreas ? options.isMouse && !this._mouseBounds.containsPoint(point) || options.isTouch && !this._touchBounds.containsPoint(point) : !this._bounds.containsPoint(point)) {\n        return null;\n      }\n      var result = null;\n      var localPoint = this._transform.getInverse().multiplyVector2(Vector2.createFromPool(point.x, point.y));\n      if (this._children.length > 0 && (hasHitAreas || this._childBounds.containsPoint(localPoint))) {\n        for (var i = this._children.length - 1; i >= 0; i--) {\n          var child = this._children[i];\n          var childHit = child.trailUnderPoint(localPoint, options);\n          if (childHit) {\n            childHit.addAncestor(this, i);\n            localPoint.freeToPool();\n            return childHit;\n          }\n        }\n      }\n      if (hasHitAreas) {\n        if (options.isMouse && this._mouseArea) {\n          result = this._mouseArea.containsPoint(localPoint) ? new scenery.Trail(this) : null;\n          localPoint.freeToPool();\n          return result;\n        }\n        if ((options.isTouch || options.isPen) && this._touchArea) {\n          result = this._touchArea.containsPoint(localPoint) ? new scenery.Trail(this) : null;\n          localPoint.freeToPool();\n          return result;\n        }\n      }\n      if (hasHitAreas || this._selfBounds.containsPoint(localPoint)) {\n        if (this.containsPointSelf(localPoint)) {\n          localPoint.freeToPool();\n          return new scenery.Trail(this);\n        }\n      }\n      localPoint.freeToPool();\n      return null;\n    },\n    containsPoint: function (point) {\n      return this.trailUnderPoint(point) !== null;\n    },\n    containsPointSelf: function (point) {\n      return this._selfBounds.containsPoint(point);\n    },\n    intersectsBoundsSelf: function (bounds) {\n      return this._selfBounds.intersectsBounds(bounds);\n    },\n    isPainted: function () {\n      return false;\n    },\n    hasParent: function () {\n      return this._parents.length !== 0;\n    },\n    hasChildren: function () {\n      return this._children.length > 0;\n    },\n    walkDepthFirst: function (callback) {\n      callback(this);\n      var length = this._children.length;\n      for (var i = 0; i < length; i++) {\n        this._children[i].walkDepthFirst(callback);\n      }\n    },\n    getChildrenWithinBounds: function (bounds) {\n      var result = [];\n      var length = this._children.length;\n      for (var i = 0; i < length; i++) {\n        var child = this._children[i];\n        if (!child._bounds.intersection(bounds).isEmpty()) {\n          result.push(child);\n        }\n      }\n      return result;\n    },\n    addInputListener: function (listener) {\n      if (_.indexOf(this._inputListeners, listener) === -1) {\n        this._inputListeners.push(listener);\n      }\n      return this;\n    },\n    removeInputListener: function (listener) {\n      sceneryAssert && sceneryAssert(_.indexOf(this._inputListeners, listener) !== -1);\n      this._inputListeners.splice(_.indexOf(this._inputListeners, listener), 1);\n      return this;\n    },\n    getInputListeners: function () {\n      return this._inputListeners.slice(0);\n    },\n    dispatchEvent: function (type, args) {\n      sceneryEventLog && sceneryEventLog(this.constructor.name + '.dispatchEvent ' + type);\n      var trail = new scenery.Trail();\n      trail.setMutable();\n      args.trail = trail;\n      var branches = false;\n      function recursiveEventDispatch(node) {\n        trail.addAncestor(node);\n        node.fireEvent(type, args);\n        var parents = node._parents;\n        var length = parents.length;\n        branches = branches || length > 1;\n        for (var i = 0; i < length; i++) {\n          recursiveEventDispatch(parents[i]);\n        }\n        if (branches) {\n          trail.removeAncestor();\n        }\n      }\n      recursiveEventDispatch(this);\n    },\n    translate: function (x, y, prependInstead) {\n      if (typeof x === 'number') {\n        if (!x && !y) {\n          return;\n        }\n        if (prependInstead) {\n          this.prependTranslation(x, y);\n        } else {\n          this.appendMatrix(Matrix3.translation(x, y));\n        }\n      } else {\n        var vector = x;\n        if (!vector.x && !vector.y) {\n          return;\n        }\n        this.translate(vector.x, vector.y, y);\n      }\n    },\n    scale: function (x, y, prependInstead) {\n      if (typeof x === 'number') {\n        if (y === undefined) {\n          if (x === 1) {\n            return;\n          }\n          this.appendMatrix(Matrix3.scaling(x, x));\n        } else {\n          if (x === 1 && y === 1) {\n            return;\n          }\n          if (prependInstead) {\n            this.prependMatrix(Matrix3.scaling(x, y));\n          } else {\n            this.appendMatrix(Matrix3.scaling(x, y));\n          }\n        }\n      } else {\n        var vector = x;\n        this.scale(vector.x, vector.y, y);\n      }\n    },\n    rotate: function (angle, prependInstead) {\n      if (angle % (2 * Math.PI) === 0) {\n        return;\n      }\n      if (prependInstead) {\n        this.prependMatrix(Matrix3.rotation2(angle));\n      } else {\n        this.appendMatrix(Matrix3.rotation2(angle));\n      }\n    },\n    rotateAround: function (point, angle) {\n      var matrix = Matrix3.translation(-point.x, -point.y);\n      matrix = Matrix3.rotation2(angle).timesMatrix(matrix);\n      matrix = Matrix3.translation(point.x, point.y).timesMatrix(matrix);\n      this.prependMatrix(matrix);\n    },\n    getX: function () {\n      return this._transform.getMatrix().m02();\n    },\n    setX: function (x) {\n      sceneryAssert && sceneryAssert(typeof x === 'number');\n      this.translate(x - this.getX(), 0, true);\n      return this;\n    },\n    getY: function () {\n      return this._transform.getMatrix().m12();\n    },\n    setY: function (y) {\n      sceneryAssert && sceneryAssert(typeof y === 'number');\n      this.translate(0, y - this.getY(), true);\n      return this;\n    },\n    getScaleVector: function () {\n      return this._transform.getMatrix().getScaleVector();\n    },\n    setScaleMagnitude: function (a, b) {\n      var currentScale = this.getScaleVector();\n      if (typeof a === 'number') {\n        if (b === undefined) {\n          b = a;\n        }\n        this.appendMatrix(Matrix3.scaling(a / currentScale.x, b / currentScale.y));\n      } else {\n        this.appendMatrix(Matrix3.scaling(a.x / currentScale.x, a.y / currentScale.y));\n      }\n      return this;\n    },\n    getRotation: function () {\n      return this._transform.getMatrix().getRotation();\n    },\n    setRotation: function (rotation) {\n      sceneryAssert && sceneryAssert(typeof rotation === 'number');\n      this.appendMatrix(Matrix3.rotation2(rotation - this.getRotation()));\n      return this;\n    },\n    setTranslation: function (a, b) {\n      var m = this._transform.getMatrix();\n      var tx = m.m02();\n      var ty = m.m12();\n      var dx, dy;\n      if (typeof a === 'number') {\n        dx = a - tx;\n        dy = b - ty;\n      } else {\n        dx = a.x - tx;\n        dy = a.y - ty;\n      }\n      this.translate(dx, dy, true);\n      return this;\n    },\n    getTranslation: function () {\n      var matrix = this._transform.getMatrix();\n      return new Vector2(matrix.m02(), matrix.m12());\n    },\n    appendMatrix: function (matrix) {\n      this._transform.append(matrix);\n    },\n    prependMatrix: function (matrix) {\n      this._transform.prepend(matrix);\n    },\n    prependTranslation: function (x, y) {\n      this._transform.prependTranslation(x, y);\n    },\n    setMatrix: function (matrix) {\n      this._transform.set(matrix);\n    },\n    getMatrix: function () {\n      return this._transform.getMatrix();\n    },\n    setTransform: function (transform) {\n      sceneryAssert && sceneryAssert(transform.isFinite(), 'Transform should not have infinite/NaN values');\n      if (this._transform !== transform) {\n        this.beforeTransformChange();\n        this._transform.removeTransformListener(this._transformListener);\n        this._transform = transform;\n        this._transform.prependTransformListener(this._transformListener);\n        this.afterTransformChange();\n      }\n    },\n    getTransform: function () {\n      return this._transform;\n    },\n    resetTransform: function () {\n      this.setMatrix(Matrix3.IDENTITY);\n    },\n    beforeTransformChange: function () {\n      this.notifyBeforeSubtreeChange();\n    },\n    afterTransformChange: function () {\n      this.notifyTransformChange();\n      this.invalidateBounds();\n      this.invalidateSubtreePaint();\n    },\n    getLeft: function () {\n      return this.getBounds().minX;\n    },\n    setLeft: function (left) {\n      sceneryAssert && sceneryAssert(typeof left === 'number');\n      this.translate(left - this.getLeft(), 0, true);\n      return this;\n    },\n    getRight: function () {\n      return this.getBounds().maxX;\n    },\n    setRight: function (right) {\n      sceneryAssert && sceneryAssert(typeof right === 'number');\n      this.translate(right - this.getRight(), 0, true);\n      return this;\n    },\n    getCenter: function () {\n      return this.getBounds().getCenter();\n    },\n    setCenter: function (center) {\n      sceneryAssert && sceneryAssert(center instanceof Vector2);\n      this.translate(center.minus(this.getCenter()), true);\n      return this;\n    },\n    getCenterX: function () {\n      return this.getBounds().getCenterX();\n    },\n    setCenterX: function (x) {\n      sceneryAssert && sceneryAssert(typeof x === 'number');\n      this.translate(x - this.getCenterX(), 0, true);\n      return this;\n    },\n    getCenterY: function () {\n      return this.getBounds().getCenterY();\n    },\n    setCenterY: function (y) {\n      sceneryAssert && sceneryAssert(typeof y === 'number');\n      this.translate(0, y - this.getCenterY(), true);\n      return this;\n    },\n    getTop: function () {\n      return this.getBounds().minY;\n    },\n    setTop: function (top) {\n      sceneryAssert && sceneryAssert(typeof top === 'number');\n      this.translate(0, top - this.getTop(), true);\n      return this;\n    },\n    getBottom: function () {\n      return this.getBounds().maxY;\n    },\n    setBottom: function (bottom) {\n      sceneryAssert && sceneryAssert(typeof bottom === 'number');\n      this.translate(0, bottom - this.getBottom(), true);\n      return this;\n    },\n    getWidth: function () {\n      return this.getBounds().getWidth();\n    },\n    getHeight: function () {\n      return this.getBounds().getHeight();\n    },\n    getId: function () {\n      return this._id;\n    },\n    isVisible: function () {\n      return this._visible;\n    },\n    setVisible: function (visible) {\n      sceneryAssert && sceneryAssert(typeof visible === 'boolean');\n      if (visible !== this._visible) {\n        if (this._visible) {\n          this.notifyBeforeSubtreeChange();\n        }\n        this._visible = visible;\n        this.notifyVisibilityChange();\n      }\n      return this;\n    },\n    getOpacity: function () {\n      return this._opacity;\n    },\n    setOpacity: function (opacity) {\n      sceneryAssert && sceneryAssert(typeof opacity === 'number');\n      var clampedOpacity = clamp(opacity, 0, 1);\n      if (clampedOpacity !== this._opacity) {\n        this.notifyBeforeSubtreeChange();\n        this._opacity = clampedOpacity;\n        this.notifyOpacityChange();\n      }\n    },\n    isPickable: function () {\n      return this._pickable;\n    },\n    setPickable: function (pickable) {\n      sceneryAssert && sceneryAssert(typeof pickable === 'boolean');\n      if (this._pickable !== pickable) {\n        this._pickable = pickable;\n      }\n    },\n    setCursor: function (cursor) {\n      sceneryAssert && sceneryAssert(typeof cursor === 'string' || cursor === null);\n      this._cursor = cursor === 'auto' ? null : cursor;\n    },\n    getCursor: function () {\n      return this._cursor;\n    },\n    setMouseArea: function (shape) {\n      sceneryAssert && sceneryAssert(shape === null || shape instanceof Shape, 'mouseArea needs to be a kite.Shape, or null');\n      if (this._mouseArea !== shape) {\n        this._mouseArea = shape;\n        this.invalidateBounds();\n      }\n    },\n    getMouseArea: function () {\n      return this._mouseArea;\n    },\n    setTouchArea: function (shape) {\n      sceneryAssert && sceneryAssert(shape === null || shape instanceof Shape, 'touchArea needs to be a kite.Shape, or null');\n      if (this._touchArea !== shape) {\n        this._touchArea = shape;\n        this.invalidateBounds();\n      }\n    },\n    getTouchArea: function () {\n      return this._touchArea;\n    },\n    updateLayerType: function () {\n      if (this._renderer && this._rendererOptions) {\n        if (this._rendererOptions.cssTransform || this._rendererOptions.cssTranslation || this._rendererOptions.cssRotation || this._rendererOptions.cssScale) {\n          this._rendererOptions.baseNode = this;\n        } else if (this._rendererOptions.hasOwnProperty('baseNode')) {\n          delete this._rendererOptions.baseNode;\n        }\n        this._rendererLayerType = this._renderer.createLayerType(this._rendererOptions);\n      } else {\n        this._rendererLayerType = null;\n      }\n    },\n    getRendererLayerType: function () {\n      return this._rendererLayerType;\n    },\n    hasRendererLayerType: function () {\n      return !!this._rendererLayerType;\n    },\n    setRenderer: function (renderer) {\n      var newRenderer;\n      if (typeof renderer === 'string') {\n        sceneryAssert && sceneryAssert(scenery.Renderer[renderer], 'unknown renderer in setRenderer: ' + renderer);\n        newRenderer = scenery.Renderer[renderer];\n      } else if (renderer instanceof scenery.Renderer) {\n        newRenderer = renderer;\n      } else if (!renderer) {\n        newRenderer = null;\n      } else {\n        throw new Error('unrecognized type of renderer: ' + renderer);\n      }\n      if (newRenderer !== this._renderer) {\n        sceneryAssert && sceneryAssert(!this.isPainted() || !newRenderer || _.contains(this._supportedRenderers, newRenderer), 'renderer ' + newRenderer + ' not supported by ' + this.constructor.name);\n        this._renderer = newRenderer;\n        this.updateLayerType();\n        this.markLayerRefreshNeeded();\n      }\n    },\n    getRenderer: function () {\n      return this._renderer;\n    },\n    hasRenderer: function () {\n      return !!this._renderer;\n    },\n    setRendererOptions: function (options) {\n      this._rendererOptions = options;\n      this.updateLayerType();\n      this.markLayerRefreshNeeded();\n    },\n    getRendererOptions: function () {\n      return this._rendererOptions;\n    },\n    hasRendererOptions: function () {\n      return !!this._rendererOptions;\n    },\n    setLayerSplitBefore: function (split) {\n      sceneryAssert && sceneryAssert(typeof split === 'boolean');\n      if (this._layerSplitBefore !== split) {\n        this._layerSplitBefore = split;\n        this.markLayerRefreshNeeded();\n      }\n    },\n    isLayerSplitBefore: function () {\n      return this._layerSplitBefore;\n    },\n    setLayerSplitAfter: function (split) {\n      sceneryAssert && sceneryAssert(typeof split === 'boolean');\n      if (this._layerSplitAfter !== split) {\n        this._layerSplitAfter = split;\n        this.markLayerRefreshNeeded();\n      }\n    },\n    isLayerSplitAfter: function () {\n      return this._layerSplitAfter;\n    },\n    setLayerSplit: function (split) {\n      sceneryAssert && sceneryAssert(typeof split === 'boolean');\n      if (split !== this._layerSplitBefore || split !== this._layerSplitAfter) {\n        this._layerSplitBefore = split;\n        this._layerSplitAfter = split;\n        this.markLayerRefreshNeeded();\n      }\n    },\n    getUniqueTrail: function () {\n      var trail = new scenery.Trail();\n      var node = this;\n      while (node) {\n        trail.addAncestor(node);\n        sceneryAssert && sceneryAssert(node._parents.length <= 1);\n        node = node._parents[0];\n      }\n      return trail;\n    },\n    getConnectedNodes: function () {\n      var result = [];\n      var fresh = this._children.concat(this._parents).concat(this);\n      while (fresh.length) {\n        var node = fresh.pop();\n        if (!_.contains(result, node)) {\n          result.push(node);\n          fresh = fresh.concat(node._children, node._parents);\n        }\n      }\n      return result;\n    },\n    getTopologicallySortedNodes: function () {\n      var edges = {};\n      var s = [];\n      var l = [];\n      var n;\n      _.each(this.getConnectedNodes(), function (node) {\n        edges[node.id] = {};\n        _.each(node.children, function (m) {\n          edges[node.id][m.id] = true;\n        });\n        if (!node.parents.length) {\n          s.push(node);\n        }\n      });\n      function handleChild(m) {\n        delete edges[n.id][m.id];\n        if (_.every(edges, function (children) {\n            return !children[m.id];\n          })) {\n          s.push(m);\n        }\n      }\n      while (s.length) {\n        n = s.pop();\n        l.push(n);\n        _.each(n.children, handleChild);\n      }\n      sceneryAssert && sceneryAssert(_.every(edges, function (children) {\n        return _.every(children, function (final) {\n          return false;\n        });\n      }), 'circular reference check');\n      return l;\n    },\n    canAddChild: function (child) {\n      if (this === child || _.contains(this.children, child)) {\n        return false;\n      }\n      var edges = {};\n      var s = [];\n      var l = [];\n      var n;\n      _.each(this.getConnectedNodes().concat(child.getConnectedNodes()), function (node) {\n        edges[node.id] = {};\n        _.each(node.children, function (m) {\n          edges[node.id][m.id] = true;\n        });\n        if (!node.parents.length && node !== child) {\n          s.push(node);\n        }\n      });\n      edges[this.id][child.id] = true;\n      function handleChild(m) {\n        delete edges[n.id][m.id];\n        if (_.every(edges, function (children) {\n            return !children[m.id];\n          })) {\n          s.push(m);\n        }\n      }\n      while (s.length) {\n        n = s.pop();\n        l.push(n);\n        _.each(n.children, handleChild);\n        if (n === this) {\n          handleChild(child);\n        }\n      }\n      return _.every(edges, function (children) {\n        return _.every(children, function (final) {\n          return false;\n        });\n      });\n    },\n    debugText: function () {\n      var startPointer = new scenery.TrailPointer(new scenery.Trail(this), true);\n      var endPointer = new scenery.TrailPointer(new scenery.Trail(this), false);\n      var depth = 0;\n      startPointer.depthFirstUntil(endPointer, function (pointer) {\n        if (pointer.isBefore) {\n          var padding = new Array(depth * 2).join(' ');\n          console.log(padding + pointer.trail.lastNode().getId() + ' ' + pointer.trail.toString());\n        }\n        depth += pointer.isBefore ? 1 : -1;\n      }, false);\n    },\n    toCanvas: function (callback, x, y, width, height) {\n      var self = this;\n      var padding = 2;\n      var bounds = this.getBounds();\n      x = x !== undefined ? x : Math.ceil(padding - bounds.minX);\n      y = y !== undefined ? y : Math.ceil(padding - bounds.minY);\n      width = width !== undefined ? width : Math.ceil(x + bounds.getWidth() + padding);\n      height = height !== undefined ? height : Math.ceil(y + bounds.getHeight() + padding);\n      var canvas = document.createElement('canvas');\n      canvas.width = width;\n      canvas.height = height;\n      var context = canvas.getContext('2d');\n      var $div = $(document.createElement('div'));\n      $div.width(width).height(height);\n      var scene = new scenery.Scene($div);\n      scene.addChild(self);\n      scene.x = x;\n      scene.y = y;\n      scene.updateScene();\n      scene.renderToCanvas(canvas, context, function () {\n        callback(canvas, x, y);\n        scene.removeChild(self);\n      });\n    },\n    toDataURL: function (callback, x, y, width, height) {\n      this.toCanvas(function (canvas, x, y) {\n        callback(canvas.toDataURL(), x, y);\n      }, x, y, width, height);\n    },\n    toImage: function (callback, x, y, width, height) {\n      this.toDataURL(function (url, x, y) {\n        var img = document.createElement('img');\n        img.onload = function () {\n          callback(img, x, y);\n          try {\n            delete img.onload;\n          } catch (e) {\n          }\n        };\n        img.src = url;\n      }, x, y, width, height);\n    },\n    toImageNodeAsynchronous: function (callback, x, y, width, height) {\n      this.toImage(function (image, x, y) {\n        callback(new scenery.Node({\n          children: [new scenery.Image(image, {\n              x: -x,\n              y: -y\n            })]\n        }));\n      }, x, y, width, height);\n    },\n    toCanvasNodeSynchronous: function (x, y, width, height) {\n      var result;\n      this.toCanvas(function (canvas, x, y) {\n        result = new scenery.Node({\n          children: [new scenery.Image(canvas, {\n              x: -x,\n              y: -y\n            })]\n        });\n      }, x, y, width, height);\n      sceneryAssert && sceneryAssert(result, 'toCanvasNodeSynchronous requires that the node can be rendered only using Canvas');\n      return result;\n    },\n    toDataURLNodeSynchronous: function (x, y, width, height) {\n      var result;\n      this.toDataURL(function (dataURL, x, y) {\n        result = new scenery.Node({\n          children: [new scenery.Image(dataURL, {\n              x: -x,\n              y: -y\n            })]\n        });\n      }, x, y, width, height);\n      sceneryAssert && sceneryAssert(result, 'toDataURLNodeSynchronous requires that the node can be rendered only using Canvas');\n      return result;\n    },\n    getInstances: function () {\n      return this._instances;\n    },\n    addInstance: function (instance) {\n      sceneryAssert && sceneryAssert(instance.getNode() === this, 'Must be an instance of this Node');\n      sceneryAssert && sceneryAssert(!_.find(this._instances, function (other) {\n        return instance.equals(other);\n      }), 'Cannot add duplicates of an instance to a Node');\n      this._instances.push(instance);\n      if (this._instances.length === 1) {\n        this.firstInstanceAdded();\n      }\n    },\n    firstInstanceAdded: function () {\n    },\n    getInstanceFromTrail: function (trail) {\n      var result;\n      var len = this._instances.length;\n      if (len === 1) {\n        result = this._instances[0];\n      } else {\n        var i = len;\n        while (i--) {\n          if (this._instances[i].trail.equals(trail)) {\n            result = this._instances[i];\n            break;\n          }\n        }\n      }\n      sceneryAssert && sceneryAssert(result, 'Could not find an instance for the trail ' + trail.toString());\n      sceneryAssert && sceneryAssert(result.trail.equals(trail), 'Instance has an incorrect Trail');\n      return result;\n    },\n    removeInstance: function (instance) {\n      var index = _.indexOf(this._instances, instance);\n      sceneryAssert && sceneryAssert(index !== -1, 'Cannot remove an Instance from a Node if it was not there');\n      this._instances.splice(index, 1);\n      if (this._instances.length === 0) {\n        this.lastInstanceRemoved();\n      }\n    },\n    lastInstanceRemoved: function () {\n    },\n    notifyVisibilityChange: function () {\n      var i = this._instances.length;\n      while (i--) {\n        this._instances[i].notifyVisibilityChange();\n      }\n    },\n    notifyOpacityChange: function () {\n      var i = this._instances.length;\n      while (i--) {\n        this._instances[i].notifyOpacityChange();\n      }\n    },\n    notifyBeforeSelfChange: function () {\n      var i = this._instances.length;\n      while (i--) {\n        this._instances[i].notifyBeforeSelfChange();\n      }\n    },\n    notifyBeforeSubtreeChange: function () {\n      var i = this._instances.length;\n      while (i--) {\n        this._instances[i].notifyBeforeSubtreeChange();\n      }\n    },\n    notifyDirtySelfPaint: function () {\n      var i = this._instances.length;\n      while (i--) {\n        this._instances[i].notifyDirtySelfPaint();\n      }\n    },\n    notifyDirtySubtreePaint: function () {\n      var i = this._instances.length;\n      while (i--) {\n        this._instances[i].notifyDirtySubtreePaint();\n      }\n    },\n    notifyTransformChange: function () {\n      var i = this._instances.length;\n      while (i--) {\n        this._instances[i].notifyTransformChange();\n      }\n    },\n    notifyBoundsAccuracyChange: function () {\n      var i = this._instances.length;\n      while (i--) {\n        this._instances[i].notifyBoundsAccuracyChange();\n      }\n    },\n    notifyStitch: function (match) {\n      var i = this._instances.length;\n      while (i--) {\n        this._instances[i].notifyStitch(match);\n      }\n    },\n    markForLayerRefresh: function () {\n      var i = this._instances.length;\n      while (i--) {\n        this._instances[i].markForLayerRefresh();\n      }\n    },\n    markForInsertion: function (child, index) {\n      var i = this._instances.length;\n      while (i--) {\n        this._instances[i].markForInsertion(child, index);\n      }\n    },\n    markForRemoval: function (child, index) {\n      var i = this._instances.length;\n      while (i--) {\n        this._instances[i].markForRemoval(child, index);\n      }\n    },\n    localToParentPoint: function (point) {\n      return this._transform.transformPosition2(point);\n    },\n    localToParentBounds: function (bounds) {\n      return this._transform.transformBounds2(bounds);\n    },\n    parentToLocalPoint: function (point) {\n      return this._transform.inversePosition2(point);\n    },\n    parentToLocalBounds: function (bounds) {\n      return this._transform.inverseBounds2(bounds);\n    },\n    transformBoundsFromLocalToParent: function (bounds) {\n      return bounds.transform(this._transform.getMatrix());\n    },\n    transformBoundsFromParentToLocal: function (bounds) {\n      return bounds.transform(this._transform.getInverse());\n    },\n    getLocalToGlobalMatrix: function () {\n      var node = this;\n      var matrices = [];\n      while (node) {\n        matrices.push(node._transform.getMatrix());\n        sceneryAssert && sceneryAssert(node._parents[1] === undefined, 'getLocalToGlobalMatrix unable to work for DAG');\n        node = node._parents[0];\n      }\n      var matrix = new Matrix3();\n      for (var i = matrices.length - 1; i >= 0; i--) {\n        matrix.multiplyMatrix(matrices[i]);\n      }\n      return matrix;\n    },\n    getUniqueTransform: function () {\n      return new Transform3(this.getLocalToGlobalMatrix());\n    },\n    getGlobalToLocalMatrix: function () {\n      return this.getLocalToGlobalMatrix().invert();\n    },\n    localToGlobalPoint: function (point) {\n      var node = this;\n      var resultPoint = point.copy();\n      while (node) {\n        node._transform.getMatrix().multiplyVector2(resultPoint);\n        sceneryAssert && sceneryAssert(node._parents[1] === undefined, 'localToGlobalPoint unable to work for DAG');\n        node = node._parents[0];\n      }\n      return resultPoint;\n    },\n    globalToLocalPoint: function (point) {\n      var node = this;\n      var transforms = [];\n      while (node) {\n        transforms.push(node._transform);\n        sceneryAssert && sceneryAssert(node._parents[1] === undefined, 'globalToLocalPoint unable to work for DAG');\n        node = node._parents[0];\n      }\n      var resultPoint = point.copy();\n      for (var i = transforms.length - 1; i >= 0; i--) {\n        transforms[i].getInverse().multiplyVector2(resultPoint);\n      }\n      return resultPoint;\n    },\n    localToGlobalBounds: function (bounds) {\n      return bounds.transformed(this.getLocalToGlobalMatrix());\n    },\n    globalToLocalBounds: function (bounds) {\n      return bounds.transformed(this.getGlobalToLocalMatrix());\n    },\n    parentToGlobalPoint: function (point) {\n      sceneryAssert && sceneryAssert(this.parents.length <= 1, 'parentToGlobalPoint unable to work for DAG');\n      return this.parents.length ? this.parents[0].localToGlobalPoint(point) : point;\n    },\n    parentToGlobalBounds: function (bounds) {\n      sceneryAssert && sceneryAssert(this.parents.length <= 1, 'parentToGlobalBounds unable to work for DAG');\n      return this.parents.length ? this.parents[0].localToGlobalBounds(bounds) : bounds;\n    },\n    globalToParentPoint: function (point) {\n      sceneryAssert && sceneryAssert(this.parents.length <= 1, 'globalToParentPoint unable to work for DAG');\n      return this.parents.length ? this.parents[0].globalToLocalPoint(point) : point;\n    },\n    globalToParentBounds: function (bounds) {\n      sceneryAssert && sceneryAssert(this.parents.length <= 1, 'globalToParentBounds unable to work for DAG');\n      return this.parents.length ? this.parents[0].globalToLocalBounds(bounds) : bounds;\n    },\n    getGlobalBounds: function () {\n      sceneryAssert && sceneryAssert(this.parents.length <= 1, 'globalBounds unable to work for DAG');\n      return this.parentToGlobalBounds(this.getBounds());\n    },\n    boundsOf: function (node) {\n      return this.globalToLocalBounds(node.getGlobalBounds());\n    },\n    boundsTo: function (node) {\n      return node.globalToLocalBounds(this.getGlobalBounds());\n    },\n    set layerSplit(value) {\n      this.setLayerSplit(value);\n    },\n    get layerSplit() {\n      throw new Error('You can\\'t get a layerSplit property, since it modifies two separate properties');\n    },\n    set layerSplitBefore(value) {\n      this.setLayerSplitBefore(value);\n    },\n    get layerSplitBefore() {\n      return this.isLayerSplitBefore();\n    },\n    set layerSplitAfter(value) {\n      this.setLayerSplitAfter(value);\n    },\n    get layerSplitAfter() {\n      return this.isLayerSplitAfter();\n    },\n    set renderer(value) {\n      this.setRenderer(value);\n    },\n    get renderer() {\n      return this.getRenderer();\n    },\n    set rendererOptions(value) {\n      this.setRendererOptions(value);\n    },\n    get rendererOptions() {\n      return this.getRendererOptions();\n    },\n    set cursor(value) {\n      this.setCursor(value);\n    },\n    get cursor() {\n      return this.getCursor();\n    },\n    set mouseArea(value) {\n      this.setMouseArea(value);\n    },\n    get mouseArea() {\n      return this.getMouseArea();\n    },\n    set touchArea(value) {\n      this.setTouchArea(value);\n    },\n    get touchArea() {\n      return this.getTouchArea();\n    },\n    set visible(value) {\n      this.setVisible(value);\n    },\n    get visible() {\n      return this.isVisible();\n    },\n    set opacity(value) {\n      this.setOpacity(value);\n    },\n    get opacity() {\n      return this.getOpacity();\n    },\n    set pickable(value) {\n      this.setPickable(value);\n    },\n    get pickable() {\n      return this.isPickable();\n    },\n    set transform(value) {\n      this.setTransform(value);\n    },\n    get transform() {\n      return this.getTransform();\n    },\n    set matrix(value) {\n      this.setMatrix(value);\n    },\n    get matrix() {\n      return this.getMatrix();\n    },\n    set translation(value) {\n      this.setTranslation(value);\n    },\n    get translation() {\n      return this.getTranslation();\n    },\n    set rotation(value) {\n      this.setRotation(value);\n    },\n    get rotation() {\n      return this.getRotation();\n    },\n    set x(value) {\n      this.setX(value);\n    },\n    get x() {\n      return this.getX();\n    },\n    set y(value) {\n      this.setY(value);\n    },\n    get y() {\n      return this.getY();\n    },\n    set left(value) {\n      this.setLeft(value);\n    },\n    get left() {\n      return this.getLeft();\n    },\n    set right(value) {\n      this.setRight(value);\n    },\n    get right() {\n      return this.getRight();\n    },\n    set top(value) {\n      this.setTop(value);\n    },\n    get top() {\n      return this.getTop();\n    },\n    set bottom(value) {\n      this.setBottom(value);\n    },\n    get bottom() {\n      return this.getBottom();\n    },\n    set center(value) {\n      this.setCenter(value);\n    },\n    get center() {\n      return this.getCenter();\n    },\n    set centerX(value) {\n      this.setCenterX(value);\n    },\n    get centerX() {\n      return this.getCenterX();\n    },\n    set centerY(value) {\n      this.setCenterY(value);\n    },\n    get centerY() {\n      return this.getCenterY();\n    },\n    set children(value) {\n      this.setChildren(value);\n    },\n    get children() {\n      return this.getChildren();\n    },\n    get parents() {\n      return this.getParents();\n    },\n    get width() {\n      return this.getWidth();\n    },\n    get height() {\n      return this.getHeight();\n    },\n    get bounds() {\n      return this.getBounds();\n    },\n    get selfBounds() {\n      return this.getSelfBounds();\n    },\n    get childBounds() {\n      return this.getChildBounds();\n    },\n    get globalBounds() {\n      return this.getGlobalBounds();\n    },\n    get visibleBounds() {\n      return this.getVisibleBounds();\n    },\n    get id() {\n      return this.getId();\n    },\n    get instances() {\n      return this.getInstances();\n    },\n    mutate: function (options) {\n      if (!options) {\n        return this;\n      }\n      var node = this;\n      _.each(this._mutatorKeys, function (key) {\n        if (options[key] !== undefined) {\n          var descriptor = Object.getOwnPropertyDescriptor(Node.prototype, key);\n          if (descriptor && typeof descriptor.value === 'function') {\n            node[key](options[key]);\n          } else {\n            node[key] = options[key];\n          }\n        }\n      });\n      return this;\n    },\n    toString: function (spaces, includeChildren) {\n      spaces = spaces || '';\n      var props = this.getPropString(spaces + '  ', includeChildren === undefined ? true : includeChildren);\n      return spaces + this.getBasicConstructor(props ? '\\n' + props + '\\n' + spaces : '');\n    },\n    getBasicConstructor: function (propLines) {\n      return 'new scenery.Node( {' + propLines + '} )';\n    },\n    getPropString: function (spaces, includeChildren) {\n      var self = this;\n      var result = '';\n      function addProp(key, value, nowrap) {\n        if (result) {\n          result += ',\\n';\n        }\n        if (!nowrap && typeof value === 'string') {\n          result += spaces + key + ': \\'' + value + '\\'';\n        } else {\n          result += spaces + key + ': ' + value;\n        }\n      }\n      if (this._children.length && includeChildren) {\n        var childString = '';\n        _.each(this._children, function (child) {\n          if (childString) {\n            childString += ',\\n';\n          }\n          childString += child.toString(spaces + '  ');\n        });\n        addProp('children', '[\\n' + childString + '\\n' + spaces + ']', true);\n      }\n      if (this.cursor) {\n        addProp('cursor', this.cursor);\n      }\n      if (!this.visible) {\n        addProp('visible', this.visible);\n      }\n      if (!this.pickable) {\n        addProp('pickable', this.pickable);\n      }\n      if (this.opacity !== 1) {\n        addProp('opacity', this.opacity);\n      }\n      if (!this.transform.isIdentity()) {\n        var m = this.transform.getMatrix();\n        addProp('matrix', 'new dot.Matrix3( ' + m.m00() + ', ' + m.m01() + ', ' + m.m02() + ', ' + m.m10() + ', ' + m.m11() + ', ' + m.m12() + ', ' + m.m20() + ', ' + m.m21() + ', ' + m.m22() + ' )', true);\n      }\n      if (this.renderer) {\n        addProp('renderer', this.renderer.name);\n        if (this.rendererOptions) {\n        }\n      }\n      if (this._layerSplitBefore) {\n        addProp('layerSplitBefore', true);\n      }\n      if (this._layerSplitAfter) {\n        addProp('layerSplitAfter', true);\n      }\n      return result;\n    }\n  };\n  Node.prototype._mutatorKeys = [\n    'children',\n    'cursor',\n    'visible',\n    'pickable',\n    'opacity',\n    'matrix',\n    'translation',\n    'x',\n    'y',\n    'rotation',\n    'scale',\n    'left',\n    'right',\n    'top',\n    'bottom',\n    'center',\n    'centerX',\n    'centerY',\n    'renderer',\n    'rendererOptions',\n    'layerSplit',\n    'layerSplitBefore',\n    'layerSplitAfter',\n    'mouseArea',\n    'touchArea'\n  ];\n  Node.prototype._supportedRenderers = [];\n  Node.prototype.layerStrategy = LayerStrategy;\n  NodeEvents(Node);\n  return Node;\n});",
    "\ndefine('SCENERY/util/Trail',['require','DOT/Matrix3','DOT/Transform3','SCENERY/scenery','SCENERY/nodes/Node'],function (require) {\n  'use strict';\n  var Matrix3 = require('DOT/Matrix3');\n  var Transform3 = require('DOT/Transform3');\n  var scenery = require('SCENERY/scenery');\n  require('SCENERY/nodes/Node');\n  scenery.Trail = function Trail(nodes) {\n    if (sceneryAssert) {\n      this.immutable = undefined;\n    }\n    if (nodes instanceof Trail) {\n      var otherTrail = nodes;\n      this.nodes = otherTrail.nodes.slice(0);\n      this.length = otherTrail.length;\n      this.uniqueId = otherTrail.uniqueId;\n      this.indices = otherTrail.indices.slice(0);\n      return;\n    }\n    this.nodes = [];\n    this.length = 0;\n    this.uniqueId = '';\n    this.indices = [];\n    var trail = this;\n    if (nodes) {\n      if (nodes instanceof scenery.Node) {\n        var node = nodes;\n        trail.addDescendant(node);\n      } else {\n        var len = nodes.length;\n        for (var i = 0; i < len; i++) {\n          trail.addDescendant(nodes[i]);\n        }\n      }\n    }\n    phetAllocation && phetAllocation('Trail');\n  };\n  var Trail = scenery.Trail;\n  Trail.prototype = {\n    constructor: Trail,\n    copy: function () {\n      return new Trail(this);\n    },\n    isPainted: function () {\n      return this.lastNode().isPainted();\n    },\n    isVisible: function () {\n      var i = this.nodes.length;\n      while (i--) {\n        if (!this.nodes[i].isVisible()) {\n          return false;\n        }\n      }\n      return true;\n    },\n    getOpacity: function () {\n      var opacity = 1;\n      var i = this.nodes.length;\n      while (i--) {\n        opacity *= this.nodes[i].getOpacity();\n      }\n      return opacity;\n    },\n    get: function (index) {\n      if (index >= 0) {\n        return this.nodes[index];\n      } else {\n        return this.nodes[this.nodes.length + index];\n      }\n    },\n    slice: function (startIndex, endIndex) {\n      return new Trail(this.nodes.slice(startIndex, endIndex));\n    },\n    subtrailTo: function (node, excludeNode) {\n      return this.slice(0, _.indexOf(this.nodes, node) + (excludeNode ? 0 : 1));\n    },\n    isEmpty: function () {\n      return this.nodes.length === 0;\n    },\n    getInstance: function () {\n      return this.lastNode().getInstanceFromTrail(this);\n    },\n    getMatrix: function () {\n      var matrix = new Matrix3();\n      var nodes = this.nodes;\n      var length = nodes.length;\n      for (var i = 0; i < length; i++) {\n        matrix.multiplyMatrix(nodes[i]._transform.getMatrix());\n      }\n      return matrix;\n    },\n    getParentMatrix: function () {\n      var matrix = new Matrix3();\n      var nodes = this.nodes;\n      var length = nodes.length;\n      for (var i = 0; i < length - 1; i++) {\n        matrix.multiplyMatrix(nodes[i]._transform.getMatrix());\n      }\n      return matrix;\n    },\n    getTransform: function () {\n      return new Transform3(this.getMatrix());\n    },\n    getParentTransform: function () {\n      return new Transform3(this.getParentMatrix());\n    },\n    addAncestor: function (node, index) {\n      sceneryAssert && sceneryAssert(!this.immutable, 'cannot modify an immutable Trail with addAncestor');\n      sceneryAssert && sceneryAssert(node, 'cannot add falsy value to a Trail');\n      if (this.nodes.length) {\n        var oldRoot = this.nodes[0];\n        this.indices.unshift(index === undefined ? _.indexOf(node._children, oldRoot) : index);\n      }\n      this.nodes.unshift(node);\n      this.length++;\n      this.uniqueId = this.uniqueId ? node._id + '-' + this.uniqueId : node._id + '';\n      return this;\n    },\n    removeAncestor: function () {\n      sceneryAssert && sceneryAssert(!this.immutable, 'cannot modify an immutable Trail with removeAncestor');\n      sceneryAssert && sceneryAssert(this.length > 0, 'cannot remove a Node from an empty trail');\n      this.nodes.shift();\n      if (this.indices.length) {\n        this.indices.shift();\n      }\n      this.length--;\n      this.updateUniqueId();\n      return this;\n    },\n    addDescendant: function (node, index) {\n      sceneryAssert && sceneryAssert(!this.immutable, 'cannot modify an immutable Trail with addDescendant');\n      sceneryAssert && sceneryAssert(node, 'cannot add falsy value to a Trail');\n      if (this.nodes.length) {\n        var parent = this.lastNode();\n        this.indices.push(index === undefined ? _.indexOf(parent._children, node) : index);\n      }\n      this.nodes.push(node);\n      this.length++;\n      this.uniqueId = this.uniqueId ? this.uniqueId + '-' + node._id : node._id + '';\n      return this;\n    },\n    removeDescendant: function () {\n      sceneryAssert && sceneryAssert(!this.immutable, 'cannot modify an immutable Trail with removeDescendant');\n      sceneryAssert && sceneryAssert(this.length > 0, 'cannot remove a Node from an empty trail');\n      this.nodes.pop();\n      if (this.indices.length) {\n        this.indices.pop();\n      }\n      this.length--;\n      this.updateUniqueId();\n      return this;\n    },\n    reindex: function () {\n      var length = this.length;\n      for (var i = 1; i < length; i++) {\n        var currentIndex = this.indices[i - 1];\n        var baseNode = this.nodes[i - 1];\n        if (baseNode._children[currentIndex] !== this.nodes[i]) {\n          this.indices[i - 1] = _.indexOf(baseNode._children, this.nodes[i]);\n        }\n      }\n    },\n    setImmutable: function () {\n      if (sceneryAssert) {\n        sceneryAssert(this.immutable !== false, 'A trail cannot be made immutable after being flagged as mutable');\n        this.immutable = true;\n      }\n      return this;\n    },\n    setMutable: function () {\n      if (sceneryAssert) {\n        sceneryAssert(this.immutable !== true, 'A trail cannot be made mutable after being flagged as immutable');\n        this.immutable = false;\n      }\n      return this;\n    },\n    areIndicesValid: function () {\n      for (var i = 1; i < this.length; i++) {\n        var currentIndex = this.indices[i - 1];\n        if (this.nodes[i - 1]._children[currentIndex] !== this.nodes[i]) {\n          return false;\n        }\n      }\n      return true;\n    },\n    equals: function (other) {\n      if (this.length !== other.length) {\n        return false;\n      }\n      for (var i = 0; i < this.nodes.length; i++) {\n        if (this.nodes[i] !== other.nodes[i]) {\n          return false;\n        }\n      }\n      return true;\n    },\n    upToNode: function (node) {\n      var nodeIndex = _.indexOf(this.nodes, node);\n      sceneryAssert && sceneryAssert(nodeIndex >= 0, 'Trail does not contain the node');\n      return this.slice(0, _.indexOf(this.nodes, node) + 1);\n    },\n    isExtensionOf: function (other, allowSameTrail) {\n      sceneryAssertExtra && sceneryAssertExtra(this.areIndicesValid(), 'Trail.compare this.areIndicesValid() failed');\n      sceneryAssertExtra && sceneryAssertExtra(other.areIndicesValid(), 'Trail.compare other.areIndicesValid() failed');\n      if (this.length <= other.length - (allowSameTrail ? 1 : 0)) {\n        return false;\n      }\n      for (var i = 0; i < other.nodes.length; i++) {\n        if (this.nodes[i] !== other.nodes[i]) {\n          return false;\n        }\n      }\n      return true;\n    },\n    getTransformTo: function (otherTrail) {\n      return new Transform3(this.getMatrixTo(otherTrail));\n    },\n    getMatrixTo: function (otherTrail) {\n      this.reindex();\n      otherTrail.reindex();\n      var branchIndex = this.getBranchIndexTo(otherTrail);\n      var idx;\n      var matrix = Matrix3.IDENTITY;\n      for (idx = this.length - 1; idx >= branchIndex; idx--) {\n        matrix = this.nodes[idx].getTransform().getMatrix().timesMatrix(matrix);\n      }\n      for (idx = branchIndex; idx < otherTrail.length; idx++) {\n        matrix = otherTrail.nodes[idx].getTransform().getInverse().timesMatrix(matrix);\n      }\n      return matrix;\n    },\n    getBranchIndexTo: function (otherTrail) {\n      sceneryAssert && sceneryAssert(this.nodes[0] === otherTrail.nodes[0], 'To get a branch index, the trails must have the same root');\n      var branchIndex;\n      for (branchIndex = 0; branchIndex < Math.min(this.length, otherTrail.length); branchIndex++) {\n        if (this.nodes[branchIndex] !== otherTrail.nodes[branchIndex]) {\n          break;\n        }\n      }\n      return branchIndex;\n    },\n    nodeFromTop: function (offset) {\n      return this.nodes[this.length - 1 - offset];\n    },\n    lastNode: function () {\n      return this.nodeFromTop(0);\n    },\n    rootNode: function () {\n      return this.nodes[0];\n    },\n    previous: function () {\n      if (this.nodes.length <= 1) {\n        return null;\n      }\n      var top = this.nodeFromTop(0);\n      var parent = this.nodeFromTop(1);\n      var parentIndex = _.indexOf(parent._children, top);\n      sceneryAssert && sceneryAssert(parentIndex !== -1);\n      var arr = this.nodes.slice(0, this.nodes.length - 1);\n      if (parentIndex === 0) {\n        return new Trail(arr);\n      } else {\n        arr.push(parent._children[parentIndex - 1]);\n        while (arr[arr.length - 1]._children.length !== 0) {\n          var last = arr[arr.length - 1];\n          arr.push(last._children[last._children.length - 1]);\n        }\n        return new Trail(arr);\n      }\n    },\n    previousPainted: function () {\n      var result = this.previous();\n      while (result && !result.isPainted()) {\n        result = result.previous();\n      }\n      return result;\n    },\n    next: function () {\n      var arr = this.nodes.slice(0);\n      var top = this.nodeFromTop(0);\n      if (top._children.length > 0) {\n        arr.push(top._children[0]);\n        return new Trail(arr);\n      } else {\n        var depth = this.nodes.length - 1;\n        while (depth > 0) {\n          var node = this.nodes[depth];\n          var parent = this.nodes[depth - 1];\n          arr.pop();\n          var index = _.indexOf(parent._children, node);\n          if (index !== parent._children.length - 1) {\n            arr.push(parent._children[index + 1]);\n            return new Trail(arr);\n          } else {\n            depth--;\n          }\n        }\n        return null;\n      }\n    },\n    nextPainted: function () {\n      var result = this.next();\n      while (result && !result.isPainted()) {\n        result = result.next();\n      }\n      return result;\n    },\n    eachTrailUnder: function (callback) {\n      new scenery.TrailPointer(this, true).eachTrailBetween(new scenery.TrailPointer(this, false), callback);\n    },\n    compare: function (other) {\n      sceneryAssert && sceneryAssert(!this.isEmpty(), 'cannot compare with an empty trail');\n      sceneryAssert && sceneryAssert(!other.isEmpty(), 'cannot compare with an empty trail');\n      sceneryAssert && sceneryAssert(this.nodes[0] === other.nodes[0], 'for Trail comparison, trails must have the same root node');\n      sceneryAssertExtra && sceneryAssertExtra(this.areIndicesValid(), 'Trail.compare this.areIndicesValid() failed on ' + this.toString());\n      sceneryAssertExtra && sceneryAssertExtra(other.areIndicesValid(), 'Trail.compare other.areIndicesValid() failed on ' + other.toString());\n      var minNodeIndex = Math.min(this.indices.length, other.indices.length);\n      for (var i = 0; i < minNodeIndex; i++) {\n        if (this.indices[i] !== other.indices[i]) {\n          if (this.indices[i] < other.indices[i]) {\n            return -1;\n          } else {\n            return 1;\n          }\n        }\n      }\n      if (this.nodes.length < other.nodes.length) {\n        return -1;\n      } else if (this.nodes.length > other.nodes.length) {\n        return 1;\n      } else {\n        return 0;\n      }\n    },\n    isBefore: function (other) {\n      return this.compare(other) === -1;\n    },\n    isAfter: function (other) {\n      return this.compare(other) === 1;\n    },\n    localToGlobalPoint: function (point) {\n      return this.getMatrix().timesVector2(point);\n    },\n    localToGlobalBounds: function (bounds) {\n      return bounds.transformed(this.getMatrix());\n    },\n    globalToLocalPoint: function (point) {\n      return this.getTransform().inversePosition2(point);\n    },\n    globalToLocalBounds: function (bounds) {\n      return this.getTransform().inverseBounds2(bounds);\n    },\n    parentToGlobalPoint: function (point) {\n      return this.getParentMatrix().timesVector2(point);\n    },\n    parentToGlobalBounds: function (bounds) {\n      return bounds.transformed(this.getParentMatrix());\n    },\n    globalToParentPoint: function (point) {\n      return this.getParentTransform().inversePosition2(point);\n    },\n    globalToParentBounds: function (bounds) {\n      return this.getParentTransform().inverseBounds2(bounds);\n    },\n    updateUniqueId: function () {\n      var result = '';\n      var len = this.nodes.length;\n      if (len > 0) {\n        result += this.nodes[0]._id;\n      }\n      for (var i = 1; i < len; i++) {\n        result += '-' + this.nodes[i]._id;\n      }\n      this.uniqueId = result;\n    },\n    getUniqueId: function () {\n      if (sceneryAssert) {\n        var oldUniqueId = this.uniqueId;\n        this.updateUniqueId();\n        sceneryAssert(oldUniqueId === this.uniqueId);\n      }\n      return this.uniqueId;\n    },\n    toString: function () {\n      this.reindex();\n      if (!this.length) {\n        return 'Empty Trail';\n      }\n      return '[Trail ' + this.indices.join('.') + ' ' + this.getUniqueId() + ']';\n    }\n  };\n  Trail.eachPaintedTrailBetween = function (a, b, callback, excludeEndTrails, scene) {\n    Trail.eachTrailBetween(a, b, function (trail) {\n      if (trail && trail.isPainted()) {\n        callback(trail);\n      }\n    }, excludeEndTrails, scene);\n  };\n  Trail.eachTrailBetween = function (a, b, callback, excludeEndTrails, scene) {\n    var aPointer = a ? new scenery.TrailPointer(a.copy(), true) : new scenery.TrailPointer(new scenery.Trail(scene), true);\n    var bPointer = b ? new scenery.TrailPointer(b.copy(), true) : new scenery.TrailPointer(new scenery.Trail(scene), false);\n    if (excludeEndTrails) {\n      aPointer.nestedForwards();\n      bPointer.nestedBackwards();\n      if (aPointer.compareNested(bPointer) === 1) {\n        return;\n      }\n    }\n    aPointer.depthFirstUntil(bPointer, function (pointer) {\n      if (pointer.isBefore) {\n        callback(pointer.trail);\n      }\n    }, false);\n  };\n  return Trail;\n});",
    "\ndefine('SCENERY/input/DownUpListener',['require','SCENERY/scenery','SCENERY/util/Trail'],function (require) {\n  'use strict';\n  var scenery = require('SCENERY/scenery');\n  require('SCENERY/util/Trail');\n  scenery.DownUpListener = function DownUpListener(options) {\n    var handler = this;\n    this.options = _.extend({ mouseButton: 0 }, options);\n    this.isDown = false;\n    this.downCurrentTarget = null;\n    this.downTrail = null;\n    this.pointer = null;\n    this.downListener = {\n      up: function (event) {\n        sceneryAssert && sceneryAssert(event.pointer === handler.pointer);\n        if (!event.pointer.isMouse || event.domEvent.button === handler.options.mouseButton) {\n          handler.buttonUp(event);\n        }\n      },\n      cancel: function (event) {\n        sceneryAssert && sceneryAssert(event.pointer === handler.pointer);\n        handler.buttonUp(event);\n      }\n    };\n  };\n  var DownUpListener = scenery.DownUpListener;\n  DownUpListener.prototype = {\n    constructor: DownUpListener,\n    buttonDown: function (event) {\n      if (this.isDown) {\n        return;\n      }\n      if (event.pointer.isMouse && event.domEvent.button !== this.options.mouseButton) {\n        return;\n      }\n      event.pointer.addInputListener(this.downListener);\n      this.isDown = true;\n      this.downCurrentTarget = event.currentTarget;\n      this.downTrail = event.trail.subtrailTo(event.currentTarget, false);\n      this.pointer = event.pointer;\n      if (this.options.down) {\n        this.options.down(event, this.downTrail);\n      }\n    },\n    buttonUp: function (event) {\n      this.isDown = false;\n      this.pointer.removeInputListener(this.downListener);\n      var currentTargetSave = event.currentTarget;\n      event.currentTarget = this.downCurrentTarget;\n      if (this.options.upInside || this.options.upOutside) {\n        var scene = this.downTrail.rootNode();\n        var trailUnderPointer = event.trail;\n        var isInside = trailUnderPointer.isExtensionOf(this.downTrail, true);\n        if (isInside && this.options.upInside) {\n          this.options.upInside(event, this.downTrail);\n        } else if (!isInside && this.options.upOutside) {\n          this.options.upOutside(event, this.downTrail);\n        }\n      }\n      if (this.options.up) {\n        this.options.up(event, this.downTrail);\n      }\n      event.currentTarget = currentTargetSave;\n    },\n    down: function (event) {\n      this.buttonDown(event);\n    }\n  };\n  return DownUpListener;\n});",
    "\ndefine('SCENERY/input/ButtonListener',['require','SCENERY/scenery','SCENERY/util/Trail','PHET_CORE/inherit','SCENERY/input/DownUpListener'],function (require) {\n  'use strict';\n  var scenery = require('SCENERY/scenery');\n  require('SCENERY/util/Trail');\n  var inherit = require('PHET_CORE/inherit');\n  var DownUpListener = require('SCENERY/input/DownUpListener');\n  scenery.ButtonListener = function ButtonListener(options) {\n    this.buttonState = 'up';\n    this._overCount = 0;\n    this._buttonOptions = options;\n    var buttonListener = this;\n    DownUpListener.call(this, {\n      mouseButton: options.mouseButton || 0,\n      down: function (event, trail) {\n        buttonListener.setButtonState(event, 'down');\n      },\n      up: function (event, trail) {\n        buttonListener.setButtonState(event, buttonListener._overCount > 0 ? 'over' : 'up');\n      }\n    });\n  };\n  var ButtonListener = scenery.ButtonListener;\n  inherit(DownUpListener, ButtonListener, {\n    setButtonState: function (event, state) {\n      if (state !== this.buttonState) {\n        var oldState = this.buttonState;\n        this.buttonState = state;\n        if (this._buttonOptions[state]) {\n          this._buttonOptions[state](event, oldState);\n        }\n        if (this._buttonOptions.fire && this._overCount > 0 && (this._buttonOptions.fireOnDown ? state === 'down' : oldState === 'down')) {\n          this._buttonOptions.fire(event);\n        }\n      }\n    },\n    enter: function (event) {\n      this._overCount++;\n      if (this._overCount === 1) {\n        this.setButtonState(event, this.isDown ? 'down' : 'over');\n      }\n    },\n    exit: function (event) {\n      sceneryAssert && sceneryAssert(this._overCount > 0, 'Exit events not matched by an enter');\n      this._overCount--;\n      if (this._overCount === 0) {\n        this.setButtonState(event, this.isDown ? 'out' : 'up');\n      }\n    }\n  });\n  ButtonListener.TEST_LISTENER = new ButtonListener({\n    up: function (event, oldState) {\n      console.log('ButtonListener.up oldState=' + oldState);\n    },\n    over: function (event, oldState) {\n      console.log('ButtonListener.over oldState=' + oldState);\n    },\n    down: function (event, oldState) {\n      console.log('ButtonListener.down oldState=' + oldState);\n    },\n    out: function (event, oldState) {\n      console.log('ButtonListener.out oldState=' + oldState);\n    },\n    fire: function (event) {\n      console.log('ButtonListener.fire');\n    }\n  });\n  return ButtonListener;\n});",
    "\ndefine('SCENERY/layers/LayerType',['require','SCENERY/scenery'],function (require) {\n  'use strict';\n  var scenery = require('SCENERY/scenery');\n  scenery.LayerType = function LayerType(Constructor, name, renderer, args) {\n    this.Constructor = Constructor;\n    this.name = name;\n    this.renderer = renderer;\n    this.args = args;\n  };\n  var LayerType = scenery.LayerType;\n  LayerType.prototype = {\n    constructor: LayerType,\n    supportsRenderer: function (renderer) {\n      return this.renderer === renderer;\n    },\n    supportsNode: function (node) {\n      var supportedRenderers = node._supportedRenderers;\n      var i = supportedRenderers.length;\n      while (i--) {\n        if (this.supportsRenderer(supportedRenderers[i])) {\n          return true;\n        }\n      }\n      return false;\n    },\n    createLayer: function (args) {\n      var Constructor = this.Constructor;\n      return new Constructor(_.extend({}, args, this.args));\n    }\n  };\n  return LayerType;\n});",
    "\ndefine('SCENERY/layers/Layer',['require','DOT/Bounds2','DOT/Transform3','SCENERY/scenery','SCENERY/util/Trail'],function (require) {\n  'use strict';\n  var Bounds2 = require('DOT/Bounds2');\n  var Transform3 = require('DOT/Transform3');\n  var scenery = require('SCENERY/scenery');\n  require('SCENERY/util/Trail');\n  var globalIdCounter = 1;\n  scenery.Layer = function Layer(args) {\n    this._id = globalIdCounter++;\n    this.$main = args.$main;\n    this.scene = args.scene;\n    this.baseNode = args.baseNode;\n    this.usesPartialCSSTransforms = args.cssTranslation || args.cssRotation || args.cssScale;\n    this.cssTranslation = args.cssTranslation;\n    this.cssRotation = args.cssRotation;\n    this.cssScale = args.cssScale;\n    this.cssTransform = args.cssTransform;\n    sceneryAssert && sceneryAssert(!(this.usesPartialCSSTransforms && this.cssTransform), 'Do not specify both partial and complete CSS transform arguments.');\n    this.dirtyBounds = Bounds2.EVERYTHING;\n    this.setStartBoundary(args.startBoundary);\n    this.setEndBoundary(args.endBoundary);\n    if (this.baseNode === this.scene) {\n      this.baseTrail = new scenery.Trail(this.scene);\n    } else {\n      this.baseTrail = this.startPaintedTrail.upToNode(this.baseNode);\n      sceneryAssert && sceneryAssert(this.baseTrail.lastNode() === this.baseNode);\n    }\n    this._layerTrails = [];\n    this._instanceCount = 0;\n    var layer = this;\n    this.baseNodeBoundsListener = function (bounds) {\n      layer.baseNodeInternalBoundsChange();\n    };\n    this.baseNode.addEventListener('selfBounds', this.baseNodeBoundsListener);\n    this.baseNode.addEventListener('childBounds', this.baseNodeBoundsListener);\n    this.fitToBounds = this.usesPartialCSSTransforms || this.cssTransform;\n    sceneryAssert && sceneryAssert(this.fitToBounds || this.baseNode === this.scene, 'If the baseNode is not the scene, we need to fit the bounds');\n    this.baseNodeTransform = new Transform3();\n    this.disposed = false;\n  };\n  var Layer = scenery.Layer;\n  Layer.prototype = {\n    constructor: Layer,\n    setStartBoundary: function (boundary) {\n      this.startBoundary = boundary;\n      this.startPaintedTrail = this.startBoundary.nextPaintedTrail;\n      this.startPaintedTrail.setImmutable();\n    },\n    setEndBoundary: function (boundary) {\n      this.endBoundary = boundary;\n      this.endPaintedTrail = this.endBoundary.previousPaintedTrail;\n      this.endPaintedTrail.setImmutable();\n    },\n    toString: function () {\n      return this.getName() + ' ' + (this.startPaintedTrail ? this.startPaintedTrail.toString() : '!') + ' => ' + (this.endPaintedTrail ? this.endPaintedTrail.toString() : '!');\n    },\n    getId: function () {\n      return this._id;\n    },\n    get id() {\n      return this._id;\n    },\n    getLayerTrails: function () {\n      return this._layerTrails.slice(0);\n    },\n    getPaintedTrailCount: function () {\n      return this._layerTrails.length;\n    },\n    render: function (state) {\n      throw new Error('Layer.render unimplemented');\n    },\n    applyTransformationMatrix: function (matrix) {\n      throw new Error('Layer.applyTransformationMatrix unimplemented');\n    },\n    addInstance: function (instance) {\n      var trail = instance.trail;\n      if (sceneryAssert) {\n        _.each(this._layerTrails, function (otherTrail) {\n          sceneryAssert(!trail.equals(otherTrail), 'trail in addInstance should not already exist in a layer');\n        });\n      }\n      this._layerTrails.push(trail);\n      trail.setImmutable();\n    },\n    removeInstance: function (instance) {\n      var i;\n      for (i = 0; i < this._layerTrails.length; i++) {\n        this._layerTrails[i].reindex();\n        if (this._layerTrails[i].compare(instance.trail) === 0) {\n          break;\n        }\n      }\n      sceneryAssert && sceneryAssert(i < this._layerTrails.length);\n      this._layerTrails.splice(i, 1);\n    },\n    reindex: function (zIndex) {\n      this.startBoundary.reindex();\n      this.endBoundary.reindex();\n    },\n    pushClipShape: function (shape) {\n      throw new Error('Layer.pushClipShape unimplemented');\n    },\n    popClipShape: function () {\n      throw new Error('Layer.popClipShape unimplemented');\n    },\n    renderToCanvas: function (canvas, context, delayCounts) {\n      throw new Error('Layer.renderToCanvas unimplemented');\n    },\n    dispose: function () {\n      sceneryAssert && sceneryAssert(!this.disposed, 'Layer has already been disposed!');\n      this.disposed = true;\n      this.baseNode.removeEventListener('selfBounds', this.baseNodeBoundsListener);\n      this.baseNode.removeEventListener('childBounds', this.baseNodeBoundsListener);\n    },\n    getName: function () {\n      throw new Error('Layer.getName unimplemented');\n    },\n    baseNodeInternalBoundsChange: function () {\n    }\n  };\n  Layer.cssTransformPadding = 3;\n  return Layer;\n});",
    "\ndefine('SCENERY/util/CanvasContextWrapper',['require','SCENERY/scenery'],function (require) {\n  'use strict';\n  var scenery = require('SCENERY/scenery');\n  scenery.CanvasContextWrapper = function CanvasContextWrapper(canvas, context) {\n    this.canvas = canvas;\n    this.context = context;\n    this.resetStyles();\n    phetAllocation && phetAllocation('CanvasContextWrapper');\n  };\n  var CanvasContextWrapper = scenery.CanvasContextWrapper;\n  CanvasContextWrapper.prototype = {\n    constructor: CanvasContextWrapper,\n    resetStyles: function () {\n      this.fillStyle = undefined;\n      this.strokeStyle = undefined;\n      this.lineWidth = undefined;\n      this.lineCap = undefined;\n      this.lineJoin = undefined;\n      this.lineDash = undefined;\n      this.lineDashOffset = undefined;\n      this.miterLimit = undefined;\n      this.font = undefined;\n      this.direction = undefined;\n    },\n    setDimensions: function (width, height) {\n      this.canvas.width = width;\n      this.canvas.height = height;\n      this.resetStyles();\n    },\n    setFillStyle: function (style) {\n      if (this.fillStyle !== style) {\n        this.fillStyle = style;\n        this.context.fillStyle = style && style.getCanvasStyle ? style.getCanvasStyle() : style;\n      }\n    },\n    setStrokeStyle: function (style) {\n      if (this.strokeStyle !== style) {\n        this.strokeStyle = style;\n        this.context.strokeStyle = style && style.getCanvasStyle ? style.getCanvasStyle() : style;\n      }\n    },\n    setLineWidth: function (width) {\n      if (this.lineWidth !== width) {\n        this.lineWidth = width;\n        this.context.lineWidth = width;\n      }\n    },\n    setLineCap: function (cap) {\n      if (this.lineCap !== cap) {\n        this.lineCap = cap;\n        this.context.lineCap = cap;\n      }\n    },\n    setLineJoin: function (join) {\n      if (this.lineJoin !== join) {\n        this.lineJoin = join;\n        this.context.lineJoin = join;\n      }\n    },\n    setLineDash: function (dash) {\n      sceneryAssert && sceneryAssert(dash !== undefined, 'undefined line dash would cause hard-to-trace errors');\n      if (this.lineDash !== dash) {\n        this.lineDash = dash;\n        if (this.context.setLineDash) {\n          this.context.setLineDash(dash === null ? [] : dash);\n        } else if (this.context.mozDash !== undefined) {\n          this.context.mozDash = dash;\n        } else if (this.context.webkitLineDash !== undefined) {\n          this.context.webkitLineDash = dash ? dash : [];\n        } else {\n        }\n      }\n    },\n    setLineDashOffset: function (lineDashOffset) {\n      if (this.lineDashOffset !== lineDashOffset) {\n        this.lineDashOffset = lineDashOffset;\n        if (this.context.lineDashOffset !== undefined) {\n          this.context.lineDashOffset = lineDashOffset;\n        } else if (this.context.webkitLineDashOffset !== undefined) {\n          this.context.webkitLineDashOffset = lineDashOffset;\n        } else {\n        }\n      }\n    },\n    setFont: function (font) {\n      if (this.font !== font) {\n        this.font = font;\n        this.context.font = font;\n      }\n    },\n    setDirection: function (direction) {\n      if (this.direction !== direction) {\n        this.direction = direction;\n        this.context.direction = direction;\n      }\n    }\n  };\n  return CanvasContextWrapper;\n});",
    "\ndefine('SCENERY/util/TrailPointer',['require','SCENERY/scenery','SCENERY/util/Trail'],function (require) {\n  'use strict';\n  var scenery = require('SCENERY/scenery');\n  require('SCENERY/util/Trail');\n  scenery.TrailPointer = function TrailPointer(trail, isBefore) {\n    sceneryAssert && sceneryAssert(trail instanceof scenery.Trail, 'trail is not a trail');\n    this.trail = trail;\n    this.setBefore(isBefore);\n    phetAllocation && phetAllocation('TrailPointer');\n  };\n  var TrailPointer = scenery.TrailPointer;\n  TrailPointer.prototype = {\n    constructor: TrailPointer,\n    copy: function () {\n      return new TrailPointer(this.trail.copy(), this.isBefore);\n    },\n    setBefore: function (isBefore) {\n      this.isBefore = isBefore;\n      this.isAfter = !isBefore;\n    },\n    getRenderSwappedPointer: function () {\n      var newTrail = this.isBefore ? this.trail.previous() : this.trail.next();\n      if (newTrail === null) {\n        return null;\n      } else {\n        return new TrailPointer(newTrail, !this.isBefore);\n      }\n    },\n    getRenderBeforePointer: function () {\n      return this.isBefore ? this : this.getRenderSwappedPointer();\n    },\n    getRenderAfterPointer: function () {\n      return this.isAfter ? this : this.getRenderSwappedPointer();\n    },\n    compareRender: function (other) {\n      sceneryAssert && sceneryAssert(other !== null);\n      var a = this.getRenderBeforePointer();\n      var b = other.getRenderBeforePointer();\n      if (a !== null && b !== null) {\n        return a.trail.compare(b.trail);\n      } else {\n        if (a === b) {\n          return 0;\n        } else {\n          return a === null ? 1 : -1;\n        }\n      }\n    },\n    compareNested: function (other) {\n      sceneryAssert && sceneryAssert(other);\n      var comparison = this.trail.compare(other.trail);\n      if (comparison === 0) {\n        if (this.isBefore === other.isBefore) {\n          return 0;\n        } else {\n          return this.isBefore ? -1 : 1;\n        }\n      } else {\n        if (this.trail.isExtensionOf(other.trail)) {\n          return other.isBefore ? 1 : -1;\n        } else if (other.trail.isExtensionOf(this.trail)) {\n          return this.isBefore ? -1 : 1;\n        } else {\n          return comparison;\n        }\n      }\n    },\n    equalsRender: function (other) {\n      return this.compareRender(other) === 0;\n    },\n    equalsNested: function (other) {\n      return this.compareNested(other) === 0;\n    },\n    hasTrail: function () {\n      return !!this.trail;\n    },\n    nestedForwards: function () {\n      if (this.isBefore) {\n        if (this.trail.lastNode()._children.length > 0) {\n          this.trail.addDescendant(this.trail.lastNode()._children[0], 0);\n        } else {\n          this.setBefore(false);\n        }\n      } else {\n        if (this.trail.indices.length === 0) {\n          this.trail = null;\n          return null;\n        } else {\n          var index = this.trail.indices[this.trail.indices.length - 1];\n          this.trail.removeDescendant();\n          if (this.trail.lastNode()._children.length > index + 1) {\n            this.trail.addDescendant(this.trail.lastNode()._children[index + 1], index + 1);\n            this.setBefore(true);\n          } else {\n          }\n        }\n      }\n      return this;\n    },\n    nestedBackwards: function () {\n      if (this.isBefore) {\n        if (this.trail.indices.length === 0) {\n          this.trail = null;\n          return null;\n        } else {\n          var index = this.trail.indices[this.trail.indices.length - 1];\n          this.trail.removeDescendant();\n          if (index - 1 >= 0) {\n            this.trail.addDescendant(this.trail.lastNode()._children[index - 1], index - 1);\n            this.setBefore(false);\n          } else {\n          }\n        }\n      } else {\n        if (this.trail.lastNode()._children.length > 0) {\n          var children = this.trail.lastNode()._children;\n          this.trail.addDescendant(children[children.length - 1], children.length - 1);\n        } else {\n          this.setBefore(true);\n        }\n      }\n      return this;\n    },\n    eachNodeBetween: function (other, callback) {\n      this.eachTrailBetween(other, function (trail) {\n        callback(trail.lastNode());\n      });\n    },\n    eachTrailBetween: function (other, callback) {\n      if (this.isBefore) {\n        callback(this.trail);\n      }\n      this.depthFirstUntil(other, function (pointer) {\n        if (pointer.isBefore) {\n          callback(pointer.trail);\n        }\n      }, true);\n    },\n    depthFirstUntil: function (other, callback, excludeEndpoints) {\n      sceneryAssert && sceneryAssert(this.compareNested(other) <= (excludeEndpoints ? -1 : 0), 'TrailPointer.depthFirstUntil pointers out of order, possibly in both meanings of the phrase!');\n      sceneryAssert && sceneryAssert(this.trail.rootNode() === other.trail.rootNode(), 'TrailPointer.depthFirstUntil takes pointers with the same root');\n      this.trail.reindex();\n      other.trail.reindex();\n      var pointer = this.copy();\n      pointer.trail.setMutable();\n      var first = true;\n      while (!pointer.equalsNested(other)) {\n        sceneryAssert && sceneryAssert(pointer.compareNested(other) !== 1, 'skipped in depthFirstUntil');\n        var skipSubtree = false;\n        if (first) {\n          if (!excludeEndpoints) {\n            skipSubtree = callback(pointer);\n          }\n          first = false;\n        } else {\n          skipSubtree = callback(pointer);\n        }\n        if (skipSubtree && pointer.isBefore) {\n          pointer.setBefore(false);\n          if (pointer.compareNested(other) === 1) {\n            break;\n          }\n        } else {\n          pointer.nestedForwards();\n        }\n      }\n      if (!excludeEndpoints) {\n        callback(pointer);\n      }\n    },\n    toString: function () {\n      return '[' + (this.isBefore ? 'before' : 'after') + ' ' + this.trail.toString().slice(1);\n    }\n  };\n  TrailPointer.compareNested = function (trailA, isBeforeA, trailB, isBeforeB) {\n    var comparison = trailA.compare(trailB);\n    if (comparison === 0) {\n      if (isBeforeA === isBeforeB) {\n        return 0;\n      } else {\n        return isBeforeA ? -1 : 1;\n      }\n    } else {\n      if (trailA.isExtensionOf(trailB)) {\n        return isBeforeB ? 1 : -1;\n      } else if (trailB.isExtensionOf(trailA)) {\n        return isBeforeA ? -1 : 1;\n      } else {\n        return comparison;\n      }\n    }\n  };\n  return TrailPointer;\n});",
    "\ndefine('SCENERY/util/Util',['require','SCENERY/scenery','DOT/Matrix3','DOT/Transform3','DOT/Bounds2','DOT/Vector2'],function (require) {\n  'use strict';\n  var scenery = require('SCENERY/scenery');\n  var Matrix3 = require('DOT/Matrix3');\n  var Transform3 = require('DOT/Transform3');\n  var Bounds2 = require('DOT/Bounds2');\n  var Vector2 = require('DOT/Vector2');\n  function p(x, y) {\n    return new Vector2(x, y);\n  }\n  var debugChromeBoundsScanning = false;\n  var transformProperty = '';\n  var transformOriginProperty = '';\n  var webkitHardwareAcceleration = false;\n  var mozillaHardwareAcceleration = false;\n  if (document && document.createElement) {\n    var style = document.createElement('div').style;\n    var transformNames = [\n        'transform',\n        'webkitTransform',\n        'oTransform',\n        'mozTransform',\n        'msTransform'\n      ];\n    var transformOriginNames = [\n        'transformOrigin',\n        'webkitTransformOrigin',\n        'oTransformOrigin',\n        'mozTransformOrigin',\n        'msTransformOrigin'\n      ];\n    var i;\n    for (i = 0; i < transformNames.length; i++) {\n      if (transformNames[i] in style) {\n        transformProperty = transformNames[i];\n        break;\n      }\n    }\n    for (i = 0; i < transformOriginNames.length; i++) {\n      if (transformOriginNames[i] in style) {\n        transformOriginProperty = transformOriginNames[i];\n        break;\n      }\n    }\n    if (!transformOriginProperty) {\n      transformOriginProperty = 'transformOrigin';\n    }\n    if ('webkitBackfaceVisibility' in style || 'webkitTransform' in style) {\n      webkitHardwareAcceleration = true;\n    }\n    if ('mozTransform' in style) {\n      mozillaHardwareAcceleration = true;\n    }\n  }\n  scenery.Util = {\n    extend: function (obj) {\n      _.each(Array.prototype.slice.call(arguments, 1), function (source) {\n        if (source) {\n          for (var prop in source) {\n            Object.defineProperty(obj, prop, Object.getOwnPropertyDescriptor(source, prop));\n          }\n        }\n      });\n      return obj;\n    },\n    objectCreate: Object.create || function (o) {\n      if (arguments.length > 1) {\n        throw new Error('Object.create implementation only accepts the first parameter.');\n      }\n      function F() {\n      }\n      F.prototype = o;\n      return new F();\n    },\n    applyCSSTransform: function (matrix, element) {\n      var transformCSS = matrix.getCSSTransform();\n      if (webkitHardwareAcceleration || mozillaHardwareAcceleration) {\n        transformCSS += ' translateZ(0)';\n      }\n      if (webkitHardwareAcceleration) {\n        element.style.webkitBackfaceVisibility = 'hidden';\n      }\n      element.style[transformProperty] = transformCSS;\n      element.style[transformOriginProperty] = 'top left';\n    },\n    testAssert: function () {\n      return 'assert.scenery: ' + (sceneryAssert ? 'true' : 'false');\n    },\n    testAssertExtra: function () {\n      return 'assert.scenery.extra: ' + (sceneryAssertExtra ? 'true' : 'false');\n    },\n    polyfillRequestAnimationFrame: function () {\n      var lastTime = 0;\n      var vendors = [\n          'ms',\n          'moz',\n          'webkit',\n          'o'\n        ];\n      for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {\n        window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];\n        window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || window[vendors[x] + 'CancelRequestAnimationFrame'];\n      }\n      if (!window.requestAnimationFrame) {\n        window.requestAnimationFrame = function (callback) {\n          var currTime = new Date().getTime();\n          var timeToCall = Math.max(0, 16 - (currTime - lastTime));\n          var id = window.setTimeout(function () {\n              callback(currTime + timeToCall);\n            }, timeToCall);\n          lastTime = currTime + timeToCall;\n          return id;\n        };\n      }\n      if (!window.cancelAnimationFrame) {\n        window.cancelAnimationFrame = function (id) {\n          clearTimeout(id);\n        };\n      }\n    },\n    backingStorePixelRatio: function (context) {\n      return context.webkitBackingStorePixelRatio || context.mozBackingStorePixelRatio || context.msBackingStorePixelRatio || context.oBackingStorePixelRatio || context.backingStorePixelRatio || 1;\n    },\n    backingScale: function (context) {\n      if ('devicePixelRatio' in window) {\n        var backingStoreRatio = Util.backingStorePixelRatio(context);\n        return window.devicePixelRatio / backingStoreRatio;\n      }\n      return 1;\n    },\n    scanBounds: function (imageData, resolution, transform) {\n      var dirtyX = _.map(_.range(resolution), function () {\n          return false;\n        });\n      var dirtyY = _.map(_.range(resolution), function () {\n          return false;\n        });\n      for (var x = 0; x < resolution; x++) {\n        for (var y = 0; y < resolution; y++) {\n          var offset = 4 * (y * resolution + x);\n          if (imageData.data[offset] !== 0 || imageData.data[offset + 1] !== 0 || imageData.data[offset + 2] !== 0 || imageData.data[offset + 3] !== 0) {\n            dirtyX[x] = true;\n            dirtyY[y] = true;\n          }\n        }\n      }\n      var minX = _.indexOf(dirtyX, true);\n      var maxX = _.lastIndexOf(dirtyX, true);\n      var minY = _.indexOf(dirtyY, true);\n      var maxY = _.lastIndexOf(dirtyY, true);\n      var extraSpread = resolution / 16;\n      return {\n        minBounds: new Bounds2(minX < 1 || minX >= resolution - 1 ? Number.POSITIVE_INFINITY : transform.inversePosition2(p(minX + 1 + extraSpread, 0)).x, minY < 1 || minY >= resolution - 1 ? Number.POSITIVE_INFINITY : transform.inversePosition2(p(0, minY + 1 + extraSpread)).y, maxX < 1 || maxX >= resolution - 1 ? Number.NEGATIVE_INFINITY : transform.inversePosition2(p(maxX - extraSpread, 0)).x, maxY < 1 || maxY >= resolution - 1 ? Number.NEGATIVE_INFINITY : transform.inversePosition2(p(0, maxY - extraSpread)).y),\n        maxBounds: new Bounds2(minX < 1 || minX >= resolution - 1 ? Number.NEGATIVE_INFINITY : transform.inversePosition2(p(minX - 1 - extraSpread, 0)).x, minY < 1 || minY >= resolution - 1 ? Number.NEGATIVE_INFINITY : transform.inversePosition2(p(0, minY - 1 - extraSpread)).y, maxX < 1 || maxX >= resolution - 1 ? Number.POSITIVE_INFINITY : transform.inversePosition2(p(maxX + 2 + extraSpread, 0)).x, maxY < 1 || maxY >= resolution - 1 ? Number.POSITIVE_INFINITY : transform.inversePosition2(p(0, maxY + 2 + extraSpread)).y)\n      };\n    },\n    canvasAccurateBounds: function (renderToContext, options) {\n      var precision = options && options.precision ? options.precision : 0.001;\n      var resolution = options && options.resolution ? options.resolution : 128;\n      var initialScale = options && options.initialScale ? options.initialScale : 1 / 16;\n      var minBounds = Bounds2.NOTHING;\n      var maxBounds = Bounds2.EVERYTHING;\n      var canvas = document.createElement('canvas');\n      canvas.width = resolution;\n      canvas.height = resolution;\n      var context = canvas.getContext('2d');\n      if (debugChromeBoundsScanning) {\n        $(window).ready(function () {\n          var header = document.createElement('h2');\n          $(header).text('Bounds Scan');\n          $('#display').append(header);\n        });\n      }\n      function scan(transform) {\n        context.save();\n        transform.matrix.canvasSetTransform(context);\n        renderToContext(context);\n        context.restore();\n        var data = context.getImageData(0, 0, resolution, resolution);\n        var minMaxBounds = Util.scanBounds(data, resolution, transform);\n        function snapshotToCanvas(snapshot) {\n          var canvas = document.createElement('canvas');\n          canvas.width = resolution;\n          canvas.height = resolution;\n          var context = canvas.getContext('2d');\n          context.putImageData(snapshot, 0, 0);\n          $(canvas).css('border', '1px solid black');\n          $(window).ready(function () {\n            $('#display').append(canvas);\n          });\n        }\n        if (debugChromeBoundsScanning) {\n          snapshotToCanvas(data);\n        }\n        context.clearRect(0, 0, resolution, resolution);\n        return minMaxBounds;\n      }\n      function idealTransform(bounds) {\n        var borderSize = 2;\n        var scaleX = (resolution - borderSize * 2) / (bounds.maxX - bounds.minX);\n        var scaleY = (resolution - borderSize * 2) / (bounds.maxY - bounds.minY);\n        var translationX = -scaleX * bounds.minX + borderSize;\n        var translationY = -scaleY * bounds.minY + borderSize;\n        return new Transform3(Matrix3.translation(translationX, translationY).timesMatrix(Matrix3.scaling(scaleX, scaleY)));\n      }\n      var initialTransform = new Transform3();\n      initialTransform.append(Matrix3.translation(resolution / 2, resolution / 2));\n      initialTransform.append(Matrix3.scaling(initialScale));\n      var coarseBounds = scan(initialTransform);\n      minBounds = minBounds.union(coarseBounds.minBounds);\n      maxBounds = maxBounds.intersection(coarseBounds.maxBounds);\n      var tempMin, tempMax, refinedBounds;\n      tempMin = maxBounds.minY;\n      tempMax = maxBounds.maxY;\n      while (isFinite(minBounds.minX) && isFinite(maxBounds.minX) && Math.abs(minBounds.minX - maxBounds.minX) > precision) {\n        refinedBounds = scan(idealTransform(new Bounds2(maxBounds.minX, tempMin, minBounds.minX, tempMax)));\n        if (minBounds.minX <= refinedBounds.minBounds.minX && maxBounds.minX >= refinedBounds.maxBounds.minX) {\n          if (debugChromeBoundsScanning) {\n            console.log('warning, exiting infinite loop!');\n            console.log('transformed \"min\" minX: ' + idealTransform(new Bounds2(maxBounds.minX, maxBounds.minY, minBounds.minX, maxBounds.maxY)).transformPosition2(p(minBounds.minX, 0)));\n            console.log('transformed \"max\" minX: ' + idealTransform(new Bounds2(maxBounds.minX, maxBounds.minY, minBounds.minX, maxBounds.maxY)).transformPosition2(p(maxBounds.minX, 0)));\n          }\n          break;\n        }\n        minBounds = minBounds.withMinX(Math.min(minBounds.minX, refinedBounds.minBounds.minX));\n        maxBounds = maxBounds.withMinX(Math.max(maxBounds.minX, refinedBounds.maxBounds.minX));\n        tempMin = Math.max(tempMin, refinedBounds.maxBounds.minY);\n        tempMax = Math.min(tempMax, refinedBounds.maxBounds.maxY);\n      }\n      tempMin = maxBounds.minY;\n      tempMax = maxBounds.maxY;\n      while (isFinite(minBounds.maxX) && isFinite(maxBounds.maxX) && Math.abs(minBounds.maxX - maxBounds.maxX) > precision) {\n        refinedBounds = scan(idealTransform(new Bounds2(minBounds.maxX, tempMin, maxBounds.maxX, tempMax)));\n        if (minBounds.maxX >= refinedBounds.minBounds.maxX && maxBounds.maxX <= refinedBounds.maxBounds.maxX) {\n          if (debugChromeBoundsScanning) {\n            console.log('warning, exiting infinite loop!');\n          }\n          break;\n        }\n        minBounds = minBounds.withMaxX(Math.max(minBounds.maxX, refinedBounds.minBounds.maxX));\n        maxBounds = maxBounds.withMaxX(Math.min(maxBounds.maxX, refinedBounds.maxBounds.maxX));\n        tempMin = Math.max(tempMin, refinedBounds.maxBounds.minY);\n        tempMax = Math.min(tempMax, refinedBounds.maxBounds.maxY);\n      }\n      tempMin = maxBounds.minX;\n      tempMax = maxBounds.maxX;\n      while (isFinite(minBounds.minY) && isFinite(maxBounds.minY) && Math.abs(minBounds.minY - maxBounds.minY) > precision) {\n        refinedBounds = scan(idealTransform(new Bounds2(tempMin, maxBounds.minY, tempMax, minBounds.minY)));\n        if (minBounds.minY <= refinedBounds.minBounds.minY && maxBounds.minY >= refinedBounds.maxBounds.minY) {\n          if (debugChromeBoundsScanning) {\n            console.log('warning, exiting infinite loop!');\n          }\n          break;\n        }\n        minBounds = minBounds.withMinY(Math.min(minBounds.minY, refinedBounds.minBounds.minY));\n        maxBounds = maxBounds.withMinY(Math.max(maxBounds.minY, refinedBounds.maxBounds.minY));\n        tempMin = Math.max(tempMin, refinedBounds.maxBounds.minX);\n        tempMax = Math.min(tempMax, refinedBounds.maxBounds.maxX);\n      }\n      tempMin = maxBounds.minX;\n      tempMax = maxBounds.maxX;\n      while (isFinite(minBounds.maxY) && isFinite(maxBounds.maxY) && Math.abs(minBounds.maxY - maxBounds.maxY) > precision) {\n        refinedBounds = scan(idealTransform(new Bounds2(tempMin, minBounds.maxY, tempMax, maxBounds.maxY)));\n        if (minBounds.maxY >= refinedBounds.minBounds.maxY && maxBounds.maxY <= refinedBounds.maxBounds.maxY) {\n          if (debugChromeBoundsScanning) {\n            console.log('warning, exiting infinite loop!');\n          }\n          break;\n        }\n        minBounds = minBounds.withMaxY(Math.max(minBounds.maxY, refinedBounds.minBounds.maxY));\n        maxBounds = maxBounds.withMaxY(Math.min(maxBounds.maxY, refinedBounds.maxBounds.maxY));\n        tempMin = Math.max(tempMin, refinedBounds.maxBounds.minX);\n        tempMax = Math.min(tempMax, refinedBounds.maxBounds.maxX);\n      }\n      if (debugChromeBoundsScanning) {\n        console.log('minBounds: ' + minBounds);\n        console.log('maxBounds: ' + maxBounds);\n      }\n      var result = new Bounds2((minBounds.minX + maxBounds.minX) / 2, (minBounds.minY + maxBounds.minY) / 2, (minBounds.maxX + maxBounds.maxX) / 2, (minBounds.maxY + maxBounds.maxY) / 2);\n      result.minBounds = minBounds;\n      result.maxBounds = maxBounds;\n      result.isConsistent = maxBounds.containsBounds(minBounds);\n      result.precision = Math.max(Math.abs(minBounds.minX - maxBounds.minX), Math.abs(minBounds.minY - maxBounds.minY), Math.abs(minBounds.maxX - maxBounds.maxX), Math.abs(minBounds.maxY - maxBounds.maxY));\n      return result;\n    }\n  };\n  var Util = scenery.Util;\n  return Util;\n});",
    "\ndefine('SCENERY/layers/CanvasLayer',['require','PHET_CORE/inherit','DOT/Bounds2','SCENERY/scenery','KITE/Shape','SCENERY/layers/Layer','SCENERY/util/CanvasContextWrapper','SCENERY/util/Trail','SCENERY/util/TrailPointer','SCENERY/util/Util'],function (require) {\n  'use strict';\n  var inherit = require('PHET_CORE/inherit');\n  var Bounds2 = require('DOT/Bounds2');\n  var scenery = require('SCENERY/scenery');\n  var Shape = require('KITE/Shape');\n  var Layer = require('SCENERY/layers/Layer');\n  require('SCENERY/util/CanvasContextWrapper');\n  require('SCENERY/util/Trail');\n  require('SCENERY/util/TrailPointer');\n  require('SCENERY/util/Util');\n  var canvasContextPool = [];\n  scenery.CanvasLayer = function CanvasLayer(args) {\n    sceneryLayerLog && sceneryLayerLog('CanvasLayer #' + this.id + ' constructor');\n    Layer.call(this, args);\n    this.backingScale = args.scene.backingScale;\n    if (args.fullResolution !== undefined) {\n      this.backingScale = args.fullResolution ? scenery.Util.backingScale(document.createElement('canvas').getContext('2d')) : 1;\n    }\n    this.logicalWidth = this.scene.sceneBounds.width;\n    this.logicalHeight = this.scene.sceneBounds.height;\n    var canvas = document.createElement('canvas');\n    canvas.width = this.logicalWidth * this.backingScale;\n    canvas.height = this.logicalHeight * this.backingScale;\n    canvas.style.width = this.logicalWidth + 'px';\n    canvas.style.height = this.logicalHeight + 'px';\n    canvas.style.position = 'absolute';\n    canvas.style.left = '0';\n    canvas.style.top = '0';\n    this.$main.append(canvas);\n    this.canvas = canvas;\n    this.context = canvas.getContext('2d');\n    this.scene = args.scene;\n    this.context.miterLimit = 20;\n    this.context.miterLimit = 10;\n    this.isCanvasLayer = true;\n    this.wrapper = new scenery.CanvasContextWrapper(this.canvas, this.context);\n    this.boundlessCount = 0;\n  };\n  var CanvasLayer = scenery.CanvasLayer;\n  inherit(Layer, CanvasLayer, {\n    render: function (scene, args) {\n      args = args || {};\n      var dirtyBoundsEnabled = this.canUseDirtyRegions() && !args.fullRender;\n      if (dirtyBoundsEnabled && this.dirtyBounds.isEmpty()) {\n        return;\n      }\n      this.context.setTransform(this.backingScale, 0, 0, this.backingScale, 0, 0);\n      var visibleDirtyBounds = dirtyBoundsEnabled ? this.dirtyBounds.intersection(scene.sceneBounds) : scene.sceneBounds;\n      if (!visibleDirtyBounds.isEmpty()) {\n        this.clearGlobalBounds(visibleDirtyBounds);\n        if (dirtyBoundsEnabled) {\n          this.pushClipShape(Shape.bounds(visibleDirtyBounds));\n        }\n        this.recursiveRender(scene, args);\n        if (dirtyBoundsEnabled) {\n          this.popClipShape();\n        }\n      }\n      this.dirtyBounds = Bounds2.NOTHING;\n    },\n    recursiveRender: function (scene, args) {\n      var layer = this;\n      var i;\n      var startPointer = new scenery.TrailPointer(this.startPaintedTrail, true);\n      var endPointer = new scenery.TrailPointer(this.endPaintedTrail, true);\n      var wrapperStack = [this.wrapper];\n      this.wrapper.resetStyles();\n      function requiresScratchCanvas(trail) {\n        return trail.lastNode().getOpacity() < 1;\n      }\n      function getCanvasWrapper() {\n        var width = layer.logicalWidth * layer.backingScale;\n        var height = layer.logicalHeight * layer.backingScale;\n        if (canvasContextPool.length) {\n          var wrapper = canvasContextPool.pop();\n          wrapper.setDimensions(width, height);\n          return wrapper;\n        } else {\n          var canvas = document.createElement('canvas');\n          canvas.width = layer.logicalWidth * layer.backingScale;\n          canvas.height = layer.logicalHeight * layer.backingScale;\n          var context = canvas.getContext('2d');\n          return new scenery.CanvasContextWrapper(canvas, context);\n        }\n      }\n      function topWrapper() {\n        return wrapperStack[wrapperStack.length - 1];\n      }\n      function enter(trail) {\n        var node = trail.lastNode();\n        if (requiresScratchCanvas(trail)) {\n          var wrapper = getCanvasWrapper();\n          wrapperStack.push(wrapper);\n          var newContext = wrapper.context;\n          newContext.setTransform(layer.backingScale, 0, 0, layer.backingScale, 0, 0);\n          var length = trail.nodes.length;\n          for (var i = 0; i < length; i++) {\n            trail.nodes[i].transform.getMatrix().canvasAppendTransform(newContext);\n          }\n        } else {\n          node.transform.getMatrix().canvasAppendTransform(topWrapper().context);\n        }\n        if (node._clipShape) {\n          layer.pushClipShape(node._clipShape);\n        }\n      }\n      function exit(trail) {\n        var node = trail.lastNode();\n        if (node._clipShape) {\n          layer.popClipShape();\n        }\n        if (requiresScratchCanvas(trail)) {\n          var baseContext = wrapperStack[wrapperStack.length - 2].context;\n          var topCanvas = wrapperStack[wrapperStack.length - 1].canvas;\n          var opacityChange = trail.lastNode().getOpacity() < 1;\n          if (opacityChange) {\n            baseContext.globalAlpha = trail.lastNode().getOpacity();\n          }\n          baseContext.save();\n          baseContext.setTransform(1, 0, 0, 1, 0, 0);\n          baseContext.drawImage(topCanvas, 0, 0);\n          baseContext.restore();\n          if (opacityChange) {\n            baseContext.globalAlpha = 1;\n          }\n          var wrapper = wrapperStack.pop();\n          if (wrapper !== layer.wrapper) {\n            canvasContextPool.push(wrapper);\n          }\n        } else {\n          node.transform.getInverse().canvasAppendTransform(topWrapper().context);\n        }\n      }\n      var invisibleCount = 0;\n      var boundaryTrail;\n      startPointer.trail.reindex();\n      endPointer.trail.reindex();\n      var startWalkLength = startPointer.trail.length - (startPointer.isBefore ? 1 : 0);\n      boundaryTrail = new scenery.Trail();\n      for (i = 0; i < startWalkLength; i++) {\n        var startNode = startPointer.trail.nodes[i];\n        boundaryTrail.addDescendant(startNode);\n        invisibleCount += startNode.isVisible() ? 0 : 1;\n        if (invisibleCount === 0) {\n          enter(boundaryTrail);\n        }\n      }\n      startPointer.depthFirstUntil(endPointer, function renderPointer(pointer) {\n        var node = pointer.trail.lastNode();\n        if (pointer.isBefore) {\n          invisibleCount += node.isVisible() ? 0 : 1;\n          if (invisibleCount === 0) {\n            enter(pointer.trail);\n            if (node.isPainted()) {\n              var wrapper = wrapperStack[wrapperStack.length - 1];\n              node.paintCanvas(wrapper);\n            }\n          } else {\n            return true;\n          }\n        } else {\n          if (invisibleCount === 0) {\n            exit(pointer.trail);\n          }\n          invisibleCount -= node.isVisible() ? 0 : 1;\n        }\n      }, false);\n      boundaryTrail = endPointer.trail.copy();\n      var endWalkLength = endPointer.trail.length - (endPointer.isAfter ? 1 : 0);\n      for (i = endWalkLength - 1; i >= 0; i--) {\n        var endNode = endPointer.trail.nodes[i];\n        invisibleCount -= endNode.isVisible() ? 0 : 1;\n        if (invisibleCount === 0) {\n          exit(boundaryTrail);\n        }\n        boundaryTrail.removeDescendant();\n      }\n    },\n    dispose: function () {\n      Layer.prototype.dispose.call(this);\n      this.canvas.parentNode.removeChild(this.canvas);\n    },\n    applyTransformationMatrix: function (matrix) {\n      matrix.canvasAppendTransform(this.context);\n    },\n    reindex: function (zIndex) {\n      Layer.prototype.reindex.call(this, zIndex);\n      if (this.zIndex !== zIndex) {\n        this.canvas.style.zIndex = zIndex;\n        this.zIndex = zIndex;\n      }\n      return zIndex + 1;\n    },\n    pushClipShape: function (shape) {\n      this.context.save();\n      this.writeClipShape(shape);\n    },\n    popClipShape: function () {\n      this.context.restore();\n    },\n    writeClipShape: function (shape) {\n      this.context.beginPath();\n      shape.writeToContext(this.context);\n      this.context.clip();\n    },\n    clearGlobalBounds: function (bounds) {\n      if (!bounds.isEmpty()) {\n        this.context.save();\n        this.context.setTransform(this.backingScale, 0, 0, this.backingScale, 0, 0);\n        this.context.clearRect(bounds.getX(), bounds.getY(), bounds.getWidth(), bounds.getHeight());\n        this.context.restore();\n      }\n    },\n    getSVGString: function () {\n      return '<image xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:href=\"' + this.canvas.toDataURL() + '\" x=\"0\" y=\"0\" height=\"' + this.canvas.height + 'px\" width=\"' + this.canvas.width + 'px\"/>';\n    },\n    renderToCanvas: function (canvas, context, delayCounts) {\n      context.drawImage(this.canvas, 0, 0);\n    },\n    addInstance: function (instance) {\n      var trail = instance.trail;\n      sceneryLayerLog && sceneryLayerLog('CanvasLayer #' + this.id + ' addInstance: ' + trail.toString());\n      Layer.prototype.addInstance.call(this, instance);\n      this.canvasMarkLocalBounds(trail.lastNode().getBounds(), trail.slice(0, trail.length - 1));\n      if (trail.lastNode().boundsInaccurate) {\n        this.boundlessCount++;\n      }\n    },\n    removeInstance: function (instance) {\n      var trail = instance.trail;\n      sceneryLayerLog && sceneryLayerLog('CanvasLayer #' + this.id + ' removeInstance: ' + trail.toString());\n      Layer.prototype.removeInstance.call(this, instance);\n      this.canvasMarkLocalBounds(trail.lastNode().getBounds(), trail.slice(0, trail.length - 1));\n      if (trail.lastNode().boundsInaccurate) {\n        this.boundlessCount--;\n      }\n    },\n    canUseDirtyRegions: function () {\n      sceneryAssert && sceneryAssert(this.boundlessCount >= 0);\n      return this.boundlessCount === 0;\n    },\n    canvasMarkGlobalBounds: function (globalBounds) {\n      sceneryLayerLog && sceneryLayerLog('CanvasLayer #' + this.id + ' canvasMarkGlobalBounds: ' + globalBounds.toString());\n      sceneryAssert && sceneryAssert(globalBounds.isEmpty() || globalBounds.isFinite(), 'Infinite (non-empty) dirty bounds passed to canvasMarkGlobalBounds');\n      this.dirtyBounds = this.dirtyBounds.union(globalBounds.dilate(2).roundOut());\n    },\n    canvasMarkLocalBounds: function (localBounds, trail) {\n      sceneryLayerLog && sceneryLayerLog('CanvasLayer #' + this.id + ' canvasMarkLocalBounds: ' + localBounds.toString() + ' on ' + trail.toString());\n      if (!this.canUseDirtyRegions()) {\n        this.dirtyBounds = Bounds2.EVERYTHING;\n      } else {\n        this.canvasMarkGlobalBounds(trail.localToGlobalBounds(localBounds));\n      }\n    },\n    canvasMarkParentBounds: function (parentBounds, trail) {\n      sceneryLayerLog && sceneryLayerLog('CanvasLayer #' + this.id + ' canvasMarkParentBounds: ' + parentBounds.toString() + ' on ' + trail.toString());\n      if (!this.canUseDirtyRegions()) {\n        this.dirtyBounds = Bounds2.EVERYTHING;\n      } else {\n        this.canvasMarkGlobalBounds(trail.parentToGlobalBounds(parentBounds));\n      }\n    },\n    canvasMarkSelf: function (instance) {\n      this.canvasMarkLocalBounds(instance.getNode().getSelfBounds(), instance.trail);\n    },\n    canvasMarkSubtree: function (instance) {\n      this.canvasMarkParentBounds(instance.getNode().getBounds(), instance.trail);\n    },\n    getName: function () {\n      return 'canvas';\n    },\n    notifyVisibilityChange: function (instance) {\n      sceneryLayerLog && sceneryLayerLog('CanvasLayer #' + this.id + ' notifyVisibilityChange: ' + instance.trail.toString());\n      if (instance.trail.isVisible()) {\n        this.canvasMarkSubtree(instance);\n      }\n    },\n    notifyOpacityChange: function (instance) {\n      sceneryLayerLog && sceneryLayerLog('CanvasLayer #' + this.id + ' notifyOpacityChange: ' + instance.trail.toString());\n      this.canvasMarkSubtree(instance);\n    },\n    notifyBeforeSelfChange: function (instance) {\n      sceneryLayerLog && sceneryLayerLog('CanvasLayer #' + this.id + ' notifyBeforeSelfChange: ' + instance.trail.toString());\n      this.canvasMarkSelf(instance);\n    },\n    notifyBeforeSubtreeChange: function (instance) {\n      sceneryLayerLog && sceneryLayerLog('CanvasLayer #' + this.id + ' notifyBeforeSubtreeChange: ' + instance.trail.toString());\n      this.canvasMarkSubtree(instance);\n    },\n    notifyDirtySelfPaint: function (instance) {\n      sceneryLayerLog && sceneryLayerLog('CanvasLayer #' + this.id + ' notifyDirtySelfPaint: ' + instance.trail.toString());\n      this.canvasMarkSelf(instance);\n    },\n    notifyDirtySubtreePaint: function (instance) {\n      sceneryLayerLog && sceneryLayerLog('CanvasLayer #' + this.id + ' notifyDirtySubtreePaint: ' + instance.trail.toString());\n      this.canvasMarkSubtree(instance);\n    },\n    notifyTransformChange: function (instance) {\n    },\n    notifyBoundsAccuracyChange: function (instance) {\n      sceneryLayerLog && sceneryLayerLog('CanvasLayer #' + this.id + ' notifyBoundsAccuracyChange: ' + instance.trail.toString());\n      if (instance.node.boundsInaccurate) {\n        this.boundlessCount++;\n      } else {\n        this.boundlessCount--;\n      }\n    }\n  });\n  return CanvasLayer;\n});",
    "\ndefine('SCENERY/layers/DOMLayer',['require','PHET_CORE/inherit','DOT/Bounds2','SCENERY/scenery','SCENERY/layers/Layer','SCENERY/util/Trail'],function (require) {\n  'use strict';\n  var inherit = require('PHET_CORE/inherit');\n  var Bounds2 = require('DOT/Bounds2');\n  var scenery = require('SCENERY/scenery');\n  var Layer = require('SCENERY/layers/Layer');\n  require('SCENERY/util/Trail');\n  scenery.DOMLayer = function DOMLayer(args) {\n    sceneryLayerLog && sceneryLayerLog('DOMLayer constructor');\n    Layer.call(this, args);\n    var width = args.scene.sceneBounds.width;\n    var height = args.scene.sceneBounds.height;\n    this.div = document.createElement('div');\n    var div = this.div;\n    div.style.position = 'absolute';\n    div.style.left = '0';\n    div.style.top = '0';\n    div.style.width = '0';\n    div.style.height = '0';\n    div.style.clip = 'rect(0px,' + width + 'px,' + height + 'px,0px)';\n    this.$div = $(this.div);\n    this.$main.append(this.div);\n    this.scene = args.scene;\n    this.isDOMLayer = true;\n    this.idElementMap = {};\n    this.idTrailMap = {};\n    this.trails = [];\n  };\n  var DOMLayer = scenery.DOMLayer;\n  inherit(Layer, DOMLayer, {\n    addInstance: function (instance) {\n      Layer.prototype.addInstance.call(this, instance);\n      var trail = instance.trail;\n      this.reindexTrails();\n      var node = trail.lastNode();\n      var element = node.getDOMElement();\n      node.updateDOMElement(element);\n      this.updateVisibility(trail, element);\n      this.idElementMap[trail.getUniqueId()] = element;\n      this.idTrailMap[trail.getUniqueId()] = trail;\n      var insertionIndex;\n      for (insertionIndex = 0; insertionIndex < this.trails.length; insertionIndex++) {\n        var otherTrail = this.trails[insertionIndex];\n        otherTrail.reindex();\n        var comparison = otherTrail.compare(trail);\n        sceneryAssert && sceneryAssert(comparison !== 0, 'Trail has already been inserted into the DOMLayer');\n        if (comparison === 1) {\n          break;\n        }\n      }\n      if (insertionIndex === this.div.childNodes.length) {\n        this.div.appendChild(element);\n        this.trails.push(trail);\n      } else {\n        this.div.insertBefore(this.getElementFromTrail(this.trails[insertionIndex]));\n        this.trails.splice(insertionIndex, 0, trail);\n      }\n      node.updateCSSTransform(trail.getTransform(), element);\n    },\n    removeInstance: function (instance) {\n      Layer.prototype.removeInstance.call(this, instance);\n      var trail = instance.trail;\n      this.reindexTrails();\n      var element = this.getElementFromTrail(trail);\n      sceneryAssert && sceneryAssert(element, 'Trail does not exist in the DOMLayer');\n      delete this.idElementMap[trail.getUniqueId];\n      delete this.idTrailMap[trail.getUniqueId];\n      this.div.removeChild(element);\n      var removalIndex = this.getIndexOfTrail(trail);\n      this.trails.splice(removalIndex, 1);\n    },\n    getElementFromTrail: function (trail) {\n      return this.idElementMap[trail.getUniqueId()];\n    },\n    reindexTrails: function (zIndex) {\n      Layer.prototype.reindex.call(this, zIndex);\n      var i = this.trails.length;\n      while (i--) {\n        this.trails[i].reindex();\n      }\n    },\n    getIndexOfTrail: function (trail) {\n      var i;\n      for (i = 0; i < this.trails.length; i++) {\n        if (this.trails[i].compare(trail) === 0) {\n          return i;\n        }\n      }\n      throw new Error('DOMLayer.getIndexOfTrail unable to find trail: ' + trail.toString());\n    },\n    render: function (scene, args) {\n    },\n    dispose: function () {\n      Layer.prototype.dispose.call(this);\n      this.div.parentNode.removeChild(this.div);\n    },\n    updateVisibility: function (trail, element) {\n      if (trail.isVisible()) {\n        element.style.visibility = 'visible';\n      } else {\n        element.style.visibility = 'hidden';\n      }\n    },\n    applyTransformationMatrix: function (matrix) {\n    },\n    getContainer: function () {\n      return this.div;\n    },\n    reindex: function (zIndex) {\n      Layer.prototype.reindex.call(this, zIndex);\n      if (this.zIndex !== zIndex) {\n        this.div.style.zIndex = zIndex;\n        this.zIndex = zIndex;\n      }\n      return zIndex + 1;\n    },\n    pushClipShape: function (shape) {\n    },\n    popClipShape: function () {\n    },\n    getSVGString: function () {\n      var data = '<svg xmlns=\\'http://www.w3.org/2000/svg\\' width=\\'' + this.$main.width() + '\\' height=\\'' + this.$main.height() + '\\'>' + '<foreignObject width=\\'100%\\' height=\\'100%\\'>' + $(this.div).html() + '</foreignObject></svg>';\n    },\n    renderToCanvas: function (canvas, context, delayCounts) {\n    },\n    getName: function () {\n      return 'dom';\n    },\n    notifyVisibilityChange: function (instance) {\n      sceneryLayerLog && sceneryLayerLog('DOMLayer #' + this.id + ' notifyVisibilityChange: ' + instance.trail.toString());\n      var trail = instance.trail;\n      for (var trailId in this.idTrailMap) {\n        var subtrail = this.idTrailMap[trailId];\n        subtrail.reindex();\n        if (subtrail.isExtensionOf(trail, true)) {\n          this.updateVisibility(subtrail, this.idElementMap[trailId]);\n        }\n      }\n    },\n    notifyOpacityChange: function (instance) {\n      sceneryLayerLog && sceneryLayerLog('DOMLayer #' + this.id + ' notifyOpacityChange: ' + instance.trail.toString());\n    },\n    notifyBeforeSelfChange: function (instance) {\n    },\n    notifyBeforeSubtreeChange: function (instance) {\n    },\n    notifyDirtySelfPaint: function (instance) {\n      sceneryLayerLog && sceneryLayerLog('DOMLayer #' + this.id + ' notifyDirtySelfPaint: ' + instance.trail.toString());\n      var node = instance.getNode();\n      var trail = instance.trail;\n      var dirtyElement = this.idElementMap[trail.getUniqueId()];\n      if (dirtyElement) {\n        node.updateDOMElement(dirtyElement);\n        if (node.domUpdateTransformOnRepaint) {\n          node.updateCSSTransform(trail.getTransform(), dirtyElement);\n        }\n      }\n    },\n    notifyDirtySubtreePaint: function (instance) {\n      if (instance.layer === this) {\n        this.notifyDirtySelfPaint(instance);\n      }\n    },\n    notifyTransformChange: function (instance) {\n      sceneryLayerLog && sceneryLayerLog('DOMLayer #' + this.id + ' notifyTransformChange: ' + instance.trail.toString());\n      var layer = this;\n      var baseTrail = instance.trail;\n      scenery.Trail.eachPaintedTrailBetween(this.startPaintedTrail, this.endPaintedTrail, function (trail) {\n        if (trail.isExtensionOf(baseTrail, true)) {\n          var element = layer.idElementMap[trail.getUniqueId()];\n          var node = trail.lastNode();\n          node.updateCSSTransform(trail.getTransform(), element);\n        }\n      }, false, this.scene);\n    },\n    notifyBoundsAccuracyChange: function (instance) {\n    }\n  });\n  return DOMLayer;\n});",
    "\ndefine('SCENERY/layers/SVGLayer',['require','PHET_CORE/inherit','DOT/Bounds2','DOT/Transform3','DOT/Matrix3','SCENERY/scenery','SCENERY/layers/Layer','SCENERY/util/Trail','SCENERY/util/Util'],function (require) {\n  'use strict';\n  var inherit = require('PHET_CORE/inherit');\n  var Bounds2 = require('DOT/Bounds2');\n  var Transform3 = require('DOT/Transform3');\n  var Matrix3 = require('DOT/Matrix3');\n  var scenery = require('SCENERY/scenery');\n  var Layer = require('SCENERY/layers/Layer');\n  require('SCENERY/util/Trail');\n  require('SCENERY/util/Util');\n  var svgns = 'http://www.w3.org/2000/svg';\n  var xlinkns = 'http://www.w3.org/1999/xlink';\n  scenery.SVGLayer = function SVGLayer(args) {\n    sceneryLayerLog && sceneryLayerLog('SVGLayer constructor');\n    var $main = args.$main;\n    this.scene = args.scene;\n    this.svg = document.createElementNS(svgns, 'svg');\n    this.g = document.createElementNS(svgns, 'g');\n    this.defs = document.createElementNS(svgns, 'defs');\n    var width = args.scene.sceneBounds.width;\n    var height = args.scene.sceneBounds.height;\n    this.svg.appendChild(this.defs);\n    this.svg.appendChild(this.g);\n    this.$svg = $(this.svg);\n    this.svg.setAttribute('width', width);\n    this.svg.setAttribute('height', height);\n    this.svg.setAttribute('stroke-miterlimit', 10);\n    this.svg.style.position = 'absolute';\n    this.svg.style.left = '0';\n    this.svg.style.top = '0';\n    this.svg.style.clip = 'rect(0px,' + width + 'px,' + height + 'px,0px)';\n    this.svg.style['pointer-events'] = 'none';\n    $main.append(this.svg);\n    this.isSVGLayer = true;\n    this.idFragmentMap = {};\n    this.idGroupMap = {};\n    Layer.call(this, args);\n    this.baseTransformDirty = true;\n    this.baseTransformChange = true;\n  };\n  var SVGLayer = scenery.SVGLayer;\n  var scratchBounds1 = Bounds2.NOTHING.copy();\n  inherit(Layer, SVGLayer, {\n    addInstance: function (instance) {\n      var trail = instance.trail;\n      sceneryLayerLog && sceneryLayerLog('SVGLayer #' + this.id + ' addInstance: ' + trail.toString());\n      sceneryAssert && sceneryAssert(!(trail.getUniqueId() in this.idFragmentMap), 'Already contained that trail!');\n      sceneryAssert && sceneryAssert(trail.isPainted(), 'Don\\'t add nodes without isPainted() to SVGLayer');\n      Layer.prototype.addInstance.call(this, instance);\n      var subtrail = this.baseTrail.copy();\n      var lastId = null;\n      while (subtrail.length <= trail.length) {\n        var id = subtrail.getUniqueId();\n        var group = this.idGroupMap[id];\n        if (!group) {\n          if (lastId) {\n            group = document.createElementNS(svgns, 'g');\n            this.applyTransform(subtrail.lastNode().getTransform(), group);\n            this.insertGroupIntoParent(group, this.idGroupMap[lastId], subtrail);\n          } else {\n            sceneryAssert && sceneryAssert(subtrail.lastNode() === this.baseNode);\n            group = this.g;\n            this.initializeBase();\n            this.refreshBaseTransform();\n          }\n          this.updateNodeGroup(subtrail.lastNode(), group);\n          group.referenceCount = 0;\n          group.trail = subtrail.copy();\n          this.idGroupMap[id] = group;\n        }\n        group.referenceCount++;\n        if (subtrail.length === trail.length) {\n          break;\n        }\n        subtrail.addDescendant(trail.nodes[subtrail.length]);\n        lastId = id;\n      }\n      var node = trail.lastNode();\n      var trailId = trail.getUniqueId();\n      var nodeGroup = this.idGroupMap[trailId];\n      var svgFragment = node.createSVGFragment(this.svg, this.defs, nodeGroup);\n      this.updateNode(node, svgFragment);\n      this.updateNodeGroup(node, nodeGroup);\n      this.idFragmentMap[trailId] = svgFragment;\n      nodeGroup.appendChild(svgFragment);\n    },\n    removeInstance: function (instance) {\n      var trail = instance.trail;\n      sceneryLayerLog && sceneryLayerLog('SVGLayer #' + this.id + ' removeInstance: ' + trail.toString());\n      sceneryAssert && sceneryAssert(trail.getUniqueId() in this.idFragmentMap, 'Did not contain that trail!');\n      Layer.prototype.removeInstance.call(this, instance);\n      var trailId = trail.getUniqueId();\n      var node = trail.lastNode();\n      var fragment = this.idFragmentMap[trailId];\n      this.idGroupMap[trailId].removeChild(fragment);\n      delete this.idFragmentMap[trailId];\n      if (node.removeSVGDefs) {\n        node.removeSVGDefs(this.svg, this.defs);\n      }\n      var subtrail = trail.copy();\n      while (subtrail.length > this.baseTrail.length) {\n        var id = subtrail.getUniqueId();\n        var group = this.idGroupMap[id];\n        group.referenceCount--;\n        if (group.referenceCount === 0) {\n          group.parentNode.removeChild(group);\n          delete group.trail;\n          delete this.idGroupMap[id];\n        }\n        subtrail.removeDescendant();\n      }\n      this.g.referenceCount--;\n    },\n    insertGroupIntoParent: function (group, parentGroup, subtrail) {\n      sceneryLayerLog && sceneryLayerLog('SVGLayer #' + this.id + ' insertGroupIntoParent subtrail:' + subtrail.toString());\n      if (!parentGroup.childNodes.length) {\n        parentGroup.appendChild(group);\n      } else {\n        var afterNode = null;\n        var indexIndex = subtrail.length - 2;\n        var ourIndex = subtrail.indices[indexIndex];\n        var i;\n        for (i = 0; i < parentGroup.childNodes.length; i++) {\n          var child = parentGroup.childNodes[i];\n          if (child.trail) {\n            child.trail.reindex();\n            var otherIndex = child.trail.indices[indexIndex];\n            if (otherIndex > ourIndex) {\n              break;\n            }\n          }\n        }\n        if (i === parentGroup.childNodes.length) {\n          parentGroup.appendChild(group);\n        } else {\n          parentGroup.insertBefore(group, parentGroup.childNodes[i]);\n        }\n      }\n    },\n    updateNode: function (node, fragment) {\n      sceneryLayerLog && sceneryLayerLog('SVGLayer #' + this.id + ' updateNode: ' + node.constructor.name + ' #' + node.id);\n      if (node.updateSVGFragment) {\n        node.updateSVGFragment(fragment);\n      }\n      if (node.updateSVGDefs) {\n        node.updateSVGDefs(this.svg, this.defs);\n      }\n    },\n    updateNodeGroup: function (node, group) {\n      sceneryLayerLog && sceneryLayerLog('SVGLayer #' + this.id + ' updateNodeGroup: ' + node.constructor.name + ' #' + node.id);\n      this.updateGroupVisibility(node, group);\n      this.updateGroupOpacity(node, group);\n    },\n    updateGroupVisibility: function (node, group) {\n      if (node === this.baseNode ? this.baseTrail.isVisible() : node.isVisible()) {\n        group.style.display = 'inherit';\n      } else {\n        group.style.display = 'none';\n      }\n    },\n    updateGroupOpacity: function (node, group) {\n      var opacity;\n      if (node === this.baseNode) {\n        opacity = this.baseTrail.getOpacity();\n      } else {\n        opacity = node.getOpacity();\n      }\n      group.setAttribute('opacity', opacity);\n    },\n    getFragmentFromInstance: function (instance) {\n      return this.idFragmentMap[instance.trail.getUniqueId()];\n    },\n    getGroupFromInstance: function (instance) {\n      return this.idGroupMap[instance.trail.getUniqueId()];\n    },\n    applyTransform: function (transform, group) {\n      if (transform.isIdentity()) {\n        if (group.hasAttribute('transform')) {\n          group.removeAttribute('transform');\n        }\n      } else {\n        group.setAttribute('transform', transform.getMatrix().getSVGTransform());\n      }\n    },\n    render: function (scene, args) {\n      this.refreshBaseTransform();\n    },\n    refreshBaseTransform: function () {\n      if (this.baseTransformDirty) {\n        var includesBaseTransformChange = this.baseTransformChange;\n        this.updateBaseTransform(includesBaseTransformChange);\n        this.baseTransformDirty = false;\n        this.baseTransformChange = false;\n      }\n    },\n    dispose: function () {\n      Layer.prototype.dispose.call(this);\n      this.svg.parentNode.removeChild(this.svg);\n    },\n    markBaseTransformDirty: function (changed) {\n      sceneryLayerLog && sceneryLayerLog('SVGLayer #' + this.id + ' markBaseTransformDirty');\n      var baseTransformChange = this.baseTransformChange || !!changed;\n      this.baseTransformDirty = true;\n      this.baseTransformChange = baseTransformChange;\n    },\n    initializeBase: function () {\n      if (this.cssTransform) {\n        this.baseNodeInternalBoundsChange();\n      } else {\n        this.markBaseTransformDirty(true);\n      }\n    },\n    baseNodeInternalBoundsChange: function () {\n      sceneryLayerLog && sceneryLayerLog('SVGLayer #' + this.id + ' baseNodeInternalBoundsChange');\n      if (this.cssTransform) {\n        var internalBounds = scratchBounds1;\n        internalBounds.setBounds(this.baseNode.getBounds());\n        this.baseNode.transformBoundsFromParentToLocal(internalBounds);\n        var padding = scenery.Layer.cssTransformPadding;\n        if (!internalBounds.isEmpty()) {\n          this.baseNodeTransform.set(Matrix3.translation(Math.ceil(-internalBounds.minX + padding), Math.ceil(-internalBounds.minY + padding)));\n          var baseNodeInteralBounds = internalBounds.transform(this.baseNodeTransform.getMatrix());\n          sceneryAssert && sceneryAssert(baseNodeInteralBounds.minX >= 0 && baseNodeInteralBounds.minY >= 0);\n          this.updateContainerDimensions(Math.ceil(baseNodeInteralBounds.maxX + padding), Math.ceil(baseNodeInteralBounds.maxY + padding));\n        }\n        this.markBaseTransformDirty(true);\n      } else if (this.usesPartialCSSTransforms) {\n        this.markBaseTransformDirty(true);\n      }\n    },\n    updateContainerDimensions: function (width, height) {\n      this.svg.setAttribute('width', width);\n      this.svg.setAttribute('height', height);\n    },\n    updateBaseTransform: function (includesBaseTransformChange) {\n      sceneryLayerLog && sceneryLayerLog('SVGLayer #' + this.id + ' updateBaseTransform');\n      var transform = this.baseTrail.getTransform();\n      if (this.cssTransform) {\n        scenery.Util.applyCSSTransform(transform.getMatrix().timesMatrix(this.baseNodeTransform.getInverse()), this.svg);\n        if (includesBaseTransformChange) {\n          this.applyTransform(this.baseNodeTransform, this.g);\n        }\n      } else if (this.usesPartialCSSTransforms) {\n        var cssTransform = new Transform3();\n        var matrix = transform.getMatrix();\n        if (this.cssTranslation) {\n          cssTransform.append(Matrix3.translation(matrix.m02(), matrix.m12()));\n        }\n        if (this.cssRotation) {\n          cssTransform.append(Matrix3.rotation2(matrix.getRotation()));\n        }\n        if (this.cssScale) {\n          var scaleVector = matrix.getScaleVector();\n          cssTransform.append(Matrix3.scaling(scaleVector.x, scaleVector.y));\n        }\n        transform.prepend(cssTransform.getInverse());\n        var padding = scenery.Layer.cssTransformPadding;\n        var internalBounds = this.baseNode.parentToLocalBounds(this.baseNode.getBounds());\n        var mappedBounds = transform.transformBounds2(internalBounds);\n        var translation = Matrix3.translation(Math.ceil(-mappedBounds.minX + padding), Math.ceil(-mappedBounds.minY + padding));\n        var inverseTranslation = translation.inverted();\n        this.updateContainerDimensions(Math.ceil(mappedBounds.getWidth() + 2 * padding), Math.ceil(mappedBounds.getHeight() + 2 * padding));\n        cssTransform.append(inverseTranslation);\n        transform.prepend(translation);\n        scenery.Util.applyCSSTransform(cssTransform.getMatrix(), this.svg);\n        this.applyTransform(transform, this.g);\n      } else {\n        this.applyTransform(transform, this.g);\n      }\n    },\n    applyTransformationMatrix: function (matrix) {\n    },\n    getContainer: function () {\n      return this.svg;\n    },\n    reindex: function (zIndex) {\n      Layer.prototype.reindex.call(this, zIndex);\n      if (this.zIndex !== zIndex) {\n        this.svg.style.zIndex = zIndex;\n        this.zIndex = zIndex;\n      }\n      return zIndex + 1;\n    },\n    pushClipShape: function (shape) {\n    },\n    popClipShape: function () {\n    },\n    getSVGString: function () {\n      return $('<div>').append(this.$svg.clone()).html();\n    },\n    renderToCanvas: function (canvas, context, delayCounts) {\n      this.applyTransform(this.baseTrail.getTransform(), this.g);\n      if (window.canvg) {\n        delayCounts.increment();\n        canvg(canvas, this.getSVGString(), {\n          ignoreMouse: true,\n          ignoreAnimation: true,\n          ignoreDimensions: true,\n          ignoreClear: true,\n          renderCallback: function () {\n            delayCounts.decrement();\n          }\n        });\n      } else {\n        var DOMURL = window.URL || window.webkitURL || window;\n        var img = new Image();\n        var raw = this.getSVGString();\n        console.log(raw);\n        var svg = new Blob([raw], { type: 'image/svg+xml;charset=utf-8' });\n        var url = DOMURL.createObjectURL(svg);\n        delayCounts.increment();\n        img.onload = function () {\n          context.drawImage(img, 0, 0);\n          DOMURL.revokeObjectURL(url);\n          delayCounts.decrement();\n        };\n        img.src = url;\n        throw new Error('this implementation hits Chrome bugs, won\\'t work on IE9/10, etc. deprecated');\n      }\n      this.updateBaseTransform();\n    },\n    getName: function () {\n      return 'svg';\n    },\n    notifyVisibilityChange: function (instance) {\n      sceneryLayerLog && sceneryLayerLog('SVGLayer #' + this.id + ' notifyVisibilityChange: ' + instance.trail.toString());\n      var group = this.getGroupFromInstance(instance);\n      if (group) {\n        this.updateGroupVisibility(instance.getNode(), group);\n      } else if (this.baseNode !== this.scene) {\n        this.updateGroupVisibility(this.baseNode, this.getGroupFromInstance(this.baseTrail.getInstance()));\n      }\n    },\n    notifyOpacityChange: function (instance) {\n      sceneryLayerLog && sceneryLayerLog('SVGLayer #' + this.id + ' notifyOpacityChange: ' + instance.trail.toString());\n      var group = this.getGroupFromInstance(instance);\n      if (group) {\n        this.updateGroupOpacity(instance.getNode(), group);\n      } else if (this.baseNode !== this.scene) {\n        this.updateGroupOpacity(this.baseNode, this.getGroupFromInstance(this.baseTrail.getInstance()));\n      }\n    },\n    notifyBeforeSelfChange: function (instance) {\n    },\n    notifyBeforeSubtreeChange: function (instance) {\n    },\n    notifyDirtySelfPaint: function (instance) {\n      sceneryLayerLog && sceneryLayerLog('SVGLayer #' + this.id + ' notifyDirtySelfPaint: ' + instance.trail.toString());\n      var fragment = this.getFragmentFromInstance(instance);\n      if (fragment) {\n        var node = instance.getNode();\n        if (node.updateSVGFragment) {\n          node.updateSVGFragment(fragment);\n        }\n        if (node.updateSVGDefs) {\n          node.updateSVGDefs(this.svg, this.defs);\n        }\n      }\n    },\n    notifyDirtySubtreePaint: function (instance) {\n      if (instance.layer === this) {\n        this.notifyDirtySelfPaint(instance);\n      }\n    },\n    notifyTransformChange: function (instance) {\n      sceneryLayerLog && sceneryLayerLog('SVGLayer #' + this.id + ' notifyTransformChange: ' + instance.trail.toString());\n      var node = instance.node;\n      var trail = instance.trail;\n      if (trail.lastNode() === this.baseNode) {\n        this.markBaseTransformDirty();\n      } else if (_.contains(trail.nodes, this.baseNode)) {\n        var group = this.idGroupMap[trail.getUniqueId()];\n        this.applyTransform(node.getTransform(), group);\n      } else {\n        this.markBaseTransformDirty();\n      }\n    },\n    notifyBoundsAccuracyChange: function (instance) {\n    }\n  });\n  return SVGLayer;\n});",
    "\ndefine('SCENERY/layers/Renderer',['require','SCENERY/scenery','SCENERY/layers/LayerType','SCENERY/layers/CanvasLayer','SCENERY/layers/DOMLayer','SCENERY/layers/SVGLayer'],function (require) {\n  'use strict';\n  var scenery = require('SCENERY/scenery');\n  require('SCENERY/layers/LayerType');\n  require('SCENERY/layers/CanvasLayer');\n  require('SCENERY/layers/DOMLayer');\n  require('SCENERY/layers/SVGLayer');\n  var defaults = {};\n  scenery.Renderer = function Renderer(layerConstructor, name, defaultOptions) {\n    this.layerConstructor = layerConstructor;\n    this.name = name;\n    this.defaultOptions = defaultOptions;\n    this.defaultLayerType = this.createLayerType({});\n  };\n  var Renderer = scenery.Renderer;\n  Renderer.prototype = {\n    constructor: Renderer,\n    createLayerType: function (rendererOptions) {\n      return new scenery.LayerType(this.layerConstructor, this.name, this, _.extend({}, this.defaultOptions, rendererOptions));\n    }\n  };\n  Renderer.Canvas = new Renderer(scenery.CanvasLayer, 'canvas', {});\n  Renderer.DOM = new Renderer(scenery.DOMLayer, 'dom', {});\n  Renderer.SVG = new Renderer(scenery.SVGLayer, 'svg', {});\n  scenery.CanvasDefaultLayerType = Renderer.Canvas.defaultLayerType;\n  scenery.DOMDefaultLayerType = Renderer.DOM.defaultLayerType;\n  scenery.SVGDefaultLayerType = Renderer.SVG.defaultLayerType;\n  Renderer.canvas = Renderer.Canvas;\n  Renderer.dom = Renderer.DOM;\n  Renderer.svg = Renderer.SVG;\n  Renderer.webgl = Renderer.WebGL;\n  return Renderer;\n});",
    "\ndefine('SCENERY/nodes/Fillable',['require','SCENERY/scenery'],function (require) {\n  'use strict';\n  var scenery = require('SCENERY/scenery');\n  scenery.Fillable = function Fillable(type) {\n    var proto = type.prototype;\n    proto.initializeFillable = function () {\n      this._fill = null;\n      var that = this;\n      this._fillListener = function () {\n        that.invalidatePaint();\n        that.invalidateFill();\n      };\n    };\n    proto.hasFill = function () {\n      return this._fill !== null;\n    };\n    proto.getFill = function () {\n      return this._fill;\n    };\n    proto.setFill = function (fill) {\n      if (this.getFill() !== fill) {\n        var hasInstances = this._instances.length > 0;\n        if (hasInstances && this._fill && this._fill.removeChangeListener) {\n          this._fill.removeChangeListener(this._fillListener);\n        }\n        this._fill = fill;\n        if (hasInstances && this._fill && this._fill.addChangeListener) {\n          this._fill.addChangeListener(this._fillListener);\n        }\n        this.invalidatePaint();\n        this.invalidateFill();\n      }\n      return this;\n    };\n    var superFirstInstanceAdded = proto.firstInstanceAdded;\n    proto.firstInstanceAdded = function () {\n      if (this._fill && this._fill.addChangeListener) {\n        this._fill.addChangeListener(this._fillListener);\n      }\n      if (superFirstInstanceAdded) {\n        superFirstInstanceAdded.call(this);\n      }\n    };\n    var superLastInstanceRemoved = proto.lastInstanceRemoved;\n    proto.lastInstanceRemoved = function () {\n      if (this._fill && this._fill.removeChangeListener) {\n        this._fill.removeChangeListener(this._fillListener);\n      }\n      if (superLastInstanceRemoved) {\n        superLastInstanceRemoved.call(this);\n      }\n    };\n    proto.beforeCanvasFill = function (wrapper) {\n      wrapper.setFillStyle(this._fill);\n      if (this._fill.transformMatrix) {\n        wrapper.context.save();\n        this._fill.transformMatrix.canvasAppendTransform(wrapper.context);\n      }\n    };\n    proto.afterCanvasFill = function (wrapper) {\n      if (this._fill.transformMatrix) {\n        wrapper.context.restore();\n      }\n    };\n    proto.getSVGFillStyle = function () {\n      var style = 'fill: ';\n      if (!this._fill) {\n        style += 'none;';\n      } else if (this._fill.toCSS) {\n        style += this._fill.toCSS() + ';';\n      } else if (this._fill.getSVGDefinition) {\n        style += 'url(#fill' + this.getId() + ');';\n      } else {\n        style += this._fill + ';';\n      }\n      return style;\n    };\n    proto.isFillDOMCompatible = function () {\n      return !this._fill || !this._fill.getSVGDefinition;\n    };\n    proto.getCSSFill = function () {\n      sceneryAssert && sceneryAssert(this.isFillDOMCompatible());\n      return this._fill ? this._fill.toCSS ? this._fill.toCSS() : this._fill : 'transparent';\n    };\n    proto.addSVGFillDef = function (svg, defs) {\n      var fill = this.getFill();\n      var fillId = 'fill' + this.getId();\n      if (fill && fill.getSVGDefinition) {\n        defs.appendChild(fill.getSVGDefinition(fillId));\n      }\n    };\n    proto.removeSVGFillDef = function (svg, defs) {\n      var fillId = 'fill' + this.getId();\n      var oldFillDef = svg.getElementById(fillId);\n      if (oldFillDef) {\n        defs.removeChild(oldFillDef);\n      }\n    };\n    proto.appendFillablePropString = function (spaces, result) {\n      if (this._fill) {\n        if (result) {\n          result += ',\\n';\n        }\n        if (typeof this._fill === 'string') {\n          result += spaces + 'fill: \\'' + this._fill + '\\'';\n        } else {\n          result += spaces + 'fill: ' + this._fill.toString();\n        }\n      }\n      return result;\n    };\n    proto._mutatorKeys = ['fill'].concat(proto._mutatorKeys);\n    Object.defineProperty(proto, 'fill', {\n      set: proto.setFill,\n      get: proto.getFill\n    });\n    if (!proto.invalidateFill) {\n      proto.invalidateFill = function () {\n      };\n    }\n  };\n  var Fillable = scenery.Fillable;\n  return Fillable;\n});",
    "\ndefine('SCENERY/nodes/Strokable',['require','SCENERY/scenery','KITE/util/LineStyles'],function (require) {\n  'use strict';\n  var scenery = require('SCENERY/scenery');\n  var LineStyles = require('KITE/util/LineStyles');\n  scenery.Strokable = function Strokable(type) {\n    var proto = type.prototype;\n    proto.initializeStrokable = function () {\n      this._stroke = null;\n      this._lineDrawingStyles = new LineStyles();\n      var that = this;\n      this._strokeListener = function () {\n        that.invalidatePaint();\n        that.invalidateStroke();\n      };\n    };\n    proto.hasStroke = function () {\n      return this._stroke !== null;\n    };\n    proto.getLineWidth = function () {\n      return this._lineDrawingStyles.lineWidth;\n    };\n    proto.setLineWidth = function (lineWidth) {\n      if (this.getLineWidth() !== lineWidth) {\n        this.markOldSelfPaint();\n        this._lineDrawingStyles.lineWidth = lineWidth;\n        this.invalidateStroke();\n      }\n      return this;\n    };\n    proto.getLineCap = function () {\n      return this._lineDrawingStyles.lineCap;\n    };\n    proto.setLineCap = function (lineCap) {\n      if (this._lineDrawingStyles.lineCap !== lineCap) {\n        this.markOldSelfPaint();\n        this._lineDrawingStyles.lineCap = lineCap;\n        this.invalidateStroke();\n      }\n      return this;\n    };\n    proto.getLineJoin = function () {\n      return this._lineDrawingStyles.lineJoin;\n    };\n    proto.setLineJoin = function (lineJoin) {\n      if (this._lineDrawingStyles.lineJoin !== lineJoin) {\n        this.markOldSelfPaint();\n        this._lineDrawingStyles.lineJoin = lineJoin;\n        this.invalidateStroke();\n      }\n      return this;\n    };\n    proto.getLineDash = function () {\n      return this._lineDrawingStyles.lineDash;\n    };\n    proto.setLineDash = function (lineDash) {\n      if (this._lineDrawingStyles.lineDash !== lineDash) {\n        this.markOldSelfPaint();\n        this._lineDrawingStyles.lineDash = lineDash || [];\n        this.invalidateStroke();\n      }\n      return this;\n    };\n    proto.getLineDashOffset = function () {\n      return this._lineDrawingStyles.lineDashOffset;\n    };\n    proto.setLineDashOffset = function (lineDashOffset) {\n      if (this._lineDrawingStyles.lineDashOffset !== lineDashOffset) {\n        this.markOldSelfPaint();\n        this._lineDrawingStyles.lineDashOffset = lineDashOffset;\n        this.invalidateStroke();\n      }\n      return this;\n    };\n    proto.setLineStyles = function (lineStyles) {\n      this.markOldSelfPaint();\n      this._lineDrawingStyles = lineStyles;\n      this.invalidateStroke();\n      return this;\n    };\n    proto.getLineStyles = function () {\n      return this._lineDrawingStyles;\n    };\n    proto.getStroke = function () {\n      return this._stroke;\n    };\n    proto.setStroke = function (stroke) {\n      if (this.getStroke() !== stroke) {\n        this.markOldSelfPaint();\n        var hasInstances = this._instances.length > 0;\n        if (hasInstances && this._stroke && this._stroke.removeChangeListener) {\n          this._stroke.removeChangeListener(this._strokeListener);\n        }\n        this._stroke = stroke;\n        if (hasInstances && this._stroke && this._stroke.addChangeListener) {\n          this._stroke.addChangeListener(this._strokeListener);\n        }\n        this.invalidateStroke();\n      }\n      return this;\n    };\n    var superFirstInstanceAdded = proto.firstInstanceAdded;\n    proto.firstInstanceAdded = function () {\n      if (this._stroke && this._stroke.addChangeListener) {\n        this._stroke.addChangeListener(this._strokeListener);\n      }\n      if (superFirstInstanceAdded) {\n        superFirstInstanceAdded.call(this);\n      }\n    };\n    var superLastInstanceRemoved = proto.lastInstanceRemoved;\n    proto.lastInstanceRemoved = function () {\n      if (this._stroke && this._stroke.removeChangeListener) {\n        this._stroke.removeChangeListener(this._strokeListener);\n      }\n      if (superLastInstanceRemoved) {\n        superLastInstanceRemoved.call(this);\n      }\n    };\n    proto.beforeCanvasStroke = function (wrapper) {\n      wrapper.setStrokeStyle(this._stroke);\n      wrapper.setLineWidth(this.getLineWidth());\n      wrapper.setLineCap(this.getLineCap());\n      wrapper.setLineJoin(this.getLineJoin());\n      wrapper.setLineDash(this.getLineDash());\n      wrapper.setLineDashOffset(this.getLineDashOffset());\n      if (this._stroke.transformMatrix) {\n        wrapper.context.save();\n        this._stroke.transformMatrix.canvasAppendTransform(wrapper.context);\n      }\n    };\n    proto.afterCanvasStroke = function (wrapper) {\n      if (this._stroke.transformMatrix) {\n        wrapper.context.restore();\n      }\n    };\n    proto.getSVGStrokeStyle = function () {\n      if (!this._stroke) {\n        return 'stroke: none;';\n      }\n      var style = 'stroke: ';\n      if (this._stroke.toCSS) {\n        style += this._stroke.toCSS() + ';';\n      } else if (this._stroke.getSVGDefinition) {\n        style += 'url(#stroke' + this.getId() + ');';\n      } else {\n        style += this._stroke + ';';\n      }\n      style += 'stroke-width: ' + this.getLineWidth() + ';';\n      style += 'stroke-linecap: ' + this.getLineCap() + ';';\n      style += 'stroke-linejoin: ' + this.getLineJoin() + ';';\n      if (this.getLineDash().length) {\n        style += 'stroke-dasharray: ' + this.getLineDash().join(',') + ';';\n        style += 'stroke-dashoffset: ' + this.getLineDashOffset() + ';';\n      }\n      return style;\n    };\n    proto.addSVGStrokeDef = function (svg, defs) {\n      var stroke = this.getStroke();\n      var strokeId = 'stroke' + this.getId();\n      if (stroke && stroke.getSVGDefinition) {\n        defs.appendChild(stroke.getSVGDefinition(strokeId));\n      }\n    };\n    proto.removeSVGStrokeDef = function (svg, defs) {\n      var strokeId = 'stroke' + this.getId();\n      var oldStrokeDef = svg.getElementById(strokeId);\n      if (oldStrokeDef) {\n        defs.removeChild(oldStrokeDef);\n      }\n    };\n    proto.appendStrokablePropString = function (spaces, result) {\n      var self = this;\n      function addProp(key, value, nowrap) {\n        if (result) {\n          result += ',\\n';\n        }\n        if (!nowrap && typeof value === 'string') {\n          result += spaces + key + ': \\'' + value + '\\'';\n        } else {\n          result += spaces + key + ': ' + value;\n        }\n      }\n      if (this._stroke) {\n        var defaultStyles = new LineStyles();\n        if (typeof this._stroke === 'string') {\n          addProp('stroke', this._stroke);\n        } else {\n          addProp('stroke', this._stroke.toString(), true);\n        }\n        _.each([\n          'lineWidth',\n          'lineCap',\n          'lineJoin',\n          'lineDashOffset'\n        ], function (prop) {\n          if (self[prop] !== defaultStyles[prop]) {\n            addProp(prop, self[prop]);\n          }\n        });\n        if (this.lineDash.length) {\n          addProp('lineDash', JSON.stringify(this.lineDash), true);\n        }\n      }\n      return result;\n    };\n    proto._mutatorKeys = [\n      'stroke',\n      'lineWidth',\n      'lineCap',\n      'lineJoin',\n      'lineDash',\n      'lineDashOffset'\n    ].concat(proto._mutatorKeys);\n    Object.defineProperty(proto, 'stroke', {\n      set: proto.setStroke,\n      get: proto.getStroke\n    });\n    Object.defineProperty(proto, 'lineWidth', {\n      set: proto.setLineWidth,\n      get: proto.getLineWidth\n    });\n    Object.defineProperty(proto, 'lineCap', {\n      set: proto.setLineCap,\n      get: proto.getLineCap\n    });\n    Object.defineProperty(proto, 'lineJoin', {\n      set: proto.setLineJoin,\n      get: proto.getLineJoin\n    });\n    Object.defineProperty(proto, 'lineDash', {\n      set: proto.setLineDash,\n      get: proto.getLineDash\n    });\n    Object.defineProperty(proto, 'lineDashOffset', {\n      set: proto.setLineDashOffset,\n      get: proto.getLineDashOffset\n    });\n    if (!proto.invalidateStroke) {\n      proto.invalidateStroke = function () {\n      };\n    }\n  };\n  var Strokable = scenery.Strokable;\n  return Strokable;\n});",
    "\ndefine('SCENERY/nodes/Path',['require','PHET_CORE/inherit','KITE/Shape','SCENERY/scenery','SCENERY/nodes/Node','SCENERY/layers/Renderer','SCENERY/nodes/Fillable','SCENERY/nodes/Strokable','SCENERY/util/Util'],function (require) {\n  'use strict';\n  var inherit = require('PHET_CORE/inherit');\n  var Shape = require('KITE/Shape');\n  var scenery = require('SCENERY/scenery');\n  var Node = require('SCENERY/nodes/Node');\n  var Renderer = require('SCENERY/layers/Renderer');\n  var Fillable = require('SCENERY/nodes/Fillable');\n  var Strokable = require('SCENERY/nodes/Strokable');\n  var objectCreate = require('SCENERY/util/Util').objectCreate;\n  scenery.Path = function Path(shape, options) {\n    this._shape = null;\n    options = options || {};\n    this.initializeFillable();\n    this.initializeStrokable();\n    Node.call(this);\n    this.setShape(shape);\n    this.mutate(options);\n  };\n  var Path = scenery.Path;\n  inherit(Node, Path, {\n    setShape: function (shape) {\n      if (this._shape !== shape) {\n        if (typeof shape === 'string') {\n          shape = new Shape(shape);\n        }\n        this._shape = shape;\n        this.invalidateShape();\n      }\n      return this;\n    },\n    getShape: function () {\n      return this._shape;\n    },\n    invalidateShape: function () {\n      this.markOldSelfPaint();\n      if (this.hasShape()) {\n        this.invalidateSelf(this.computeShapeBounds());\n        this.invalidatePaint();\n      }\n    },\n    computeShapeBounds: function () {\n      return this._stroke ? this._shape.computeBounds(this._lineDrawingStyles) : this._shape.bounds;\n    },\n    invalidateStroke: function () {\n      this.invalidateShape();\n    },\n    hasShape: function () {\n      return this._shape;\n    },\n    paintCanvas: function (wrapper) {\n      var context = wrapper.context;\n      if (this.hasShape()) {\n        context.beginPath();\n        this._shape.writeToContext(context);\n        if (this._fill) {\n          this.beforeCanvasFill(wrapper);\n          context.fill();\n          this.afterCanvasFill(wrapper);\n        }\n        if (this._stroke) {\n          this.beforeCanvasStroke(wrapper);\n          context.stroke();\n          this.afterCanvasStroke(wrapper);\n        }\n      }\n    },\n    paintWebGL: function (state) {\n      throw new Error('Path.prototype.paintWebGL unimplemented');\n    },\n    createSVGFragment: function (svg, defs, group) {\n      return document.createElementNS('http://www.w3.org/2000/svg', 'path');\n    },\n    updateSVGFragment: function (path) {\n      var svgPath = this.hasShape() ? this._shape.getSVGPath() : '';\n      if (!svgPath) {\n        svgPath = 'M0 0';\n      }\n      if (svgPath) {\n        path.setAttribute('d', svgPath);\n      } else if (path.hasAttribute('d')) {\n        path.removeAttribute('d');\n      }\n      path.setAttribute('style', this.getSVGFillStyle() + this.getSVGStrokeStyle());\n    },\n    updateSVGDefs: function (svg, defs) {\n      this.removeSVGDefs(svg, defs);\n      this.addSVGFillDef(svg, defs);\n      this.addSVGStrokeDef(svg, defs);\n    },\n    removeSVGDefs: function (svg, defs) {\n      this.removeSVGFillDef(svg, defs);\n      this.removeSVGStrokeDef(svg, defs);\n    },\n    isPainted: function () {\n      return true;\n    },\n    containsPointSelf: function (point) {\n      if (!this.hasShape()) {\n        return false;\n      }\n      var result = this._shape.containsPoint(point);\n      if (!result && this._includeStrokeInHitRegion && this.hasStroke()) {\n        result = this._shape.getStrokedShape(this._lineDrawingStyles).containsPoint(point);\n      }\n      return result;\n    },\n    intersectsBoundsSelf: function (bounds) {\n      return this.hasShape() ? this._shape.intersectsBounds(bounds) : false;\n    },\n    set shape(value) {\n      this.setShape(value);\n    },\n    get shape() {\n      return this.getShape();\n    },\n    getBasicConstructor: function (propLines) {\n      return 'new scenery.Path( ' + this._shape.toString() + ', {' + propLines + '} )';\n    },\n    getPropString: function (spaces, includeChildren) {\n      var result = Node.prototype.getPropString.call(this, spaces, includeChildren);\n      result = this.appendFillablePropString(spaces, result);\n      result = this.appendStrokablePropString(spaces, result);\n      return result;\n    }\n  });\n  Path.prototype._mutatorKeys = ['shape'].concat(Node.prototype._mutatorKeys);\n  Path.prototype._supportedRenderers = [\n    Renderer.Canvas,\n    Renderer.SVG\n  ];\n  Fillable(Path);\n  Strokable(Path);\n  return Path;\n});",
    "\ndefine('SUN/ExpandCollapseButton',['require','SCENERY/input/ButtonListener','PHET_CORE/inherit','SCENERY/nodes/Node','SCENERY/nodes/Path','KITE/Shape'],function (require) {\n  'use strict';\n  var ButtonListener = require('SCENERY/input/ButtonListener');\n  var inherit = require('PHET_CORE/inherit');\n  var Node = require('SCENERY/nodes/Node');\n  var Path = require('SCENERY/nodes/Path');\n  var Shape = require('KITE/Shape');\n  function ExpandCollapseButton(sideLength, expandedProperty, options) {\n    options = _.extend({}, options);\n    var thisButton = this;\n    Node.call(thisButton);\n    var cornerRadius = 0.1 * sideLength;\n    var buttonShape = Shape.roundRectangle(0, 0, sideLength, sideLength, cornerRadius, cornerRadius);\n    var symbolLength = 0.6 * sideLength;\n    var symbolLineWidth = 0.15 * sideLength;\n    var symbolOptions = {\n        lineWidth: symbolLineWidth,\n        stroke: 'white',\n        centerX: sideLength / 2,\n        centerY: sideLength / 2\n      };\n    var expandButton = new Path(buttonShape, {\n        fill: 'rgb(0, 179, 0 )',\n        stroke: 'black',\n        lineWidth: 0.5\n      });\n    var plusSymbolShape = new Shape().moveTo(symbolLength / 2, 0).lineTo(symbolLength / 2, symbolLength).moveTo(0, symbolLength / 2).lineTo(symbolLength, symbolLength / 2);\n    expandButton.addChild(new Path(plusSymbolShape, symbolOptions));\n    var collapseButton = new Path(buttonShape, {\n        fill: 'rgb( 255, 85, 0 )',\n        stroke: 'black',\n        lineWidth: 0.5\n      });\n    var minusSymbolShape = new Shape().moveTo(-symbolLength / 2, 0).lineTo(symbolLength / 2, 0);\n    collapseButton.addChild(new Path(minusSymbolShape, symbolOptions));\n    thisButton.addChild(expandButton);\n    thisButton.addChild(collapseButton);\n    thisButton.cursor = 'pointer';\n    thisButton.addInputListener(new ButtonListener({\n      fire: function () {\n        expandedProperty.set(!expandedProperty.get());\n      }\n    }));\n    expandedProperty.link(function (expanded) {\n      expandButton.visible = !expanded;\n      collapseButton.visible = expanded;\n    });\n    thisButton.mutate(options);\n  }\n  return inherit(Node, ExpandCollapseButton);\n});",
    "\ndefine('SCENERY/nodes/Rectangle',['require','PHET_CORE/inherit','SCENERY/scenery','SCENERY/nodes/Path','KITE/Shape','DOT/Vector2'],function (require) {\n  'use strict';\n  var inherit = require('PHET_CORE/inherit');\n  var scenery = require('SCENERY/scenery');\n  var Path = require('SCENERY/nodes/Path');\n  var Shape = require('KITE/Shape');\n  var Vector2 = require('DOT/Vector2');\n  scenery.Rectangle = function Rectangle(x, y, width, height, arcWidth, arcHeight, options) {\n    if (typeof x === 'object') {\n      options = x;\n      this._rectX = options.rectX || 0;\n      this._rectY = options.rectY || 0;\n      this._rectWidth = options.rectWidth;\n      this._rectHeight = options.rectHeight;\n      this._rectArcWidth = options.rectArcWidth || 0;\n      this._rectArcHeight = options.rectArcHeight || 0;\n    } else if (arguments.length < 6) {\n      this._rectX = x;\n      this._rectY = y;\n      this._rectWidth = width;\n      this._rectHeight = height;\n      this._rectArcWidth = 0;\n      this._rectArcHeight = 0;\n      options = arcWidth || {};\n    } else {\n      this._rectX = x;\n      this._rectY = y;\n      this._rectWidth = width;\n      this._rectHeight = height;\n      this._rectArcWidth = arcWidth;\n      this._rectArcHeight = arcHeight;\n      options = options || {};\n    }\n    Path.call(this, this.createRectangleShape(), options);\n  };\n  var Rectangle = scenery.Rectangle;\n  inherit(Path, Rectangle, {\n    setRect: function (x, y, width, height, arcWidth, arcHeight) {\n      sceneryAssert && sceneryAssert(x !== undefined && y !== undefined && width !== undefined && height !== undefined, 'x/y/width/height need to be defined');\n      this._rectX = x;\n      this._rectY = y;\n      this._rectWidth = width;\n      this._rectHeight = height;\n      this._rectArcWidth = arcWidth || 0;\n      this._rectArcHeight = arcHeight || 0;\n      this.invalidateRectangle();\n    },\n    isRounded: function () {\n      return this._rectArcWidth !== 0 && this._rectArcHeight !== 0;\n    },\n    createRectangleShape: function () {\n      sceneryAssert && sceneryAssert(isFinite(this._rectX), 'A rectangle needs to have a finite x (' + this._rectX + ')');\n      sceneryAssert && sceneryAssert(isFinite(this._rectY), 'A rectangle needs to have a finite x (' + this._rectY + ')');\n      sceneryAssert && sceneryAssert(this._rectWidth >= 0 && isFinite(this._rectWidth), 'A rectangle needs to have a non-negative finite width (' + this._rectWidth + ')');\n      sceneryAssert && sceneryAssert(this._rectHeight >= 0 && isFinite(this._rectHeight), 'A rectangle needs to have a non-negative finite height (' + this._rectHeight + ')');\n      sceneryAssert && sceneryAssert(this._rectArcWidth >= 0 && isFinite(this._rectArcWidth), 'A rectangle needs to have a non-negative finite arcWidth (' + this._rectArcWidth + ')');\n      sceneryAssert && sceneryAssert(this._rectArcHeight >= 0 && isFinite(this._rectArcHeight), 'A rectangle needs to have a non-negative finite arcHeight (' + this._rectArcHeight + ')');\n      if (this.isRounded()) {\n        var maximumArcSize = Math.min(this._rectWidth / 2, this._rectHeight / 2);\n        return Shape.roundRectangle(this._rectX, this._rectY, this._rectWidth, this._rectHeight, Math.min(maximumArcSize, this._rectArcWidth), Math.min(maximumArcSize, this._rectArcHeight));\n      } else {\n        return Shape.rectangle(this._rectX, this._rectY, this._rectWidth, this._rectHeight);\n      }\n    },\n    invalidateRectangle: function () {\n      this.setShape(this.createRectangleShape());\n    },\n    computeShapeBounds: function () {\n      return this._stroke ? this._shape.bounds.dilated(this._lineDrawingStyles.lineWidth / 2) : this._shape.bounds;\n    },\n    containsPointSelf: function (point) {\n      var result = point.x >= this._rectX && point.x <= this._rectX + this._rectWidth && point.y >= this._rectY && point.y <= this._rectY + this._rectHeight;\n      if (!result || !this.isRounded()) {\n        return result;\n      }\n      var closestCornerX, closestCornerY, guaranteedInside = false;\n      if (point.x < this._rectX + this._rectWidth / 2) {\n        closestCornerX = this._rectX + this._rectArcWidth;\n        guaranteedInside = guaranteedInside || point.x >= closestCornerX;\n      } else {\n        closestCornerX = this._rectX + this._rectWidth - this._rectArcWidth;\n        guaranteedInside = guaranteedInside || point.x <= closestCornerX;\n      }\n      if (guaranteedInside) {\n        return true;\n      }\n      if (point.y < this._rectY + this._rectHeight / 2) {\n        closestCornerY = this._rectY + this._rectArcHeight;\n        guaranteedInside = guaranteedInside || point.y >= closestCornerY;\n      } else {\n        closestCornerY = this._rectY + this._rectHeight - this._rectArcHeight;\n        guaranteedInside = guaranteedInside || point.y <= closestCornerY;\n      }\n      if (guaranteedInside) {\n        return true;\n      }\n      var offsetX = point.x - closestCornerX;\n      var offsetY = point.y - closestCornerY;\n      offsetX /= this._rectArcWidth;\n      offsetY /= this._rectArcHeight;\n      offsetX *= offsetX;\n      offsetY *= offsetY;\n      return offsetX + offsetY <= 1;\n    },\n    paintCanvas: function (wrapper) {\n      var context = wrapper.context;\n      if (this.isRounded()) {\n        return Path.prototype.paintCanvas.call(this, wrapper);\n      }\n      if (this._fill) {\n        this.beforeCanvasFill(wrapper);\n        context.fillRect(this._rectX, this._rectY, this._rectWidth, this._rectHeight);\n        this.afterCanvasFill(wrapper);\n      }\n      if (this._stroke) {\n        this.beforeCanvasStroke(wrapper);\n        context.strokeRect(this._rectX, this._rectY, this._rectWidth, this._rectHeight);\n        this.afterCanvasStroke(wrapper);\n      }\n    },\n    createSVGFragment: function (svg, defs, group) {\n      return document.createElementNS('http://www.w3.org/2000/svg', 'rect');\n    },\n    updateSVGFragment: function (rect) {\n      rect.setAttribute('x', this._rectX);\n      rect.setAttribute('y', this._rectY);\n      rect.setAttribute('width', this._rectWidth);\n      rect.setAttribute('height', this._rectHeight);\n      rect.setAttribute('rx', this._rectArcWidth);\n      rect.setAttribute('ry', this._rectArcHeight);\n      rect.setAttribute('style', this.getSVGFillStyle() + this.getSVGStrokeStyle());\n    },\n    getBasicConstructor: function (propLines) {\n      return 'new scenery.Rectangle( ' + this._rectX + ', ' + this._rectY + ', ' + this._rectWidth + ', ' + this._rectHeight + ', ' + this._rectArcWidth + ', ' + this._rectArcHeight + ', {' + propLines + '} )';\n    }\n  });\n  function addRectProp(capitalizedShort) {\n    var getName = 'getRect' + capitalizedShort;\n    var setName = 'setRect' + capitalizedShort;\n    var privateName = '_rect' + capitalizedShort;\n    Rectangle.prototype[getName] = function () {\n      return this[privateName];\n    };\n    Rectangle.prototype[setName] = function (value) {\n      this[privateName] = value;\n      this.invalidateRectangle();\n      return this;\n    };\n    Object.defineProperty(Rectangle.prototype, 'rect' + capitalizedShort, {\n      set: Rectangle.prototype[setName],\n      get: Rectangle.prototype[getName]\n    });\n  }\n  addRectProp('X');\n  addRectProp('Y');\n  addRectProp('Width');\n  addRectProp('Height');\n  addRectProp('ArcWidth');\n  addRectProp('ArcHeight');\n  Rectangle.prototype._mutatorKeys = [\n    'rectX',\n    'rectY',\n    'rectWidth',\n    'rectHeight',\n    'rectArcWidth',\n    'rectArcHeight'\n  ].concat(Path.prototype._mutatorKeys);\n  return Rectangle;\n});",
    "\ndefine('PHET_CORE/escapeHTML',['require'],function (require) {\n  'use strict';\n  return function escapeHTML(str) {\n    return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\\\"/g, '&quot;').replace(/\\'/g, '&#x27;').replace(/\\//g, '&#x2F;');\n  };\n});",
    "\ndefine('SCENERY/util/Font',['require','SCENERY/scenery'],function (require) {\n  'use strict';\n  var scenery = require('SCENERY/scenery');\n  var styles = [\n      'normal',\n      'italic',\n      'oblique'\n    ];\n  var variants = [\n      'normal',\n      'small-caps'\n    ];\n  var weights = [\n      'normal',\n      'bold',\n      'bolder',\n      'lighter',\n      '100',\n      '200',\n      '300',\n      '400',\n      '500',\n      '600',\n      '700',\n      '800',\n      '900'\n    ];\n  var stretches = [\n      'normal',\n      'ultra-condensed',\n      'extra-condensed',\n      'condensed',\n      'semi-condensed',\n      'semi-expanded',\n      'expanded',\n      'extra-expanded',\n      'ultra-expanded'\n    ];\n  var sizes = [\n      'xx-small',\n      'x-small',\n      'small',\n      'medium',\n      'large',\n      'x-large',\n      'xx-large',\n      'larger',\n      'smaller'\n    ];\n  function castSize(size) {\n    if (typeof size === 'number') {\n      return size + 'px';\n    } else {\n      return size;\n    }\n  }\n  scenery.Font = function Font(options) {\n    this._style = 'normal';\n    this._variant = 'normal';\n    this._weight = 'normal';\n    this._stretch = 'normal';\n    this._size = '10px';\n    this._lineHeight = 'normal';\n    this._family = 'sans-serif';\n    var type = typeof options;\n    if (type === 'string') {\n      var tokens = _.filter(options.split(/[\\x09\\x0A\\x0C\\x0D\\x20]/), function (token) {\n          return token.length > 0;\n        });\n      for (var i = 0; i < tokens.length; i++) {\n        var token = tokens[i];\n        if (token === 'normal') {\n        } else if (_.contains(styles, token)) {\n          sceneryAssert && sceneryAssert(this._style === 'normal', 'Style cannot be applied twice. Already set to \"' + this._style + '\", attempt to replace with \"' + token + '\"');\n          this._style = token;\n        } else if (_.contains(variants, token)) {\n          sceneryAssert && sceneryAssert(this._variant === 'normal', 'Variant cannot be applied twice. Already set to \"' + this._variant + '\", attempt to replace with \"' + token + '\"');\n          this._variant = token;\n        } else if (_.contains(weights, token)) {\n          sceneryAssert && sceneryAssert(this._weight === 'normal', 'Weight cannot be applied twice. Already set to \"' + this._weight + '\", attempt to replace with \"' + token + '\"');\n          this._weight = token;\n        } else if (_.contains(stretches, token)) {\n          sceneryAssert && sceneryAssert(this._stretch === 'normal', 'Stretch cannot be applied twice. Already set to \"' + this._stretch + '\", attempt to replace with \"' + token + '\"');\n          this._stretch = token;\n        } else {\n          var subtokens = token.split(/\\//);\n          this._size = subtokens[0];\n          if (subtokens[1]) {\n            this._lineHeight = subtokens[1];\n          }\n          this._family = tokens.slice(i + 1).join(' ');\n          break;\n        }\n      }\n    } else if (type === 'object') {\n      if (options.style !== undefined) {\n        this._style = options.style;\n      }\n      if (options.variant !== undefined) {\n        this._variant = options.variant;\n      }\n      if (options.weight !== undefined) {\n        this._weight = '' + options.weight;\n      }\n      if (options.stretch !== undefined) {\n        this._stretch = options.stretch;\n      }\n      if (options.size !== undefined) {\n        this._size = castSize(options.size);\n      }\n      if (options.lineHeight !== undefined) {\n        this._lineHeight = options.lineHeight;\n      }\n      if (options.family !== undefined) {\n        this._family = options.family;\n      }\n    }\n    sceneryAssert && sceneryAssert(typeof this._style === 'string' && _.contains(styles, this._style), 'Font style must be one of \"normal\", \"italic\", or \"oblique\"');\n    sceneryAssert && sceneryAssert(typeof this._variant === 'string' && _.contains(variants, this._variant), 'Font variant must be \"normal\" or \"small-caps\"');\n    sceneryAssert && sceneryAssert(typeof this._weight === 'string' && _.contains(weights, this._weight), 'Font weight must be one of \"normal\", \"bold\", \"bolder\", \"lighter\", \"100\", \"200\", \"300\", \"400\", \"500\", \"600\", \"700\", \"800\", or \"900\"');\n    sceneryAssert && sceneryAssert(typeof this._stretch === 'string' && _.contains(stretches, this._stretch), 'Font stretch must be one of \"normal\", \"ultra-condensed\", \"extra-condensed\", \"condensed\", \"semi-condensed\", \"semi-expanded\", \"expanded\", \"extra-expanded\", or \"ultra-expanded\"');\n    sceneryAssert && sceneryAssert(typeof this._size === 'string' && !_.contains([\n      '0',\n      '1',\n      '2',\n      '3',\n      '4',\n      '5',\n      '6',\n      '7',\n      '8',\n      '9'\n    ], this._size[this._size.length - 1]), 'Font size must be either passed as a number (not a string, interpreted as px), or must contain a suffix for percentage, absolute or relative units, or an explicit size constant');\n    sceneryAssert && sceneryAssert(typeof this._lineHeight === 'string');\n    sceneryAssert && sceneryAssert(typeof this._family === 'string');\n    this._font = this.computeShorthand();\n    phetAllocation && phetAllocation('Font');\n  };\n  var Font = scenery.Font;\n  Font.prototype = {\n    constructor: Font,\n    getFont: function () {\n      return this._font;\n    },\n    getStyle: function () {\n      return this._style;\n    },\n    getVariant: function () {\n      return this._variant;\n    },\n    getWeight: function () {\n      return this._weight;\n    },\n    getStretch: function () {\n      return this._stretch;\n    },\n    getSize: function () {\n      return this._size;\n    },\n    getLineHeight: function () {\n      return this._lineHeight;\n    },\n    getFamily: function () {\n      return this._family;\n    },\n    get font() {\n      return this.getFont();\n    },\n    get style() {\n      return this.getStyle();\n    },\n    get variant() {\n      return this.getVariant();\n    },\n    get weight() {\n      return this.getWeight();\n    },\n    get stretch() {\n      return this.getStretch();\n    },\n    get size() {\n      return this.getSize();\n    },\n    get lineHeight() {\n      return this.getLineHeight();\n    },\n    get family() {\n      return this.getFamily();\n    },\n    copy: function (options) {\n      return new Font(_.extend({\n        style: this._style,\n        variant: this._variant,\n        weight: this._weight,\n        stretch: this._stretch,\n        size: this._size,\n        lineHeight: this._lineHeight,\n        family: this._family\n      }, options));\n    },\n    computeShorthand: function () {\n      var ret = '';\n      if (this._style !== 'normal') {\n        ret += this._style + ' ';\n      }\n      if (this._variant !== 'normal') {\n        ret += this._variant + ' ';\n      }\n      if (this._weight !== 'normal') {\n        ret += this._weight + ' ';\n      }\n      if (this._stretch !== 'normal') {\n        ret += this._stretch + ' ';\n      }\n      ret += this._size;\n      if (this._lineHeight !== 'normal') {\n        ret += '/' + this._lineHeight;\n      }\n      ret += ' ' + this._family;\n      return ret;\n    },\n    toCSS: function () {\n      return this.getFont();\n    }\n  };\n  Font.DEFAULT = new Font();\n  return Font;\n});",
    "\ndefine('SCENERY/nodes/Text',['require','PHET_CORE/inherit','PHET_CORE/escapeHTML','DOT/Bounds2','DOT/Matrix3','SCENERY/scenery','SCENERY/nodes/Node','SCENERY/layers/Renderer','SCENERY/nodes/Fillable','SCENERY/nodes/Strokable','SCENERY/util/Util','SCENERY/util/Font','SCENERY/util/Util'],function (require) {\n  'use strict';\n  var inherit = require('PHET_CORE/inherit');\n  var escapeHTML = require('PHET_CORE/escapeHTML');\n  var Bounds2 = require('DOT/Bounds2');\n  var Matrix3 = require('DOT/Matrix3');\n  var scenery = require('SCENERY/scenery');\n  var Node = require('SCENERY/nodes/Node');\n  var Renderer = require('SCENERY/layers/Renderer');\n  var Fillable = require('SCENERY/nodes/Fillable');\n  var Strokable = require('SCENERY/nodes/Strokable');\n  var objectCreate = require('SCENERY/util/Util').objectCreate;\n  require('SCENERY/util/Font');\n  require('SCENERY/util/Util');\n  var svgTextSizeContainer = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n  svgTextSizeContainer.setAttribute('width', '2');\n  svgTextSizeContainer.setAttribute('height', '2');\n  svgTextSizeContainer.setAttribute('style', 'display: hidden; pointer-events: none; position: absolute; left: -65535; right: -65535;');\n  var svgTextSizeElement = document.createElementNS('http://www.w3.org/2000/svg', 'text');\n  svgTextSizeElement.appendChild(document.createTextNode(''));\n  svgTextSizeContainer.appendChild(svgTextSizeElement);\n  var useDOMAsFastBounds = window.navigator.userAgent.indexOf('like Gecko) Version/5') !== -1 && window.navigator.userAgent.indexOf('Safari/') !== -1;\n  var hybridTextNode;\n  var initializingHybridTextNode = false;\n  scenery.Text = function Text(text, options) {\n    this._text = '';\n    this._font = scenery.Font.DEFAULT;\n    this._direction = 'ltr';\n    this._boundsMethod = 'hybrid';\n    this._isHTML = this._isHTML === undefined ? false : this._isHTML;\n    this._supportedRenderers = [\n      Renderer.Canvas,\n      Renderer.SVG,\n      Renderer.DOM\n    ];\n    var thisFont = this;\n    options = options || {};\n    if (options.fill === undefined) {\n      options.fill = '#000000';\n    }\n    if (text !== undefined) {\n      options.text = text;\n    }\n    this.initializeStrokable();\n    Node.call(this, options);\n    this.updateTextFlags();\n  };\n  var Text = scenery.Text;\n  inherit(Node, Text, {\n    domUpdateTransformOnRepaint: true,\n    setText: function (text) {\n      if (text !== this._text) {\n        this._text = text;\n        this.invalidateText();\n      }\n      return this;\n    },\n    getText: function () {\n      return this._text;\n    },\n    setBoundsMethod: function (method) {\n      sceneryAssert && sceneryAssert(method === 'fast' || method === 'fastCanvas' || method === 'accurate' || method === 'hybrid', 'Unknown Text boundsMethod');\n      if (method !== this._boundsMethod) {\n        this._boundsMethod = method;\n        this.updateTextFlags();\n        this.dispatchEvent('boundsAccuracy', { node: this });\n        this.invalidateText();\n      }\n      return this;\n    },\n    getBoundsMethod: function () {\n      return this._boundsMethod;\n    },\n    updateTextFlags: function () {\n      var thisText = this;\n      this.boundsInaccurate = this._boundsMethod !== 'accurate';\n      var renderersChanged = false;\n      function check(predicateValue, renderer) {\n        var inSupportedRenderers = _.contains(thisText._supportedRenderers, renderer);\n        if (predicateValue !== inSupportedRenderers) {\n          renderersChanged = true;\n          if (predicateValue) {\n            thisText._supportedRenderers.push(renderer);\n          } else {\n            thisText._supportedRenderers.splice(_.indexOf(thisText._supportedRenderers, renderer), 1);\n            if (thisText.renderer === renderer) {\n              thisText.renderer = null;\n              throw new Error('The explicitly specified Text renderer: ' + renderer.name + ' is not supported by this operation (probably invalid stroke, fill, or boundsMethod)');\n            }\n          }\n        }\n      }\n      check(this._boundsMethod !== 'fast' && !this._isHTML, Renderer.Canvas);\n      check(!this._isHTML, Renderer.SVG);\n      check(!this.hasStroke() && this.isFillDOMCompatible(), Renderer.DOM);\n      if (this._supportedRenderers.length === 0) {\n        throw new Error('No renderers are able to support this Text node (probably HTML text with a stroke or incompatible fill)');\n      }\n      if (renderersChanged) {\n        this.markLayerRefreshNeeded();\n      }\n    },\n    invalidateText: function () {\n      if (this._isHTML || useDOMAsFastBounds && this._boundsMethod !== 'accurate') {\n        this.invalidateSelf(this.approximateDOMBounds());\n      } else if (this._boundsMethod === 'hybrid') {\n        this.invalidateSelf(this.approximateHybridBounds());\n      } else if (this._boundsMethod === 'fast' || this._boundsMethod === 'fastCanvas') {\n        this.invalidateSelf(this.approximateSVGBounds());\n      } else {\n        this.invalidateSelf(this.accurateCanvasBounds());\n      }\n      this.updateTextFlags();\n    },\n    invalidateStroke: function () {\n      this.invalidateText();\n    },\n    invalidateFill: function () {\n      this.invalidateText();\n    },\n    paintCanvas: function (wrapper) {\n      var context = wrapper.context;\n      if (this.hasFill() || this.hasStroke()) {\n        wrapper.setFont(this._font.getFont());\n        wrapper.setDirection(this._direction);\n      }\n      if (this.hasFill()) {\n        this.beforeCanvasFill(wrapper);\n        context.fillText(this._text, 0, 0);\n        this.afterCanvasFill(wrapper);\n      }\n      if (this.hasStroke()) {\n        this.beforeCanvasStroke(wrapper);\n        context.strokeText(this._text, 0, 0);\n        this.afterCanvasStroke(wrapper);\n      }\n    },\n    paintWebGL: function (state) {\n      throw new Error('Text.prototype.paintWebGL unimplemented');\n    },\n    createSVGFragment: function (svg, defs, group) {\n      var element = document.createElementNS('http://www.w3.org/2000/svg', 'text');\n      element.appendChild(document.createTextNode(''));\n      return element;\n    },\n    updateSVGFragment: function (element) {\n      var isRTL = this._direction === 'rtl';\n      element.lastChild.nodeValue = this._text;\n      element.setAttribute('style', this.getSVGFillStyle() + this.getSVGStrokeStyle());\n      element.setAttribute('dominant-baseline', 'alphabetic');\n      element.setAttribute('direction', this._direction);\n      element.setAttribute('font-family', this._font.getFamily());\n      element.setAttribute('font-size', this._font.getSize());\n      element.setAttribute('font-style', this._font.getStyle());\n      element.setAttribute('font-weight', this._font.getWeight());\n      element.setAttribute('font-stretch', this._font.getStretch());\n    },\n    updateSVGDefs: function (svg, defs) {\n      this.removeSVGDefs(svg, defs);\n      this.addSVGFillDef(svg, defs);\n      this.addSVGStrokeDef(svg, defs);\n    },\n    removeSVGDefs: function (svg, defs) {\n      this.removeSVGFillDef(svg, defs);\n      this.removeSVGStrokeDef(svg, defs);\n    },\n    allowsMultipleDOMInstances: true,\n    getDOMElement: function () {\n      return document.createElement('div');\n    },\n    updateDOMElement: function (div) {\n      var $div = $(div);\n      div.style.font = this.getFont();\n      div.style.color = this.getCSSFill();\n      $div.width(this.getSelfBounds().width);\n      $div.height(this.getSelfBounds().height);\n      $div.empty();\n      div.appendChild(this.getDOMTextNode());\n      div.setAttribute('dir', this._direction);\n    },\n    updateCSSTransform: function (transform, element) {\n      var yOffset = this.getSelfBounds().minY;\n      var matrix = transform.getMatrix().timesMatrix(Matrix3.translation(0, yOffset));\n      scenery.Util.applyCSSTransform(matrix, element);\n    },\n    getDOMTextNode: function () {\n      if (this._isHTML) {\n        var span = document.createElement('span');\n        span.innerHTML = this.text;\n        return span;\n      } else {\n        return document.createTextNode(this.text);\n      }\n    },\n    accurateCanvasBounds: function () {\n      var node = this;\n      var svgBounds = this.approximateSVGBounds();\n      if (svgBounds.width === 0 && svgBounds.height === 0) {\n        return svgBounds;\n      }\n      return scenery.Util.canvasAccurateBounds(function (context) {\n        context.font = node.font;\n        context.direction = node.direction;\n        context.fillText(node.text, 0, 0);\n      }, {\n        precision: 0.5,\n        resolution: 128,\n        initialScale: 32 / Math.max(Math.abs(svgBounds.minX), Math.abs(svgBounds.minY), Math.abs(svgBounds.maxX), Math.abs(svgBounds.maxY))\n      });\n    },\n    approximateCanvasWidth: function () {\n      var context = scenery.scratchContext;\n      context.font = this.font;\n      context.direction = this.direction;\n      return context.measureText(this.text).width;\n    },\n    approximateSVGBounds: function () {\n      if (!svgTextSizeContainer.parentNode) {\n        if (document.body) {\n          document.body.appendChild(svgTextSizeContainer);\n        } else {\n          if (initializingHybridTextNode) {\n            return Bounds2.NOTHING;\n          } else {\n            throw new Error('No document.body and trying to get approximate SVG bounds of a Text node');\n          }\n        }\n      }\n      this.updateSVGFragment(svgTextSizeElement);\n      var rect = svgTextSizeElement.getBBox();\n      return new Bounds2(rect.x, rect.y, rect.x + rect.width, rect.y + rect.height);\n    },\n    approximateHybridBounds: function () {\n      if (!hybridTextNode) {\n        return Bounds2.NOTHING;\n      }\n      if (this._font._cachedSVGBounds === undefined) {\n        hybridTextNode.setFont(this._font);\n        this._font._cachedSVGBounds = hybridTextNode.getBounds();\n      }\n      var canvasWidth = this.approximateCanvasWidth();\n      var verticalBounds = this._font._cachedSVGBounds;\n      return new Bounds2(0, verticalBounds.minY, canvasWidth, verticalBounds.maxY);\n    },\n    approximateDOMBounds: function () {\n      var maxHeight = 1024;\n      var isRTL = this.direction === 'rtl';\n      var div = document.createElement('div');\n      $(div).css({\n        position: 'absolute',\n        left: 0,\n        top: 0,\n        padding: '0 !important',\n        margin: '0 !important',\n        display: 'hidden'\n      });\n      var span = document.createElement('span');\n      $(span).css('font', this.getFont());\n      span.appendChild(this.getDOMTextNode());\n      span.setAttribute('direction', this._direction);\n      var fakeImage = document.createElement('div');\n      $(fakeImage).css({\n        'vertical-align': 'baseline',\n        display: 'inline-block',\n        width: 0,\n        height: maxHeight + 'px',\n        margin: '0 !important',\n        padding: '0 !important'\n      });\n      div.appendChild(span);\n      div.appendChild(fakeImage);\n      document.body.appendChild(div);\n      var rect = span.getBoundingClientRect();\n      var divRect = div.getBoundingClientRect();\n      var result = new Bounds2(rect.left, rect.top - maxHeight, rect.right + 1, rect.bottom - maxHeight).shifted(-divRect.left, -divRect.top);\n      document.body.removeChild(div);\n      var width = rect.right - rect.left;\n      return result.shiftedX(isRTL ? -width : 0);\n    },\n    setFont: function (font) {\n      if (this.font !== font) {\n        this._font = font instanceof scenery.Font ? font : new scenery.Font(font);\n        this.invalidateText();\n      }\n      return this;\n    },\n    getFont: function () {\n      return this._font.getFont();\n    },\n    setDirection: function (direction) {\n      this._direction = direction;\n      this.invalidateText();\n      return this;\n    },\n    getDirection: function () {\n      return this._direction;\n    },\n    isPainted: function () {\n      return true;\n    },\n    getBasicConstructor: function (propLines) {\n      return 'new scenery.Text( \\'' + escapeHTML(this._text.replace(/'/g, '\\\\\\'')) + '\\', {' + propLines + '} )';\n    },\n    getPropString: function (spaces, includeChildren) {\n      var result = Node.prototype.getPropString.call(this, spaces, includeChildren);\n      result = this.appendFillablePropString(spaces, result);\n      result = this.appendStrokablePropString(spaces, result);\n      function addProp(key, value, nowrap) {\n        if (result) {\n          result += ',\\n';\n        }\n        if (!nowrap && typeof value === 'string') {\n          result += spaces + key + ': \\'' + value + '\\'';\n        } else {\n          result += spaces + key + ': ' + value;\n        }\n      }\n      if (this.font !== new scenery.Font().getFont()) {\n        addProp('font', this.font.replace(/'/g, '\\\\\\''));\n      }\n      if (this._direction !== 'ltr') {\n        addProp('direction', this._direction);\n      }\n      return result;\n    }\n  });\n  function addFontForwarding(propertyName, fullCapitalized, shortUncapitalized) {\n    var getterName = 'get' + fullCapitalized;\n    var setterName = 'set' + fullCapitalized;\n    Text.prototype[getterName] = function () {\n      return this._font[shortUncapitalized];\n    };\n    Text.prototype[setterName] = function (value) {\n      var ob = {};\n      ob[shortUncapitalized] = value;\n      var newFont = this._font.copy(ob);\n      this.setFont(newFont);\n      return this;\n    };\n    Object.defineProperty(Text.prototype, propertyName, {\n      set: Text.prototype[setterName],\n      get: Text.prototype[getterName]\n    });\n  }\n  addFontForwarding('fontWeight', 'FontWeight', 'weight');\n  addFontForwarding('fontFamily', 'FontFamily', 'family');\n  addFontForwarding('fontStretch', 'FontStretch', 'stretch');\n  addFontForwarding('fontStyle', 'FontStyle', 'style');\n  addFontForwarding('fontSize', 'FontSize', 'size');\n  addFontForwarding('lineHeight', 'LineHeight', 'lineHeight');\n  Text.prototype._mutatorKeys = [\n    'boundsMethod',\n    'text',\n    'font',\n    'fontWeight',\n    'fontFamily',\n    'fontStretch',\n    'fontStyle',\n    'fontSize',\n    'lineHeight',\n    'direction'\n  ].concat(Node.prototype._mutatorKeys);\n  Text.prototype._supportedRenderers = [\n    Renderer.Canvas,\n    Renderer.SVG,\n    Renderer.DOM\n  ];\n  Text.prototype._supportedRenderersWithFastBounds = [\n    Renderer.SVG,\n    Renderer.DOM\n  ];\n  Object.defineProperty(Text.prototype, 'font', {\n    set: Text.prototype.setFont,\n    get: Text.prototype.getFont\n  });\n  Object.defineProperty(Text.prototype, 'text', {\n    set: Text.prototype.setText,\n    get: Text.prototype.getText\n  });\n  Object.defineProperty(Text.prototype, 'direction', {\n    set: Text.prototype.setDirection,\n    get: Text.prototype.getDirection\n  });\n  Object.defineProperty(Text.prototype, 'boundsMethod', {\n    set: Text.prototype.setBoundsMethod,\n    get: Text.prototype.getBoundsMethod\n  });\n  Fillable(Text);\n  Strokable(Text);\n  initializingHybridTextNode = true;\n  hybridTextNode = new Text('m', { boundsMethod: 'fast' });\n  initializingHybridTextNode = false;\n  return Text;\n});",
    "\ndefine('SUN/AccordionBox',['require','SUN/ExpandCollapseButton','PHET_CORE/inherit','SCENERY/nodes/Node','SCENERY/nodes/Rectangle','SCENERY/nodes/Text','AXON/Property'],function (require) {\n  'use strict';\n  var ExpandCollapseButton = require('SUN/ExpandCollapseButton');\n  var inherit = require('PHET_CORE/inherit');\n  var Node = require('SCENERY/nodes/Node');\n  var Rectangle = require('SCENERY/nodes/Rectangle');\n  var Text = require('SCENERY/nodes/Text');\n  var Property = require('AXON/Property');\n  var CONTROL_BUTTON_INSET = 4;\n  var TITLE_INSET = 10;\n  var CONTROL_BUTTON_DIMENSION = 16;\n  var CONTENT_HORIZONTAL_INSET = 15;\n  var CONTENT_VERTICAL_INSET = 8;\n  var CORNER_ROUNDING = 3;\n  function AccordionBox(contentNode, options) {\n    options = _.extend({\n      stroke: 'black',\n      lineWidth: 1,\n      fill: 'rgb( 238, 238, 238 )',\n      font: '20px Arial',\n      contentPosition: 'center',\n      buttonPosition: 'left',\n      titlePosition: 'center'\n    }, options);\n    var thisNode = this;\n    Node.call(this, options);\n    this.open = new Property(options.initiallyOpen !== undefined ? options.initiallyOpen : true);\n    var expandCollapseButton = new ExpandCollapseButton(CONTROL_BUTTON_DIMENSION, this.open);\n    var title = new Node();\n    if (options.title !== undefined) {\n      title = new Text(options.title, {\n        font: options.font,\n        renderer: 'svg'\n      });\n    }\n    var containerWidth = Math.max(options.minWidth || 0, Math.max(contentNode.width + 2 * CONTENT_HORIZONTAL_INSET, CONTROL_BUTTON_INSET * 2 + CONTROL_BUTTON_DIMENSION + TITLE_INSET * 2 + title.width));\n    var closedContainerHeight = CONTROL_BUTTON_INSET * 2 + CONTROL_BUTTON_DIMENSION;\n    var openContainerHeight = CONTROL_BUTTON_INSET * 2 + CONTROL_BUTTON_DIMENSION + 2 * CONTENT_VERTICAL_INSET + contentNode.height;\n    this.openHeight = openContainerHeight;\n    var openContainer = new Rectangle(0, 0, containerWidth, openContainerHeight, CORNER_ROUNDING, CORNER_ROUNDING, {\n        stroke: options.stroke,\n        lineWidth: options.lineWidth,\n        fill: options.fill\n      });\n    openContainer.addChild(expandCollapseButton);\n    openContainer.addChild(contentNode);\n    openContainer.addChild(title);\n    this.addChild(openContainer);\n    var closedContainer = new Rectangle(0, 0, containerWidth, closedContainerHeight, CORNER_ROUNDING, CORNER_ROUNDING, {\n        stroke: options.stroke,\n        lineWidth: options.lineWidth,\n        fill: options.fill\n      });\n    closedContainer.addChild(expandCollapseButton);\n    closedContainer.addChild(title);\n    this.addChild(closedContainer);\n    var availableTitleSpace = containerWidth - CONTROL_BUTTON_INSET - CONTROL_BUTTON_DIMENSION - 2 * TITLE_INSET;\n    if (title.width > availableTitleSpace) {\n      title.scale(availableTitleSpace / title.width);\n    }\n    var openCloseNode = new Rectangle(0, 0, containerWidth, closedContainerHeight, CORNER_ROUNDING, CORNER_ROUNDING, {\n        fill: 'rgba( 0, 0, 0, 0)',\n        cursor: 'pointer'\n      });\n    openCloseNode.addInputListener({\n      down: function () {\n        thisNode.open.set(!thisNode.open.get());\n      }\n    });\n    openContainer.addChild(openCloseNode);\n    closedContainer.addChild(openCloseNode);\n    expandCollapseButton.top = CONTROL_BUTTON_INSET;\n    title.centerY = expandCollapseButton.centerY;\n    var titleLeftBound = TITLE_INSET;\n    var titleRightBound = containerWidth - TITLE_INSET;\n    contentNode.bottom = openContainerHeight - CONTENT_VERTICAL_INSET;\n    if (options.buttonPosition === 'left') {\n      expandCollapseButton.left = CONTROL_BUTTON_INSET;\n      titleLeftBound = expandCollapseButton.right + TITLE_INSET;\n    } else {\n      expandCollapseButton.right = containerWidth - CONTROL_BUTTON_INSET;\n      titleLeftBound = TITLE_INSET;\n    }\n    if (options.contentPosition === 'left') {\n      contentNode.left = CONTENT_HORIZONTAL_INSET;\n    } else if (options.contentPosition === 'right') {\n      contentNode.right = CONTENT_HORIZONTAL_INSET;\n    } else {\n      contentNode.centerX = containerWidth / 2;\n    }\n    if (options.titlePosition === 'left') {\n      title.left = titleLeftBound;\n    } else if (options.titlePosition === 'right') {\n      title.right = titleRightBound;\n    } else {\n      title.centerX = (titleLeftBound + titleRightBound) / 2;\n    }\n    this.open.link(function (isOpen) {\n      openContainer.visible = isOpen;\n      closedContainer.visible = !isOpen;\n    });\n  }\n  inherit(Node, AccordionBox);\n  return AccordionBox;\n});",
    "\ndefine('SCENERY/nodes/Circle',['require','PHET_CORE/inherit','SCENERY/scenery','SCENERY/nodes/Path','KITE/Shape'],function (require) {\n  'use strict';\n  var inherit = require('PHET_CORE/inherit');\n  var scenery = require('SCENERY/scenery');\n  var Path = require('SCENERY/nodes/Path');\n  var Shape = require('KITE/Shape');\n  scenery.Circle = function Circle(radius, options) {\n    if (typeof radius === 'object') {\n      options = radius;\n    } else {\n      this._radius = radius;\n      options = options || {};\n    }\n    Path.call(this, Shape.circle(0, 0, radius), options);\n  };\n  var Circle = scenery.Circle;\n  inherit(Path, Circle, {\n    invalidateCircle: function () {\n      this.setShape(Shape.circle(0, 0, this._radius));\n    },\n    createSVGFragment: function (svg, defs, group) {\n      return document.createElementNS('http://www.w3.org/2000/svg', 'circle');\n    },\n    updateSVGFragment: function (circle) {\n      circle.setAttribute('r', this._radius);\n      circle.setAttribute('style', this.getSVGFillStyle() + this.getSVGStrokeStyle());\n    },\n    getBasicConstructor: function (propLines) {\n      return 'new scenery.Circle( ' + this._radius + ', {' + propLines + '} )';\n    },\n    getRadius: function () {\n      return this._radius;\n    },\n    setRadius: function (radius) {\n      if (this._radius !== radius) {\n        this._radius = radius;\n        this.invalidateCircle();\n      }\n      return this;\n    },\n    computeShapeBounds: function () {\n      return this._stroke ? this._shape.bounds.dilated(this._lineDrawingStyles.lineWidth / 2) : this._shape.bounds;\n    },\n    containsPointSelf: function (point) {\n      return point.x * point.x + point.y * point.y < this._radius * this._radius;\n    },\n    get radius() {\n      return this.getRadius();\n    },\n    set radius(value) {\n      return this.setRadius(value);\n    }\n  });\n  Circle.prototype._mutatorKeys = ['radius'].concat(Path.prototype._mutatorKeys);\n  return Circle;\n});",
    "\ndefine('SUN/RadioButton',['require','SCENERY/input/ButtonListener','PHET_CORE/inherit','SCENERY/nodes/Node','SCENERY/nodes/Path','KITE/Shape'],function (require) {\n  'use strict';\n  var ButtonListener = require('SCENERY/input/ButtonListener');\n  var inherit = require('PHET_CORE/inherit');\n  var Node = require('SCENERY/nodes/Node');\n  var Path = require('SCENERY/nodes/Path');\n  var Shape = require('KITE/Shape');\n  function RadioButton(property, value, selectedNode, deselectedNode, options) {\n    options = _.extend({ cursor: 'pointer' }, options);\n    var thisNode = this;\n    Node.call(thisNode, options);\n    var background = new Path(Shape.bounds(selectedNode.bounds.union(deselectedNode.bounds)));\n    thisNode.addChild(background);\n    thisNode.addChild(selectedNode);\n    thisNode.addChild(deselectedNode);\n    property.link(function (newValue) {\n      selectedNode.visible = newValue === value;\n      deselectedNode.visible = !selectedNode.visible;\n    });\n    thisNode.addInputListener(new ButtonListener({\n      fire: function () {\n        property.set(value);\n      }\n    }));\n  }\n  inherit(Node, RadioButton);\n  return RadioButton;\n});",
    "\ndefine('SUN/AquaRadioButton',['require','SCENERY/nodes/Circle','PHET_CORE/inherit','SCENERY/nodes/Node','SUN/RadioButton'],function (require) {\n  'use strict';\n  var Circle = require('SCENERY/nodes/Circle');\n  var inherit = require('PHET_CORE/inherit');\n  var Node = require('SCENERY/nodes/Node');\n  var RadioButton = require('SUN/RadioButton');\n  function AquaRadioButton(property, value, node, options) {\n    options = _.extend({\n      cursor: 'pointer',\n      selectedColor: 'rgb( 143, 197, 250 )',\n      deselectedColor: 'white',\n      centerColor: 'black',\n      radius: 16,\n      xSpacing: 8,\n      stroke: 'black'\n    }, options);\n    var selectedNode = new Node();\n    var innerCircle = new Circle(options.radius / 3, { fill: options.centerColor });\n    var outerCircleSelected = new Circle(options.radius, {\n        fill: options.selectedColor,\n        stroke: options.stroke\n      });\n    selectedNode.addChild(outerCircleSelected);\n    selectedNode.addChild(innerCircle);\n    selectedNode.addChild(node);\n    node.left = outerCircleSelected.right + options.xSpacing;\n    node.centerY = outerCircleSelected.centerY;\n    var deselectedNode = new Node();\n    var outerCircleDeselected = new Circle(options.radius, {\n        fill: options.deselectedColor,\n        stroke: options.stroke\n      });\n    deselectedNode.addChild(outerCircleDeselected);\n    deselectedNode.addChild(node);\n    node.left = outerCircleDeselected.right + options.xSpacing;\n    node.centerY = outerCircleDeselected.centerY;\n    RadioButton.call(this, property, value, selectedNode, deselectedNode, options);\n  }\n  inherit(RadioButton, AquaRadioButton);\n  return AquaRadioButton;\n});",
    "\ndefine('SCENERY_PHET/PhetFont',['require','SCENERY/util/Font','PHET_CORE/inherit'],function (require) {\n  'use strict';\n  var Font = require('SCENERY/util/Font');\n  var inherit = require('PHET_CORE/inherit');\n  function PhetFont(options) {\n    if (typeof options === 'number' || typeof options === 'string') {\n      options = { size: options };\n    }\n    options = _.extend({ family: 'Arial' }, options);\n    null;\n    options.family = options.family + ', sans-serif';\n    Font.call(this, options);\n  }\n  return inherit(Font, PhetFont);\n});",
    "\ndefine('SCENERY/util/Color',['require','SCENERY/scenery','DOT/Util','DOT/Util'],function (require) {\n  'use strict';\n  var scenery = require('SCENERY/scenery');\n  var clamp = require('DOT/Util').clamp;\n  var linear = require('DOT/Util').linear;\n  scenery.Color = function Color(r, g, b, a) {\n    this.listeners = [];\n    if (typeof r === 'string') {\n      var str = r.replace(/ /g, '').toLowerCase();\n      var success = false;\n      var keywordMatch = Color.colorKeywords[str];\n      if (keywordMatch) {\n        str = '#' + keywordMatch;\n      }\n      for (var i = 0; i < Color.formatParsers.length; i++) {\n        var parser = Color.formatParsers[i];\n        var matches = parser.regexp.exec(str);\n        if (matches) {\n          parser.apply(this, matches);\n          success = true;\n          break;\n        }\n      }\n      if (!success) {\n        throw new Error('scenery.Color unable to parse color string: ' + r);\n      }\n    } else {\n      var alpha = a === undefined ? 1 : a;\n      if (g === undefined || b === undefined) {\n        this.setRGBA(r >> 16 && 255, r >> 8 && 255, r >> 0 && 255, alpha);\n      } else {\n        this.setRGBA(r, g, b, alpha);\n      }\n    }\n    phetAllocation && phetAllocation('Color');\n  };\n  var Color = scenery.Color;\n  var rgbNumber = '(-?\\\\d{1,3}%?)';\n  var aNumber = '(\\\\d+|\\\\d*\\\\.\\\\d+)';\n  var rawNumber = '(\\\\d{1,3})';\n  function parseRGBNumber(str) {\n    var multiplier = 1;\n    if (str.charAt(str.length - 1) === '%') {\n      multiplier = 2.55;\n      str = str.slice(0, str.length - 1);\n    }\n    return Math.round(parseInt(str, 10) * multiplier);\n  }\n  Color.formatParsers = [\n    {\n      regexp: /^transparent$/,\n      apply: function (color, matches) {\n        color.setRGBA(0, 0, 0, 0);\n      }\n    },\n    {\n      regexp: /^#(\\w{1})(\\w{1})(\\w{1})$/,\n      apply: function (color, matches) {\n        color.setRGBA(parseInt(matches[1] + matches[1], 16), parseInt(matches[2] + matches[2], 16), parseInt(matches[3] + matches[3], 16), 1);\n      }\n    },\n    {\n      regexp: /^#(\\w{2})(\\w{2})(\\w{2})$/,\n      apply: function (color, matches) {\n        color.setRGBA(parseInt(matches[1], 16), parseInt(matches[2], 16), parseInt(matches[3], 16), 1);\n      }\n    },\n    {\n      regexp: new RegExp('^rgb\\\\(' + rgbNumber + ',' + rgbNumber + ',' + rgbNumber + '\\\\)$'),\n      apply: function (color, matches) {\n        color.setRGBA(parseRGBNumber(matches[1]), parseRGBNumber(matches[2]), parseRGBNumber(matches[3]), 1);\n      }\n    },\n    {\n      regexp: new RegExp('^rgba\\\\(' + rgbNumber + ',' + rgbNumber + ',' + rgbNumber + ',' + aNumber + '\\\\)$'),\n      apply: function (color, matches) {\n        color.setRGBA(parseRGBNumber(matches[1]), parseRGBNumber(matches[2]), parseRGBNumber(matches[3]), parseFloat(matches[4]));\n      }\n    },\n    {\n      regexp: new RegExp('^hsl\\\\(' + rawNumber + ',' + rawNumber + '%,' + rawNumber + '%\\\\)$'),\n      apply: function (color, matches) {\n        color.setHSLA(parseInt(matches[1], 10), parseInt(matches[2], 10), parseInt(matches[3], 10), 1);\n      }\n    },\n    {\n      regexp: new RegExp('^hsla\\\\(' + rawNumber + ',' + rawNumber + '%,' + rawNumber + '%,' + aNumber + '\\\\)$'),\n      apply: function (color, matches) {\n        color.setHSLA(parseInt(matches[1], 10), parseInt(matches[2], 10), parseInt(matches[3], 10), parseFloat(matches[4]));\n      }\n    }\n  ];\n  Color.hueToRGB = function (m1, m2, h) {\n    if (h < 0) {\n      h = h + 1;\n    }\n    if (h > 1) {\n      h = h - 1;\n    }\n    if (h * 6 < 1) {\n      return m1 + (m2 - m1) * h * 6;\n    }\n    if (h * 2 < 1) {\n      return m2;\n    }\n    if (h * 3 < 2) {\n      return m1 + (m2 - m1) * (2 / 3 - h) * 6;\n    }\n    return m1;\n  };\n  Color.prototype = {\n    constructor: Color,\n    copy: function () {\n      return new Color(this.r, this.g, this.b, this.a);\n    },\n    getRed: function () {\n      return this.r;\n    },\n    setRed: function (value) {\n      return this.setRGBA(value, this.g, this.b, this.a);\n    },\n    get red() {\n      return this.getRed();\n    },\n    set red(value) {\n      return this.setRed(value);\n    },\n    getGreen: function () {\n      return this.g;\n    },\n    setGreen: function (value) {\n      return this.setRGBA(this.r, value, this.b, this.a);\n    },\n    get green() {\n      return this.getGreen();\n    },\n    set green(value) {\n      return this.setGreen(value);\n    },\n    getBlue: function () {\n      return this.b;\n    },\n    setBlue: function (value) {\n      return this.setRGBA(this.r, this.g, value, this.a);\n    },\n    get blue() {\n      return this.getBlue();\n    },\n    set blue(value) {\n      return this.setBlue(value);\n    },\n    getAlpha: function () {\n      return this.a;\n    },\n    setAlpha: function (value) {\n      return this.setRGBA(this.r, this.g, this.b, value);\n    },\n    get alpha() {\n      return this.getAlpha();\n    },\n    set alpha(value) {\n      return this.setAlpha(value);\n    },\n    setRGBA: function (red, green, blue, alpha) {\n      this.r = Math.round(clamp(red, 0, 255));\n      this.g = Math.round(clamp(green, 0, 255));\n      this.b = Math.round(clamp(blue, 0, 255));\n      this.a = clamp(alpha, 0, 1);\n      this.updateColor();\n      return this;\n    },\n    computeCSS: function () {\n      if (this.a === 1) {\n        return 'rgb(' + this.r + ',' + this.g + ',' + this.b + ')';\n      } else {\n        var alphaString = this.a === 0 || this.a === 1 ? this.a : this.a.toFixed(20);\n        return 'rgba(' + this.r + ',' + this.g + ',' + this.b + ',' + alphaString + ')';\n      }\n    },\n    toCSS: function () {\n      sceneryAssert && sceneryAssert(this._css === this.computeCSS(), 'CSS cached value is ' + this._css + ', but the computed value appears to be ' + this.computeCSS());\n      return this._css;\n    },\n    updateColor: function () {\n      sceneryAssert && sceneryAssert(!this.immutable, 'Cannot modify an immutable color');\n      var oldCSS = this._css;\n      this._css = this.computeCSS();\n      if (oldCSS !== this._css && this.listeners.length) {\n        var listeners = this.listeners.slice(0);\n        var length = listeners.length;\n        for (var i = 0; i < length; i++) {\n          listeners[i]();\n        }\n      }\n    },\n    setImmutable: function () {\n      if (sceneryAssert) {\n        this.immutable = true;\n      }\n      return this;\n    },\n    getCanvasStyle: function () {\n      return this.toCSS();\n    },\n    setHSLA: function (hue, saturation, lightness, alpha) {\n      hue = hue % 360 / 360;\n      saturation = clamp(saturation / 100, 0, 1);\n      lightness = clamp(lightness / 100, 0, 1);\n      var m1, m2;\n      if (lightness < 0.5) {\n        m2 = lightness * (saturation + 1);\n      } else {\n        m2 = lightness + saturation - lightness * saturation;\n      }\n      m1 = lightness * 2 - m2;\n      this.r = Math.round(Color.hueToRGB(m1, m2, hue + 1 / 3) * 255);\n      this.g = Math.round(Color.hueToRGB(m1, m2, hue) * 255);\n      this.b = Math.round(Color.hueToRGB(m1, m2, hue - 1 / 3) * 255);\n      this.a = clamp(alpha, 0, 1);\n      this.updateColor();\n      return this;\n    },\n    equals: function (color) {\n      return this.r === color.r && this.g === color.g && this.b === color.b && this.a === color.a;\n    },\n    withAlpha: function (alpha) {\n      return new Color(this.r, this.g, this.b, alpha);\n    },\n    checkFactor: function (factor) {\n      if (factor < 0 || factor > 1) {\n        throw new Error('factor must be between 0 and 1: ' + factor);\n      }\n      return factor === undefined ? 0.7 : factor;\n    },\n    brighterColor: function (factor) {\n      factor = this.checkFactor(factor);\n      var red = Math.min(255, Math.floor(this.r / factor));\n      var green = Math.min(255, Math.floor(this.g / factor));\n      var blue = Math.min(255, Math.floor(this.b / factor));\n      return new Color(red, green, blue, this.a);\n    },\n    colorUtilsBrighter: function (factor) {\n      factor = this.checkFactor(factor);\n      var red = Math.min(255, this.getRed() + Math.floor(factor * (255 - this.getRed())));\n      var green = Math.min(255, this.getGreen() + Math.floor(factor * (255 - this.getGreen())));\n      var blue = Math.min(255, this.getBlue() + Math.floor(factor * (255 - this.getBlue())));\n      return new Color(red, green, blue, this.getAlpha());\n    },\n    darkerColor: function (factor) {\n      factor = this.checkFactor(factor);\n      var red = Math.max(0, Math.floor(factor * this.r));\n      var green = Math.max(0, Math.floor(factor * this.g));\n      var blue = Math.max(0, Math.floor(factor * this.b));\n      return new Color(red, green, blue, this.a);\n    },\n    colorUtilsDarker: function (factor) {\n      factor = this.checkFactor(factor);\n      var red = Math.max(0, this.getRed() - Math.floor(factor * this.getRed()));\n      var green = Math.max(0, this.getGreen() - Math.floor(factor * this.getGreen()));\n      var blue = Math.max(0, this.getBlue() - Math.floor(factor * this.getBlue()));\n      return new Color(red, green, blue, this.getAlpha());\n    },\n    addChangeListener: function (listener) {\n      sceneryAssert && sceneryAssert(listener !== undefined && listener !== null, 'Verify that the listener exists');\n      sceneryAssert && sceneryAssert(!_.contains(this.listeners, listener));\n      this.listeners.push(listener);\n    },\n    removeChangeListener: function (listener) {\n      sceneryAssert && sceneryAssert(_.contains(this.listeners, listener));\n      this.listeners.splice(_.indexOf(this.listeners, listener), 1);\n    },\n    toString: function () {\n      return this.constructor.name + '[r:' + this.r + ' g:' + this.g + ' b:' + this.b + ' a:' + this.a + ']';\n    }\n  };\n  Color.basicColorKeywords = {\n    aqua: '00ffff',\n    black: '000000',\n    blue: '0000ff',\n    fuchsia: 'ff00ff',\n    gray: '808080',\n    green: '008000',\n    lime: '00ff00',\n    maroon: '800000',\n    navy: '000080',\n    olive: '808000',\n    purple: '800080',\n    red: 'ff0000',\n    silver: 'c0c0c0',\n    teal: '008080',\n    white: 'ffffff',\n    yellow: 'ffff00'\n  };\n  Color.colorKeywords = {\n    aliceblue: 'f0f8ff',\n    antiquewhite: 'faebd7',\n    aqua: '00ffff',\n    aquamarine: '7fffd4',\n    azure: 'f0ffff',\n    beige: 'f5f5dc',\n    bisque: 'ffe4c4',\n    black: '000000',\n    blanchedalmond: 'ffebcd',\n    blue: '0000ff',\n    blueviolet: '8a2be2',\n    brown: 'a52a2a',\n    burlywood: 'deb887',\n    cadetblue: '5f9ea0',\n    chartreuse: '7fff00',\n    chocolate: 'd2691e',\n    coral: 'ff7f50',\n    cornflowerblue: '6495ed',\n    cornsilk: 'fff8dc',\n    crimson: 'dc143c',\n    cyan: '00ffff',\n    darkblue: '00008b',\n    darkcyan: '008b8b',\n    darkgoldenrod: 'b8860b',\n    darkgray: 'a9a9a9',\n    darkgreen: '006400',\n    darkkhaki: 'bdb76b',\n    darkmagenta: '8b008b',\n    darkolivegreen: '556b2f',\n    darkorange: 'ff8c00',\n    darkorchid: '9932cc',\n    darkred: '8b0000',\n    darksalmon: 'e9967a',\n    darkseagreen: '8fbc8f',\n    darkslateblue: '483d8b',\n    darkslategray: '2f4f4f',\n    darkturquoise: '00ced1',\n    darkviolet: '9400d3',\n    deeppink: 'ff1493',\n    deepskyblue: '00bfff',\n    dimgray: '696969',\n    dodgerblue: '1e90ff',\n    feldspar: 'd19275',\n    firebrick: 'b22222',\n    floralwhite: 'fffaf0',\n    forestgreen: '228b22',\n    fuchsia: 'ff00ff',\n    gainsboro: 'dcdcdc',\n    ghostwhite: 'f8f8ff',\n    gold: 'ffd700',\n    goldenrod: 'daa520',\n    gray: '808080',\n    green: '008000',\n    greenyellow: 'adff2f',\n    honeydew: 'f0fff0',\n    hotpink: 'ff69b4',\n    indianred: 'cd5c5c',\n    indigo: '4b0082',\n    ivory: 'fffff0',\n    khaki: 'f0e68c',\n    lavender: 'e6e6fa',\n    lavenderblush: 'fff0f5',\n    lawngreen: '7cfc00',\n    lemonchiffon: 'fffacd',\n    lightblue: 'add8e6',\n    lightcoral: 'f08080',\n    lightcyan: 'e0ffff',\n    lightgoldenrodyellow: 'fafad2',\n    lightgrey: 'd3d3d3',\n    lightgreen: '90ee90',\n    lightpink: 'ffb6c1',\n    lightsalmon: 'ffa07a',\n    lightseagreen: '20b2aa',\n    lightskyblue: '87cefa',\n    lightslateblue: '8470ff',\n    lightslategray: '778899',\n    lightsteelblue: 'b0c4de',\n    lightyellow: 'ffffe0',\n    lime: '00ff00',\n    limegreen: '32cd32',\n    linen: 'faf0e6',\n    magenta: 'ff00ff',\n    maroon: '800000',\n    mediumaquamarine: '66cdaa',\n    mediumblue: '0000cd',\n    mediumorchid: 'ba55d3',\n    mediumpurple: '9370d8',\n    mediumseagreen: '3cb371',\n    mediumslateblue: '7b68ee',\n    mediumspringgreen: '00fa9a',\n    mediumturquoise: '48d1cc',\n    mediumvioletred: 'c71585',\n    midnightblue: '191970',\n    mintcream: 'f5fffa',\n    mistyrose: 'ffe4e1',\n    moccasin: 'ffe4b5',\n    navajowhite: 'ffdead',\n    navy: '000080',\n    oldlace: 'fdf5e6',\n    olive: '808000',\n    olivedrab: '6b8e23',\n    orange: 'ffa500',\n    orangered: 'ff4500',\n    orchid: 'da70d6',\n    palegoldenrod: 'eee8aa',\n    palegreen: '98fb98',\n    paleturquoise: 'afeeee',\n    palevioletred: 'd87093',\n    papayawhip: 'ffefd5',\n    peachpuff: 'ffdab9',\n    peru: 'cd853f',\n    pink: 'ffc0cb',\n    plum: 'dda0dd',\n    powderblue: 'b0e0e6',\n    purple: '800080',\n    red: 'ff0000',\n    rosybrown: 'bc8f8f',\n    royalblue: '4169e1',\n    saddlebrown: '8b4513',\n    salmon: 'fa8072',\n    sandybrown: 'f4a460',\n    seagreen: '2e8b57',\n    seashell: 'fff5ee',\n    sienna: 'a0522d',\n    silver: 'c0c0c0',\n    skyblue: '87ceeb',\n    slateblue: '6a5acd',\n    slategray: '708090',\n    snow: 'fffafa',\n    springgreen: '00ff7f',\n    steelblue: '4682b4',\n    tan: 'd2b48c',\n    teal: '008080',\n    thistle: 'd8bfd8',\n    tomato: 'ff6347',\n    turquoise: '40e0d0',\n    violet: 'ee82ee',\n    violetred: 'd02090',\n    wheat: 'f5deb3',\n    white: 'ffffff',\n    whitesmoke: 'f5f5f5',\n    yellow: 'ffff00',\n    yellowgreen: '9acd32'\n  };\n  Color.BLACK = new Color(0, 0, 0).setImmutable();\n  Color.BLUE = new Color(0, 0, 255).setImmutable();\n  Color.CYAN = new Color(0, 255, 255).setImmutable();\n  Color.DARK_GRAY = new Color(64, 64, 64).setImmutable();\n  Color.GRAY = new Color(128, 128, 128).setImmutable();\n  Color.GREEN = new Color(0, 255, 0).setImmutable();\n  Color.LIGHT_GRAY = new Color(192, 192, 192).setImmutable();\n  Color.MAGENTA = new Color(255, 0, 255).setImmutable();\n  Color.ORANGE = new Color(255, 200, 0).setImmutable();\n  Color.PINK = new Color(255, 175, 175).setImmutable();\n  Color.RED = new Color(255, 0, 0).setImmutable();\n  Color.WHITE = new Color(255, 255, 255).setImmutable();\n  Color.YELLOW = new Color(255, 255, 0).setImmutable();\n  Color.interpolateRBGA = function (color1, color2, distance) {\n    if (distance < 0 || distance > 1) {\n      throw new Error('distance must be between 0 and 1: ' + distance);\n    }\n    var r = Math.floor(linear(0, 1, color1.r, color2.r, distance));\n    var g = Math.floor(linear(0, 1, color1.g, color2.g, distance));\n    var b = Math.floor(linear(0, 1, color1.b, color2.b, distance));\n    var a = linear(0, 1, color1.a, color2.a, distance);\n    return new Color(r, g, b, a);\n  };\n  return Color;\n});",
    "\ndefine('SCENERY/util/Gradient',['require','SCENERY/util/Color','SCENERY/scenery','DOT/Vector2'],function (require) {\n  'use strict';\n  require('SCENERY/util/Color');\n  var scenery = require('SCENERY/scenery');\n  var Vector2 = require('DOT/Vector2');\n  scenery.Gradient = function Gradient(canvasGradient) {\n    sceneryAssert && sceneryAssert(this.constructor.name !== 'Gradient', 'Please create a LinearGradient or RadialGradient. Do not directly use the supertype Gradient.');\n    this.stops = [];\n    this.lastStopRatio = 0;\n    this.canvasGradient = canvasGradient;\n    this.transformMatrix = null;\n  };\n  var Gradient = scenery.Gradient;\n  Gradient.prototype = {\n    constructor: Gradient,\n    addColorStop: function (ratio, color) {\n      if (this.lastStopRatio > ratio) {\n        throw new Error('Color stops not specified in the order of increasing ratios');\n      } else {\n        this.lastStopRatio = ratio;\n      }\n      if (typeof color === 'string') {\n        color = new scenery.Color(color);\n      }\n      this.stops.push({\n        ratio: ratio,\n        color: color\n      });\n      this.canvasGradient.addColorStop(ratio, color.toCSS());\n      return this;\n    },\n    setTransformMatrix: function (transformMatrix) {\n      if (this.transformMatrix !== transformMatrix) {\n        this.transformMatrix = transformMatrix;\n      }\n      return this;\n    },\n    getCanvasStyle: function () {\n      return this.canvasGradient;\n    }\n  };\n  return Gradient;\n});",
    "\ndefine('SCENERY/util/RadialGradient',['require','SCENERY/scenery','PHET_CORE/inherit','DOT/Vector2','SCENERY/util/Gradient'],function (require) {\n  'use strict';\n  var scenery = require('SCENERY/scenery');\n  var inherit = require('PHET_CORE/inherit');\n  var Vector2 = require('DOT/Vector2');\n  var Gradient = require('SCENERY/util/Gradient');\n  scenery.RadialGradient = function RadialGradient(x0, y0, r0, x1, y1, r1) {\n    this.start = new Vector2(x0, y0);\n    this.end = new Vector2(x1, y1);\n    this.startRadius = r0;\n    this.endRadius = r1;\n    this.focalPoint = this.start.plus(this.end.minus(this.start).times(this.startRadius / (this.startRadius - this.endRadius)));\n    if (this.startRadius >= this.endRadius) {\n      sceneryAssert && sceneryAssert(this.focalPoint.minus(this.start).magnitude() <= this.startRadius);\n    } else {\n      sceneryAssert && sceneryAssert(this.focalPoint.minus(this.end).magnitude() <= this.endRadius);\n    }\n    Gradient.call(this, scenery.scratchContext.createRadialGradient(x0, y0, r0, x1, y1, r1));\n  };\n  var RadialGradient = scenery.RadialGradient;\n  inherit(Gradient, RadialGradient, {\n    getSVGDefinition: function (id) {\n      var startIsLarger = this.startRadius > this.endRadius;\n      var largePoint = startIsLarger ? this.start : this.end;\n      var smallPoint = startIsLarger ? this.end : this.start;\n      var maxRadius = Math.max(this.startRadius, this.endRadius);\n      var minRadius = Math.min(this.startRadius, this.endRadius);\n      var svgns = 'http://www.w3.org/2000/svg';\n      var definition = document.createElementNS(svgns, 'radialGradient');\n      definition.setAttribute('id', id);\n      definition.setAttribute('gradientUnits', 'userSpaceOnUse');\n      definition.setAttribute('cx', largePoint.x);\n      definition.setAttribute('cy', largePoint.y);\n      definition.setAttribute('r', maxRadius);\n      definition.setAttribute('fx', this.focalPoint.x);\n      definition.setAttribute('fy', this.focalPoint.y);\n      if (this.transformMatrix) {\n        definition.setAttribute('gradientTransform', this.transformMatrix.getSVGTransform());\n      }\n      function linearMap(a0, b0, a1, b1, x) {\n        return a1 + (x - a0) * (b1 - a1) / (b0 - a0);\n      }\n      function applyStop(stop) {\n        var ratio = startIsLarger ? 1 - stop.ratio : stop.ratio;\n        if (minRadius > 0) {\n          ratio = linearMap(0, 1, minRadius / maxRadius, 1, ratio);\n        }\n        var stopElement = document.createElementNS(svgns, 'stop');\n        stopElement.setAttribute('offset', ratio);\n        stopElement.setAttribute('style', 'stop-color: ' + stop.color.withAlpha(1).toCSS() + '; stop-opacity: ' + stop.color.a.toFixed(20) + ';');\n        definition.appendChild(stopElement);\n      }\n      var i;\n      if (startIsLarger) {\n        for (i = this.stops.length - 1; i >= 0; i--) {\n          applyStop(this.stops[i]);\n        }\n      } else {\n        for (i = 0; i < this.stops.length; i++) {\n          applyStop(this.stops[i]);\n        }\n      }\n      return definition;\n    },\n    toString: function () {\n      var result = 'new scenery.RadialGradient( ' + this.start.x + ', ' + this.start.y + ', ' + this.startRadius + ', ' + this.end.x + ', ' + this.end.y + ', ' + this.endRadius + ' )';\n      _.each(this.stops, function (stop) {\n        result += '.addColorStop( ' + stop.ratio + ', \\'' + stop.color.toString() + '\\' )';\n      });\n      return result;\n    }\n  });\n  return RadialGradient;\n});",
    "\ndefine('SCENERY/input/SimpleDragHandler',['require','DOT/Matrix3','SCENERY/scenery'],function (require) {\n  'use strict';\n  var Matrix3 = require('DOT/Matrix3');\n  var scenery = require('SCENERY/scenery');\n  scenery.SimpleDragHandler = function SimpleDragHandler(options) {\n    var handler = this;\n    this.options = _.extend({\n      allowTouchSnag: false,\n      mouseButton: 0\n    }, options);\n    this.dragging = false;\n    this.pointer = null;\n    this.trail = null;\n    this.transform = null;\n    this.node = null;\n    this.lastDragPoint = null;\n    this.startTransformMatrix = null;\n    this.mouseButton = undefined;\n    this.transformListener = {\n      transform: function (args) {\n        if (!handler.trail.isExtensionOf(args.trail, true)) {\n          return;\n        }\n        var newMatrix = args.trail.getTransform().getMatrix();\n        var oldMatrix = handler.transform.getMatrix();\n        handler.node.prependMatrix(newMatrix.inverted().timesMatrix(oldMatrix));\n        handler.transform.set(newMatrix);\n      }\n    };\n    this.dragListener = {\n      up: function (event) {\n        sceneryAssert && sceneryAssert(event.pointer === handler.pointer);\n        if (!event.pointer.isMouse || event.domEvent.button === handler.mouseButton) {\n          var saveCurrentTarget = event.currentTarget;\n          event.currentTarget = handler.node;\n          handler.endDrag(event);\n          event.currentTarget = saveCurrentTarget;\n        }\n      },\n      cancel: function (event) {\n        sceneryAssert && sceneryAssert(event.pointer === handler.pointer);\n        var saveCurrentTarget = event.currentTarget;\n        event.currentTarget = handler.node;\n        handler.endDrag(event);\n        event.currentTarget = saveCurrentTarget;\n        if (!handler.transform) {\n          handler.node.setMatrix(handler.startTransformMatrix);\n        }\n      },\n      move: function (event) {\n        sceneryAssert && sceneryAssert(event.pointer === handler.pointer);\n        var delta = handler.transform.inverseDelta2(handler.pointer.point.minus(handler.lastDragPoint));\n        if (handler.options.translate) {\n          var translation = handler.node.getTransform().getMatrix().getTranslation();\n          handler.options.translate({\n            delta: delta,\n            oldPosition: translation,\n            position: translation.plus(delta)\n          });\n        } else {\n          handler.node.translate(delta, true);\n        }\n        handler.lastDragPoint = handler.pointer.point;\n        if (handler.options.drag) {\n          var saveCurrentTarget = event.currentTarget;\n          event.currentTarget = handler.node;\n          handler.options.drag(event, handler.trail);\n          event.currentTarget = saveCurrentTarget;\n        }\n      }\n    };\n  };\n  var SimpleDragHandler = scenery.SimpleDragHandler;\n  SimpleDragHandler.prototype = {\n    constructor: SimpleDragHandler,\n    startDrag: function (event) {\n      event.pointer.dragging = true;\n      event.pointer.addInputListener(this.dragListener);\n      this.dragging = true;\n      this.pointer = event.pointer;\n      this.trail = event.trail.subtrailTo(event.currentTarget, true);\n      this.transform = this.trail.getTransform();\n      this.node = event.currentTarget;\n      this.lastDragPoint = event.pointer.point;\n      this.startTransformMatrix = event.currentTarget.getMatrix();\n      this.mouseButton = event.pointer.isMouse ? event.domEvent.button : undefined;\n      if (this.options.start) {\n        this.options.start(event, this.trail);\n      }\n    },\n    endDrag: function (event) {\n      this.pointer.dragging = false;\n      this.pointer.removeInputListener(this.dragListener);\n      this.dragging = false;\n      if (this.options.end) {\n        this.options.end(event, this.trail);\n      }\n    },\n    tryToSnag: function (event) {\n      if (event.pointer.isMouse && event.domEvent && this.options.mouseButton !== event.domEvent.button && this.options.mouseButton !== -1) {\n        return;\n      }\n      if (!this.dragging && !event.pointer.dragging) {\n        this.startDrag(event);\n      }\n    },\n    down: function (event) {\n      this.tryToSnag(event);\n    },\n    touchenter: function (event) {\n      if (this.options.allowTouchSnag) {\n        this.tryToSnag(event);\n      }\n    }\n  };\n  return SimpleDragHandler;\n});",
    "\ndefine('common/view/ElectronCloudView',['require','SCENERY/nodes/Node','SCENERY/nodes/Circle','SCENERY/util/RadialGradient','SCENERY/input/SimpleDragHandler','PHET_CORE/inherit'],function (require) {\n  'use strict';\n  var Node = require('SCENERY/nodes/Node');\n  var Circle = require('SCENERY/nodes/Circle');\n  var RadialGradient = require('SCENERY/util/RadialGradient');\n  var SimpleDragHandler = require('SCENERY/input/SimpleDragHandler');\n  var inherit = require('PHET_CORE/inherit');\n  var ElectronCloudView = function ElectronCloudView(atom, mvt) {\n    Node.call(this, { cursor: 'pointer' });\n    var thisNode = this;\n    var electronCloud = new Circle(mvt.modelToViewDeltaX(atom.outerElectronShellRadius), {\n        fill: 'pink',\n        translation: mvt.modelToViewPosition({\n          x: 0,\n          y: 0\n        })\n      });\n    this.addChild(electronCloud);\n    var updateElectronCloud = function (numElectrons) {\n      if (numElectrons === 0) {\n        electronCloud.radius = 0.00001;\n        electronCloud.fill = 'transparent';\n      } else {\n        var minRadius = mvt.modelToViewDeltaX(atom.innerElectronShellRadius) * 0.5;\n        var maxRadius = mvt.modelToViewDeltaX(atom.outerElectronShellRadius);\n        var radius = minRadius + (maxRadius - minRadius) / 10 * numElectrons;\n        electronCloud.radius = radius;\n        electronCloud.fill = new RadialGradient(0, 0, 0, 0, 0, radius).addColorStop(0, 'rgba( 0, 0, 255, 200 )').addColorStop(0.9, 'rgba( 0, 0, 255, 0 )');\n      }\n    };\n    updateElectronCloud(atom.electrons.length);\n    atom.electrons.lengthProperty.link(function (length) {\n      updateElectronCloud(length);\n    });\n    this.extractedElectron = null;\n    this.addInputListener(new SimpleDragHandler({\n      activeParticle: null,\n      start: function (event, trail) {\n        var positionInModelSpace = mvt.viewToModelPosition(thisNode.getParents()[0].globalToLocalPoint(event.pointer.point));\n        var electron = atom.removeParticle('electron');\n        if (electron !== null) {\n          electron.userControlled = true;\n          electron.setPositionAndDestination(positionInModelSpace);\n          thisNode.extractedElectron = electron;\n        }\n      },\n      translate: function (translationParams) {\n        if (thisNode.extractedElectron !== null) {\n          thisNode.extractedElectron.setPositionAndDestination(thisNode.extractedElectron.position.plus(mvt.viewToModelDelta(translationParams.delta)));\n        }\n      },\n      end: function (event) {\n        if (thisNode.extractedElectron !== null) {\n          thisNode.extractedElectron.userControlled = false;\n        }\n      }\n    }));\n  };\n  inherit(Node, ElectronCloudView);\n  return ElectronCloudView;\n});",
    "\ndefine('common/view/ElectronShellView',['require','SCENERY/nodes/Circle','PHET_CORE/inherit','SCENERY/nodes/Node'],function (require) {\n  'use strict';\n  var Circle = require('SCENERY/nodes/Circle');\n  var inherit = require('PHET_CORE/inherit');\n  var Node = require('SCENERY/nodes/Node');\n  var LINE_DASH = [\n      4,\n      5\n    ];\n  var ElectronShellView = function ElectronShellView(atom, mvt) {\n    Node.call(this, { renderer: 'svg' });\n    var outerRing = new Circle(mvt.modelToViewDeltaX(atom.outerElectronShellRadius), {\n        stroke: 'blue',\n        lineWidth: 1.5,\n        lineDash: LINE_DASH,\n        translation: mvt.modelToViewPosition({\n          x: 0,\n          y: 0\n        })\n      });\n    this.addChild(outerRing);\n    var innerRing = new Circle(mvt.modelToViewDeltaX(atom.innerElectronShellRadius), {\n        stroke: 'blue',\n        lineWidth: 1.5,\n        lineDash: LINE_DASH,\n        translation: mvt.modelToViewPosition({\n          x: 0,\n          y: 0\n        })\n      });\n    this.addChild(innerRing);\n  };\n  inherit(Node, ElectronShellView);\n  return ElectronShellView;\n});",
    "\ndefine('common/view/AtomNode',['require','common/AtomIdentifier','SCENERY_PHET/PhetFont','common/view/ElectronCloudView','common/view/ElectronShellView','PHET_CORE/inherit','SCENERY/nodes/Node','SCENERY/nodes/Path','AXON/Property','KITE/Shape','SCENERY/nodes/Text','DOT/Vector2'],function (require) {\n  'use strict';\n  var AtomIdentifier = require('common/AtomIdentifier');\n  var PhetFont = require('SCENERY_PHET/PhetFont');\n  var ElectronCloudView = require('common/view/ElectronCloudView');\n  var ElectronShellView = require('common/view/ElectronShellView');\n  var inherit = require('PHET_CORE/inherit');\n  var Node = require('SCENERY/nodes/Node');\n  var Path = require('SCENERY/nodes/Path');\n  var Property = require('AXON/Property');\n  var Shape = require('KITE/Shape');\n  var Text = require('SCENERY/nodes/Text');\n  var Vector2 = require('DOT/Vector2');\n  function AtomNode(particleAtom, mvt, options) {\n    options = _.extend({\n      showCenterX: true,\n      showElementNameProperty: new Property(true),\n      showNeutralOrIonProperty: new Property(true),\n      showStableOrUnstableProperty: new Property(true),\n      electronShellDepictionProperty: new Property('orbits')\n    }, options);\n    Node.call(this, options);\n    var thisAtomView = this;\n    this.atom = particleAtom;\n    this.mvt = mvt;\n    if (options.showCenterX) {\n      var sizeInPixels = mvt.modelToViewDeltaX(20);\n      var center = mvt.modelToViewPosition(particleAtom.position);\n      var centerMarker = new Shape();\n      centerMarker.moveTo(center.x - sizeInPixels / 2, center.y - sizeInPixels / 2);\n      centerMarker.lineTo(center.x + sizeInPixels / 2, center.y + sizeInPixels / 2);\n      centerMarker.moveTo(center.x - sizeInPixels / 2, center.y + sizeInPixels / 2);\n      centerMarker.lineTo(center.x + sizeInPixels / 2, center.y - sizeInPixels / 2);\n      var atomCenterMarker = new Path(centerMarker, {\n          stroke: 'orange',\n          lineWidth: 5\n        });\n      this.addChild(atomCenterMarker);\n      var listener = function () {\n        atomCenterMarker.visible = particleAtom.getWeight() === 0;\n      };\n      particleAtom.electrons.lengthProperty.link(listener);\n      particleAtom.neutrons.lengthProperty.link(listener);\n      particleAtom.protons.lengthProperty.link(listener);\n    }\n    var electronShell = new ElectronShellView(particleAtom, mvt);\n    this.addChild(electronShell);\n    var electronCloud = new ElectronCloudView(particleAtom, mvt);\n    this.addChild(electronCloud);\n    options.electronShellDepictionProperty.link(function (depiction) {\n      electronShell.visible = depiction === 'orbits';\n      electronCloud.visible = depiction === 'cloud';\n    });\n    var elementNameCenterPos = mvt.modelToViewPosition(particleAtom.position.plus(new Vector2(0, particleAtom.innerElectronShellRadius / 2)));\n    var elementNameFontSize = mvt.modelToViewDeltaX(particleAtom.innerElectronShellRadius) * 0.35;\n    this.elementName = new Text('', {\n      font: new PhetFont(elementNameFontSize),\n      fill: 'red',\n      center: elementNameCenterPos\n    });\n    this.addChild(this.elementName);\n    var updateElementName = function () {\n      var name = AtomIdentifier.getName(thisAtomView.atom.protons.length);\n      if (name.length === 0) {\n        name = '';\n      }\n      thisAtomView.elementName.text = name;\n      thisAtomView.elementName.setScaleMagnitude(1);\n      var maxLabelWidth = mvt.modelToViewDeltaX(particleAtom.innerElectronShellRadius * 1.4);\n      thisAtomView.elementName.setScaleMagnitude(Math.min(maxLabelWidth / thisAtomView.elementName.width, 1));\n      thisAtomView.elementName.center = elementNameCenterPos;\n    };\n    updateElementName();\n    particleAtom.protons.lengthProperty.link(function () {\n      updateElementName();\n    });\n    options.showElementNameProperty.link(function (visible) {\n      thisAtomView.elementName.visible = visible;\n    });\n    var ionIndicatorTranslation = mvt.modelToViewPosition(particleAtom.position.plus(new Vector2(particleAtom.outerElectronShellRadius * 1.05, 0).rotated(Math.PI * 0.4)));\n    this.ionIndicator = new Text('', {\n      font: new PhetFont(24),\n      fill: 'black',\n      translation: ionIndicatorTranslation\n    });\n    this.addChild(this.ionIndicator);\n    var updateIonIndicator = function () {\n      if (thisAtomView.atom.protons.length > 0) {\n        var charge = thisAtomView.atom.getCharge();\n        if (charge < 0) {\n          thisAtomView.ionIndicator.text = '- Ion';\n          thisAtomView.ionIndicator.fill = 'blue';\n        } else if (charge > 0) {\n          thisAtomView.ionIndicator.text = '+ Ion';\n          thisAtomView.ionIndicator.fill = 'red';\n        } else {\n          thisAtomView.ionIndicator.text = 'Neutral Atom';\n          thisAtomView.ionIndicator.fill = 'black';\n        }\n      } else {\n        thisAtomView.ionIndicator.text = '';\n        thisAtomView.ionIndicator.fill = 'black';\n      }\n    };\n    updateIonIndicator();\n    particleAtom.protons.lengthProperty.link(updateIonIndicator);\n    particleAtom.electrons.lengthProperty.link(updateIonIndicator);\n    options.showNeutralOrIonProperty.link(function (visible) {\n      thisAtomView.ionIndicator.visible = visible;\n    });\n    var stabilityIndicatorCenterPos = mvt.modelToViewPosition(Vector2.ZERO).add(new Vector2(0, 40));\n    this.stabilityIndicator = new Text('', {\n      font: new PhetFont(24),\n      fill: 'black',\n      center: stabilityIndicatorCenterPos\n    });\n    this.addChild(this.stabilityIndicator);\n    var updateStabilityIndicator = function () {\n      if (thisAtomView.atom.protons.length > 0) {\n        if (AtomIdentifier.isStable(thisAtomView.atom.protons.length, thisAtomView.atom.neutrons.length)) {\n          thisAtomView.stabilityIndicator.text = 'Stable';\n        } else {\n          thisAtomView.stabilityIndicator.text = 'Unstable';\n        }\n      } else {\n        thisAtomView.stabilityIndicator.text = '';\n      }\n      thisAtomView.stabilityIndicator.center = stabilityIndicatorCenterPos;\n    };\n    updateStabilityIndicator();\n    particleAtom.protons.lengthProperty.link(function () {\n      updateElementName();\n      updateIonIndicator();\n      updateStabilityIndicator();\n    });\n    particleAtom.electrons.lengthProperty.link(updateIonIndicator);\n    particleAtom.neutrons.lengthProperty.link(updateStabilityIndicator);\n    options.showStableOrUnstableProperty.link(function (visible) {\n      thisAtomView.stabilityIndicator.visible = visible;\n    });\n  }\n  inherit(Node, AtomNode);\n  return AtomNode;\n});",
    "\ndefine('buildanatom/view/BucketDragHandler',['require','PHET_CORE/inherit','SCENERY/input/SimpleDragHandler','DOT/Vector2','DOT/Bounds2'],function (require) {\n  'use strict';\n  var inherit = require('PHET_CORE/inherit');\n  var SimpleDragHandler = require('SCENERY/input/SimpleDragHandler');\n  var Vector2 = require('DOT/Vector2');\n  var Bounds2 = require('DOT/Bounds2');\n  var BucketDragHandler = function BucketDragHandler(bucket, bucketView, mvt) {\n    var activeParticle = null;\n    var options = {\n        start: function (event, trail) {\n          var positionInModelSpace = mvt.viewToModelPosition(bucketView.getParents()[0].globalToLocalPoint(event.pointer.point));\n          activeParticle = bucket.extractClosestParticle(positionInModelSpace);\n          if (activeParticle !== null) {\n            activeParticle.setPositionAndDestination(positionInModelSpace);\n          }\n        },\n        translate: function (translationParams) {\n          if (activeParticle !== null) {\n            activeParticle.setPositionAndDestination(activeParticle.position.plus(mvt.viewToModelDelta(translationParams.delta)));\n          }\n        },\n        end: function (event) {\n          if (activeParticle !== null) {\n            activeParticle.userControlled = false;\n          }\n        }\n      };\n    SimpleDragHandler.call(this, options);\n  };\n  inherit(SimpleDragHandler, BucketDragHandler);\n  return BucketDragHandler;\n});",
    "\ndefine('SCENERY/util/LinearGradient',['require','SCENERY/scenery','PHET_CORE/inherit','DOT/Vector2','SCENERY/util/Gradient'],function (require) {\n  'use strict';\n  var scenery = require('SCENERY/scenery');\n  var inherit = require('PHET_CORE/inherit');\n  var Vector2 = require('DOT/Vector2');\n  var Gradient = require('SCENERY/util/Gradient');\n  scenery.LinearGradient = function LinearGradient(x0, y0, x1, y1) {\n    sceneryAssert && sceneryAssert(isFinite(x0) && isFinite(y0) && isFinite(x1) && isFinite(y1));\n    var usesVectors = y1 === undefined;\n    if (usesVectors) {\n      sceneryAssert && sceneryAssert(x0 instanceof Vector2 && y0 instanceof Vector2, 'If less than 4 parameters are given, the first two parameters must be Vector2');\n    }\n    this.start = usesVectors ? x0 : new Vector2(x0, y0);\n    this.end = usesVectors ? y0 : new Vector2(x1, y1);\n    Gradient.call(this, scenery.scratchContext.createLinearGradient(x0, y0, x1, y1));\n  };\n  var LinearGradient = scenery.LinearGradient;\n  inherit(Gradient, LinearGradient, {\n    getSVGDefinition: function (id) {\n      var svgns = 'http://www.w3.org/2000/svg';\n      var definition = document.createElementNS(svgns, 'linearGradient');\n      definition.setAttribute('id', id);\n      definition.setAttribute('gradientUnits', 'userSpaceOnUse');\n      definition.setAttribute('x1', this.start.x);\n      definition.setAttribute('y1', this.start.y);\n      definition.setAttribute('x2', this.end.x);\n      definition.setAttribute('y2', this.end.y);\n      if (this.transformMatrix) {\n        definition.setAttribute('gradientTransform', this.transformMatrix.getSVGTransform());\n      }\n      _.each(this.stops, function (stop) {\n        var stopElement = document.createElementNS(svgns, 'stop');\n        stopElement.setAttribute('offset', stop.ratio);\n        stopElement.setAttribute('style', 'stop-color: ' + stop.color.withAlpha(1).toCSS() + '; stop-opacity: ' + stop.color.a.toFixed(20) + ';');\n        definition.appendChild(stopElement);\n      });\n      return definition;\n    },\n    toString: function () {\n      var result = 'new scenery.LinearGradient( ' + this.start.x + ', ' + this.start.y + ', ' + this.end.x + ', ' + this.end.y + ' )';\n      _.each(this.stops, function (stop) {\n        result += '.addColorStop( ' + stop.ratio + ', \\'' + stop.color.toString() + '\\' )';\n      });\n      return result;\n    }\n  });\n  return LinearGradient;\n});",
    "\ndefine('SCENERY_PHET/bucket/BucketFront',['require','PHET_CORE/inherit','SCENERY/nodes/Node','SCENERY/nodes/Path','SCENERY/nodes/Text','SCENERY/util/Color','SCENERY/util/LinearGradient','KITE/Shape','DOT/Matrix3'],function (require) {\n  'use strict';\n  var inherit = require('PHET_CORE/inherit');\n  var Node = require('SCENERY/nodes/Node');\n  var Path = require('SCENERY/nodes/Path');\n  var Text = require('SCENERY/nodes/Text');\n  var Color = require('SCENERY/util/Color');\n  var LinearGradient = require('SCENERY/util/LinearGradient');\n  var Shape = require('KITE/Shape');\n  var Matrix3 = require('DOT/Matrix3');\n  var BucketFront = function BucketFront(bucket, mvt) {\n    Node.call(this);\n    var scaleMatrix = Matrix3.scaling(mvt.getMatrix().m00(), mvt.getMatrix().m11());\n    var transformedShape = bucket.containerShape.transformed(scaleMatrix);\n    var baseColor = new Color(bucket.baseColor);\n    var frontGradient = new LinearGradient(transformedShape.bounds.getMinX(), 0, transformedShape.bounds.getMaxX(), 0);\n    frontGradient.addColorStop(0, baseColor.colorUtilsBrighter(0.5).toCSS());\n    frontGradient.addColorStop(1, baseColor.colorUtilsDarker(0.5).toCSS());\n    this.addChild(new Path(transformedShape, { fill: frontGradient }));\n    this.addChild(new Text(bucket.captionText, {\n      font: 'bold 18px Arial',\n      fill: bucket.captionColor,\n      centerX: transformedShape.bounds.getCenterX(),\n      centerY: transformedShape.bounds.getCenterY(),\n      renderer: 'svg'\n    }));\n    this.translation = mvt.modelToViewPosition(bucket.position);\n  };\n  inherit(Node, BucketFront);\n  return BucketFront;\n});",
    "\ndefine('SCENERY_PHET/bucket/BucketHole',['require','PHET_CORE/inherit','SCENERY/nodes/Node','SCENERY/nodes/Path','SCENERY/util/LinearGradient','KITE/Shape','DOT/Matrix3'],function (require) {\n  'use strict';\n  var inherit = require('PHET_CORE/inherit');\n  var Node = require('SCENERY/nodes/Node');\n  var Path = require('SCENERY/nodes/Path');\n  var LinearGradient = require('SCENERY/util/LinearGradient');\n  var Shape = require('KITE/Shape');\n  var Matrix3 = require('DOT/Matrix3');\n  var BucketHole = function BucketHole(bucket, mvt) {\n    Node.call(this);\n    var scaleMatrix = Matrix3.scaling(mvt.getMatrix().m00(), mvt.getMatrix().m11());\n    var transformedShape = bucket.holeShape.transformed(scaleMatrix);\n    var gradientPaint = new LinearGradient(transformedShape.bounds.getMinX(), 0, transformedShape.bounds.getMaxX(), 0);\n    gradientPaint.addColorStop(0, 'black');\n    gradientPaint.addColorStop(1, '#c0c0c0');\n    this.addChild(new Path(transformedShape, {\n      fill: gradientPaint,\n      stroke: '#777',\n      lineWidth: 1\n    }));\n    this.translation = mvt.modelToViewPosition(bucket.position);\n  };\n  inherit(Node, BucketHole);\n  return BucketHole;\n});",
    "\ndefine('PHETCOMMON/view/ModelViewTransform2',['require','PHET_CORE/inherit','DOT/Vector2','DOT/Matrix3','DOT/Transform3'],function (require) {\n  'use strict';\n  var inherit = require('PHET_CORE/inherit');\n  var Vector2 = require('DOT/Vector2');\n  var Matrix3 = require('DOT/Matrix3');\n  var Transform3 = require('DOT/Transform3');\n  function ModelViewTransform2(matrix) {\n    Transform3.call(this, matrix);\n  }\n  inherit(Transform3, ModelViewTransform2, {\n    modelToViewPosition: function (point) {\n      return this.transformPosition2(point);\n    },\n    modelToViewX: function (x) {\n      return this.matrix.m00() * x + this.matrix.m02();\n    },\n    modelToViewY: function (y) {\n      return this.matrix.m11() * y + this.matrix.m12();\n    },\n    modelToViewDelta: function (vector) {\n      return this.transformDelta2(vector);\n    },\n    modelToViewNormal: function (normal) {\n      return this.transformNormal2(normal);\n    },\n    modelToViewDeltaX: function (x) {\n      return this.transformDeltaX(x);\n    },\n    modelToViewDeltaY: function (y) {\n      return this.transformDeltaY(y);\n    },\n    modelToViewBounds: function (bounds) {\n      return this.transformBounds2(bounds);\n    },\n    modelToViewShape: function (shape) {\n      return this.transformShape(shape);\n    },\n    modelToViewRay: function (ray) {\n      return this.transformRay2(ray);\n    },\n    viewToModelPosition: function (point) {\n      return this.inversePosition2(point);\n    },\n    viewToModelX: function (x) {\n      return this.inversePosition2(new Vector2(x, 0)).x;\n    },\n    viewToModelY: function (y) {\n      return this.inversePosition2(new Vector2(0, y)).y;\n    },\n    viewToModelDelta: function (vector) {\n      return this.inverseDelta2(vector);\n    },\n    viewToModelNormal: function (normal) {\n      return this.inverseNormal2(normal);\n    },\n    viewToModelDeltaX: function (x) {\n      return this.inverseDeltaX(x);\n    },\n    viewToModelDeltaY: function (y) {\n      return this.inverseDeltaY(y);\n    },\n    viewToModelBounds: function (bounds) {\n      return this.inverseBounds2(bounds);\n    },\n    viewToModelShape: function (shape) {\n      return this.inverseShape(shape);\n    },\n    viewToModelRay: function (ray) {\n      return this.inverseRay2(ray);\n    }\n  });\n  ModelViewTransform2.createIdentity = function () {\n    return new ModelViewTransform2(Matrix3.IDENTITY);\n  };\n  ModelViewTransform2.createOffsetScaleMapping = function (offset, scale) {\n    return new ModelViewTransform2(Matrix3.affine(scale, 0, 0, scale, offset.x, offset.y));\n  };\n  ModelViewTransform2.createOffsetXYScaleMapping = function (offset, xScale, yScale) {\n    return new ModelViewTransform2(Matrix3.affine(xScale, 0, 0, yScale, offset.x, offset.y));\n  };\n  ModelViewTransform2.createSinglePointXYScaleMapping = function (modelPoint, viewPoint, xScale, yScale) {\n    var offsetX = viewPoint.x - modelPoint.x * xScale;\n    var offsetY = viewPoint.y - modelPoint.y * yScale;\n    return this.createOffsetXYScaleMapping(new Vector2(offsetX, offsetY), xScale, yScale);\n  };\n  ModelViewTransform2.createSinglePointScaleMapping = function (modelPoint, viewPoint, scale) {\n    return this.createSinglePointXYScaleMapping(modelPoint, viewPoint, scale, scale);\n  };\n  ModelViewTransform2.createSinglePointScaleInvertedYMapping = function (modelPoint, viewPoint, scale) {\n    return this.createSinglePointXYScaleMapping(modelPoint, viewPoint, scale, -scale);\n  };\n  ModelViewTransform2.createRectangleMapping = function (modelBounds, viewBounds) {\n    var m00 = viewBounds.width / modelBounds.width;\n    var m02 = viewBounds.x - m00 * modelBounds.x;\n    var m11 = viewBounds.height / modelBounds.height;\n    var m12 = viewBounds.y - m11 * modelBounds.y;\n    return new ModelViewTransform2(Matrix3.affine(m00, 0, 0, m11, m02, m12));\n  };\n  ModelViewTransform2.createRectangleInvertedYMapping = function (modelBounds, viewBounds) {\n    var m00 = viewBounds.width / modelBounds.width;\n    var m02 = viewBounds.x - m00 * modelBounds.x;\n    var m11 = -viewBounds.height / modelBounds.height;\n    var m12 = viewBounds.y - m11 * modelBounds.getMaxY();\n    return new ModelViewTransform2(Matrix3.affine(m00, 0, 0, m11, m02, m12));\n  };\n  return ModelViewTransform2;\n});",
    "\ndefine('SUN/Panel',['require','PHET_CORE/inherit','SCENERY/nodes/Node','SCENERY/nodes/Rectangle'],function (require) {\n  'use strict';\n  var inherit = require('PHET_CORE/inherit');\n  var Node = require('SCENERY/nodes/Node');\n  var Rectangle = require('SCENERY/nodes/Rectangle');\n  function Panel(content, options) {\n    var thisNode = this;\n    options = _.extend({\n      fill: 'white',\n      stroke: 'black',\n      lineWidth: 1,\n      xMargin: 5,\n      yMargin: 5,\n      cornerRadius: 10,\n      resize: true,\n      backgroundPickable: false\n    }, options);\n    Node.call(thisNode);\n    var background = new Rectangle(0, 0, 1, 1, {\n        stroke: options.stroke,\n        lineWidth: options.lineWidth,\n        fill: options.fill,\n        pickable: options.backgroundPickable\n      });\n    this.addChild(background);\n    this.addChild(content);\n    var updateBackground = function () {\n      background.setRect(0, 0, content.width + 2 * options.xMargin, content.height + 2 * options.yMargin, options.cornerRadius, options.cornerRadius);\n      content.centerX = background.centerX;\n      content.centerY = background.centerY;\n    };\n    if (options.resize) {\n      content.addEventListener('bounds', function () {\n        updateBackground();\n      });\n    }\n    updateBackground();\n    this.mutate(options);\n  }\n  inherit(Node, Panel);\n  return Panel;\n});",
    "\ndefine('common/view/ParticleNode',['require','SCENERY/nodes/Node','SCENERY/nodes/Circle','SCENERY/util/RadialGradient','PHET_CORE/inherit'],function (require) {\n  'use strict';\n  var Node = require('SCENERY/nodes/Node');\n  var Circle = require('SCENERY/nodes/Circle');\n  var RadialGradient = require('SCENERY/util/RadialGradient');\n  var inherit = require('PHET_CORE/inherit');\n  function ParticleNode(particleType, radius, options) {\n    Node.call(this, options);\n    var colors = {\n        proton: 'red',\n        neutron: 'gray',\n        electron: 'blue'\n      };\n    var baseColor = colors[particleType];\n    if (baseColor === undefined) {\n      console.error('Unrecognized particle type.');\n      baseColor = 'black';\n    }\n    this.addChild(new Circle(radius, {\n      fill: new RadialGradient(-radius * 0.4, -radius * 0.4, 0, -radius * 0.4, -radius * 0.4, radius * 1.6).addColorStop(0, 'white').addColorStop(1, baseColor),\n      cursor: 'pointer'\n    }));\n  }\n  inherit(Node, ParticleNode);\n  return ParticleNode;\n});",
    "\ndefine('common/view/ParticleCountDisplay',['require','SCENERY_PHET/PhetFont','SCENERY/nodes/Node','SCENERY/nodes/Rectangle','PHET_CORE/inherit','SCENERY/nodes/Text','common/view/ParticleNode','SUN/Panel','common/SharedConstants'],function (require) {\n  'use strict';\n  var PhetFont = require('SCENERY_PHET/PhetFont');\n  var Node = require('SCENERY/nodes/Node');\n  var Rectangle = require('SCENERY/nodes/Rectangle');\n  var inherit = require('PHET_CORE/inherit');\n  var Text = require('SCENERY/nodes/Text');\n  var ParticleNode = require('common/view/ParticleNode');\n  var Panel = require('SUN/Panel');\n  var SharedConstants = require('common/SharedConstants');\n  var FONT = new PhetFont(14);\n  var ParticleCountDisplay = function ParticleCountDisplay(numberAtom, maxParticles, maxWidth) {\n    Node.call(this, { pickable: false });\n    var panelContents = new Node();\n    var titleOptions = { font: new PhetFont(14) };\n    var protonTitle = new Text('Protons:', titleOptions);\n    panelContents.addChild(protonTitle);\n    var neutronTitle = new Text('Neutrons:', titleOptions);\n    panelContents.addChild(neutronTitle);\n    var electronTitle = new Text('Electrons:', titleOptions);\n    panelContents.addChild(electronTitle);\n    var maxLabelWidth = Math.max(Math.max(protonTitle.width, neutronTitle.width), electronTitle.width);\n    protonTitle.right = maxLabelWidth;\n    protonTitle.top = 0;\n    neutronTitle.right = maxLabelWidth;\n    neutronTitle.top = protonTitle.bottom;\n    electronTitle.right = maxLabelWidth;\n    electronTitle.top = neutronTitle.bottom;\n    var totalParticleSpace = maxWidth - protonTitle.right - 10;\n    var nucleonRadius = totalParticleSpace / (maxParticles * 2 + (maxParticles - 1) + 2);\n    var electronRadius = nucleonRadius * 0.6;\n    var interParticleSpacing = nucleonRadius * 3;\n    var spacer = new Rectangle(maxLabelWidth, 0, interParticleSpacing * 3, 1);\n    var particleLayer = new Node({ children: [spacer] });\n    panelContents.addChild(particleLayer);\n    var protons = [];\n    var neutrons = [];\n    var electrons = [];\n    var protonDisplayCount = 0;\n    var neutronDisplayCount = 0;\n    var electronDisplayCount = 0;\n    function incrementParticle(array, currentQuantity, particleType, radius, startX, startY) {\n      var newIndex = currentQuantity;\n      if (newIndex === array.length) {\n        array.push(new ParticleNode(particleType, radius, {\n          x: startX + newIndex * interParticleSpacing,\n          y: startY\n        }));\n      }\n      particleLayer.addChild(array[newIndex]);\n      currentQuantity += 1;\n      return currentQuantity;\n    }\n    function decrementParticle(array, currentQuantity) {\n      currentQuantity -= 1;\n      particleLayer.removeChild(array[currentQuantity]);\n      return currentQuantity;\n    }\n    var updateParticles = function (atom) {\n      while (atom.protonCount > protonDisplayCount) {\n        protonDisplayCount = incrementParticle(protons, protonDisplayCount, 'proton', nucleonRadius, protonTitle.right + interParticleSpacing, protonTitle.center.y);\n      }\n      while (atom.protonCount < protonDisplayCount) {\n        protonDisplayCount = decrementParticle(protons, protonDisplayCount);\n      }\n      while (atom.neutronCount > neutronDisplayCount) {\n        neutronDisplayCount = incrementParticle(neutrons, neutronDisplayCount, 'neutron', nucleonRadius, neutronTitle.right + interParticleSpacing, neutronTitle.center.y);\n      }\n      while (atom.neutronCount < neutronDisplayCount) {\n        neutronDisplayCount = decrementParticle(neutrons, neutronDisplayCount);\n      }\n      while (atom.electronCount > electronDisplayCount) {\n        electronDisplayCount = incrementParticle(electrons, electronDisplayCount, 'electron', electronRadius, electronTitle.right + interParticleSpacing, electronTitle.center.y);\n      }\n      while (atom.electronCount < electronDisplayCount) {\n        electronDisplayCount = decrementParticle(electrons, electronDisplayCount);\n      }\n    };\n    numberAtom.particleCountProperty.link(function () {\n      updateParticles(numberAtom);\n    });\n    updateParticles(numberAtom);\n    this.addChild(new Panel(panelContents, { fill: SharedConstants.DISPLAY_PANEL_BACKGROUND_COLOR }));\n  };\n  inherit(Node, ParticleCountDisplay);\n  return ParticleCountDisplay;\n});",
    "\ndefine('SCENERY/nodes/Image',['require','PHET_CORE/inherit','DOT/Bounds2','SCENERY/scenery','SCENERY/nodes/Node','SCENERY/layers/Renderer','SCENERY/util/Util','SCENERY/util/Util'],function (require) {\n  'use strict';\n  var inherit = require('PHET_CORE/inherit');\n  var Bounds2 = require('DOT/Bounds2');\n  var scenery = require('SCENERY/scenery');\n  var Node = require('SCENERY/nodes/Node');\n  var Renderer = require('SCENERY/layers/Renderer');\n  var objectCreate = require('SCENERY/util/Util').objectCreate;\n  require('SCENERY/util/Util');\n  scenery.Image = function Image(image, options) {\n    sceneryAssert && sceneryAssert(image, 'image should be available');\n    options = options || {};\n    if (image) {\n      options.image = image;\n    }\n    var self = this;\n    this.loadListener = function (event) {\n      self.invalidateImage();\n      self._image.removeEventListener('load', self.loadListener);\n    };\n    Node.call(this, options);\n  };\n  var Image = scenery.Image;\n  inherit(Node, Image, {\n    allowsMultipleDOMInstances: false,\n    invalidateImage: function () {\n      this.invalidateSelf(new Bounds2(0, 0, this.getImageWidth(), this.getImageHeight()));\n    },\n    getImage: function () {\n      return this._image;\n    },\n    setImage: function (image) {\n      var self = this;\n      if (this._image !== image && (typeof image !== 'string' || !this._image || image !== this._image.src)) {\n        if (this._image) {\n          this._image.removeEventListener('load', this.loadListener);\n        }\n        if (typeof image === 'string') {\n          var src = image;\n          image = document.createElement('img');\n          image.addEventListener('load', this.loadListener);\n          image.src = src;\n        } else if (image instanceof HTMLImageElement) {\n          if (!image.width || !image.height) {\n            image.addEventListener('load', this.loadListener);\n          }\n        }\n        if (image instanceof HTMLCanvasElement) {\n          if (!this.hasOwnProperty('_supportedRenderers')) {\n            this._supportedRenderers = [Renderer.Canvas];\n            this.markLayerRefreshNeeded();\n          }\n        } else {\n          if (this.hasOwnProperty('_supportedRenderers')) {\n            delete this._supportedRenderers;\n            this.markLayerRefreshNeeded();\n          }\n        }\n        this._image = image;\n        this.invalidateImage();\n      }\n      return this;\n    },\n    getImageWidth: function () {\n      return this._image.width;\n    },\n    getImageHeight: function () {\n      return this._image.height;\n    },\n    getImageURL: function () {\n      return this._image.src;\n    },\n    isPainted: function () {\n      return true;\n    },\n    paintCanvas: function (wrapper) {\n      wrapper.context.drawImage(this._image, 0, 0);\n    },\n    paintWebGL: function (state) {\n      throw new Error('paintWebGL:nimplemented');\n    },\n    createSVGFragment: function (svg, defs, group) {\n      var element = document.createElementNS('http://www.w3.org/2000/svg', 'image');\n      element.setAttribute('x', 0);\n      element.setAttribute('y', 0);\n      return element;\n    },\n    updateSVGFragment: function (element) {\n      var xlinkns = 'http://www.w3.org/1999/xlink';\n      element.setAttribute('width', this.getImageWidth() + 'px');\n      element.setAttribute('height', this.getImageHeight() + 'px');\n      element.setAttributeNS(xlinkns, 'xlink:href', this.getImageURL());\n    },\n    getDOMElement: function () {\n      this._image.style.display = 'block';\n      this._image.style.position = 'absolute';\n      this._image.style.left = '0';\n      this._image.style.top = '0';\n      return this._image;\n    },\n    updateDOMElement: function (image) {\n      if (image.src !== this._image.src) {\n        image.src = this._image.src;\n      }\n    },\n    updateCSSTransform: function (transform, element) {\n      scenery.Util.applyCSSTransform(transform.getMatrix(), element);\n    },\n    set image(value) {\n      this.setImage(value);\n    },\n    get image() {\n      return this.getImage();\n    },\n    getBasicConstructor: function (propLines) {\n      return 'new scenery.Image( \\'' + (this._image.src ? this._image.src.replace(/'/g, '\\\\\\'') : 'other') + '\\', {' + propLines + '} )';\n    }\n  });\n  Image.prototype._mutatorKeys = ['image'].concat(Node.prototype._mutatorKeys);\n  Image.prototype._supportedRenderers = [\n    Renderer.Canvas,\n    Renderer.SVG,\n    Renderer.DOM\n  ];\n  Image.createSVGImage = function (url, width, height) {\n    var xlinkns = 'http://www.w3.org/1999/xlink';\n    var svgns = 'http://www.w3.org/2000/svg';\n    var element = document.createElementNS(svgns, 'image');\n    element.setAttribute('x', 0);\n    element.setAttribute('y', 0);\n    element.setAttribute('width', width + 'px');\n    element.setAttribute('height', height + 'px');\n    element.setAttributeNS(xlinkns, 'xlink:href', url);\n    return element;\n  };\n  return Image;\n});",
    "\ndefine('common/view/ParticleView',['require','SCENERY/nodes/Node','SCENERY/nodes/Image','SCENERY/nodes/Circle','SCENERY/input/SimpleDragHandler','common/view/ParticleNode','PHET_CORE/inherit'],function (require) {\n  'use strict';\n  var Node = require('SCENERY/nodes/Node');\n  var Image = require('SCENERY/nodes/Image');\n  var Circle = require('SCENERY/nodes/Circle');\n  var SimpleDragHandler = require('SCENERY/input/SimpleDragHandler');\n  var ParticleNode = require('common/view/ParticleNode');\n  var inherit = require('PHET_CORE/inherit');\n  var particleNodes = {};\n  function getParticleNode(particle, mvt) {\n    var id = 'id-' + particle.type + '-' + particle.radius;\n    if (particleNodes[id]) {\n      return particleNodes[id];\n    }\n    var scale = 2;\n    var viewRadius = mvt.modelToViewDeltaX(particle.radius);\n    var scaledRadius = viewRadius * scale;\n    var particleNode = new ParticleNode(particle.type, scaledRadius);\n    var node = new Node({ cursor: 'pointer' });\n    particleNode.toImage(function (im, x, y) {\n      var image = new Image(im, {\n          x: -x,\n          y: -y\n        });\n      image.scale(1 / scale, 1 / scale, true);\n      node.addChild(image);\n    }, scaledRadius + 1, scaledRadius + 1, 2 * (scaledRadius + 1), 2 * (scaledRadius + 1));\n    return node;\n  }\n  function ParticleView(particle, mvt) {\n    Node.call(this, { renderer: 'svg' });\n    var thisParticleView = this;\n    this.particle = particle;\n    this.mvt = mvt;\n    this.addChild(getParticleNode(particle, mvt));\n    particle.positionProperty.link(function (position) {\n      thisParticleView.translation = thisParticleView.mvt.modelToViewPosition(position);\n    });\n    this.addInputListener(new SimpleDragHandler({\n      allowTouchSnag: true,\n      translate: function (translationParams) {\n        particle.setPositionAndDestination(particle.position.plus(mvt.viewToModelDelta(translationParams.delta)));\n        return translationParams.position;\n      },\n      start: function (event, trail) {\n        thisParticleView.particle.userControlled = true;\n      },\n      end: function (event, trail) {\n        thisParticleView.particle.userControlled = false;\n      }\n    }));\n  }\n  inherit(Node, ParticleView);\n  return ParticleView;\n});",
    "\ndefine('common/view/PeriodicTableCell',['require','SCENERY_PHET/PhetFont','SCENERY/nodes/Node','SCENERY/nodes/Text','SCENERY/util/LinearGradient','PHET_CORE/inherit','SCENERY/nodes/Rectangle','common/AtomIdentifier'],function (require) {\n  'use strict';\n  var PhetFont = require('SCENERY_PHET/PhetFont');\n  var Node = require('SCENERY/nodes/Node');\n  var Text = require('SCENERY/nodes/Text');\n  var LinearGradient = require('SCENERY/util/LinearGradient');\n  var inherit = require('PHET_CORE/inherit');\n  var Rectangle = require('SCENERY/nodes/Rectangle');\n  var AtomIdentifier = require('common/AtomIdentifier');\n  var NOMINAL_CELL_DIMENSION = 25;\n  var NOMINAL_FONT_SIZE = 14;\n  function PeriodicTableCell(atomicNumber, dimension, interactive, numberAtom) {\n    Node.call(this);\n    this.normalFill = interactive ? new LinearGradient(0, 0, 0, dimension).addColorStop(0, 'white').addColorStop(1, 'rgb( 240, 240, 240 )') : 'white';\n    this.highlightedFill = 'yellow';\n    this.cell = new Rectangle(0, 0, dimension, dimension, 0, 0, {\n      stroke: 'black',\n      lineWidth: 1,\n      fill: this.normalFill,\n      cursor: interactive ? 'pointer' : null\n    });\n    this.label = new Text(AtomIdentifier.getSymbol(atomicNumber), {\n      font: new PhetFont(NOMINAL_FONT_SIZE * (dimension / NOMINAL_CELL_DIMENSION)),\n      center: this.cell.center\n    });\n    this.cell.addChild(this.label);\n    this.addChild(this.cell);\n    if (interactive) {\n      this.cell.addInputListener({\n        up: function () {\n          numberAtom.protonCount = atomicNumber;\n          numberAtom.neutronCount = AtomIdentifier.getNumNeutronsInMostCommonIsotope(atomicNumber);\n          numberAtom.electronCount = atomicNumber;\n        }\n      });\n    }\n  }\n  inherit(Node, PeriodicTableCell, {\n    setHighlighted: function (highLighted) {\n      this.cell.fill = highLighted ? this.highlightedFill : this.normalFill;\n      this.cell.stroke = highLighted ? 'red' : 'black';\n      this.cell.lineWidth = highLighted ? 2 : 1;\n      this.label.fontWeight = highLighted ? 'bold' : 'normal';\n    }\n  });\n  return PeriodicTableCell;\n});",
    "\ndefine('common/view/PeriodicTableNode',['require','SCENERY/nodes/Node','PHET_CORE/inherit','DOT/Vector2','common/view/PeriodicTableCell'],function (require) {\n  'use strict';\n  var Node = require('SCENERY/nodes/Node');\n  var inherit = require('PHET_CORE/inherit');\n  var Vector2 = require('DOT/Vector2');\n  var PeriodicTableCell = require('common/view/PeriodicTableCell');\n  var POPULATED_CELLS = [\n      [\n        0,\n        17\n      ],\n      [\n        0,\n        1,\n        12,\n        13,\n        14,\n        15,\n        16,\n        17\n      ],\n      [\n        0,\n        1,\n        12,\n        13,\n        14,\n        15,\n        16,\n        17\n      ],\n      [\n        0,\n        1,\n        2,\n        3,\n        4,\n        5,\n        6,\n        7,\n        8,\n        9,\n        10,\n        11,\n        12,\n        13,\n        14,\n        15,\n        16,\n        17\n      ],\n      [\n        0,\n        1,\n        2,\n        3,\n        4,\n        5,\n        6,\n        7,\n        8,\n        9,\n        10,\n        11,\n        12,\n        13,\n        14,\n        15,\n        16,\n        17\n      ],\n      [\n        0,\n        1,\n        2,\n        3,\n        4,\n        5,\n        6,\n        7,\n        8,\n        9,\n        10,\n        11,\n        12,\n        13,\n        14,\n        15,\n        16,\n        17\n      ],\n      [\n        0,\n        1,\n        2,\n        3,\n        4,\n        5,\n        6,\n        7,\n        8,\n        9,\n        10,\n        11,\n        12\n      ]\n    ];\n  var CELL_DIMENSION = 25;\n  function PeriodicTableNode(numberAtom, interactiveMax) {\n    Node.call(this, { renderer: 'svg' });\n    var thisPeriodicTable = this;\n    this.cells = [];\n    var elementIndex = 1;\n    for (var i = 0; i < POPULATED_CELLS.length; i++) {\n      var populatedCellsInRow = POPULATED_CELLS[i];\n      for (var j = 0; j < populatedCellsInRow.length; j++) {\n        var cell = new PeriodicTableCell(elementIndex, CELL_DIMENSION, interactiveMax >= elementIndex, numberAtom);\n        cell.translation = new Vector2(populatedCellsInRow[j] * CELL_DIMENSION, i * CELL_DIMENSION);\n        this.addChild(cell);\n        this.cells.push(cell);\n        elementIndex++;\n      }\n    }\n    var highlightedCell = null;\n    numberAtom.protonCountProperty.link(function (protonCount) {\n      if (highlightedCell !== null) {\n        highlightedCell.setHighlighted(false);\n      }\n      if (protonCount > 0 && protonCount <= thisPeriodicTable.cells.length) {\n        highlightedCell = thisPeriodicTable.cells[protonCount - 1];\n        highlightedCell.moveToFront();\n        highlightedCell.setHighlighted(true);\n      }\n    });\n  }\n  inherit(Node, PeriodicTableNode);\n  return PeriodicTableNode;\n});",
    "\ndefine('buildanatom/view/PeriodicTableAndSymbol',['require','common/AtomIdentifier','SCENERY_PHET/PhetFont','PHET_CORE/inherit','SCENERY/nodes/Node','common/view/PeriodicTableNode','SCENERY/nodes/Rectangle','SCENERY/nodes/Text','DOT/Vector2'],function (require) {\n  'use strict';\n  var AtomIdentifier = require('common/AtomIdentifier');\n  var PhetFont = require('SCENERY_PHET/PhetFont');\n  var inherit = require('PHET_CORE/inherit');\n  var Node = require('SCENERY/nodes/Node');\n  var PeriodicTableNode = require('common/view/PeriodicTableNode');\n  var Rectangle = require('SCENERY/nodes/Rectangle');\n  var Text = require('SCENERY/nodes/Text');\n  var Vector2 = require('DOT/Vector2');\n  var SYMBOL_WIDTH_PROPORTION = 0.2;\n  var SYMBOL_ASPECT_RATIO = 1;\n  function PeriodicTableAndSymbol(numberAtom) {\n    Node.call(this);\n    var periodicTable = new PeriodicTableNode(numberAtom, 0);\n    this.addChild(periodicTable);\n    var symbolRectangle = new Rectangle(0, 0, periodicTable.width * SYMBOL_WIDTH_PROPORTION, periodicTable.width * SYMBOL_WIDTH_PROPORTION / SYMBOL_ASPECT_RATIO, {\n        fill: 'white',\n        stroke: 'black',\n        lineWidth: 2\n      });\n    this.addChild(symbolRectangle);\n    numberAtom.protonCountProperty.link(function (numProtons) {\n      symbolRectangle.removeAllChildren();\n      var symbolText = new Text(AtomIdentifier.getSymbol(numberAtom.protonCount), {\n          font: new PhetFont({\n            size: 48,\n            weight: 'bold'\n          })\n        });\n      symbolText.scale(Math.min(Math.min(symbolRectangle.width * 0.8 / symbolText.width, symbolRectangle.height * 0.8 / symbolText.height), 1));\n      symbolText.center = new Vector2(symbolRectangle.width / 2, symbolRectangle.height / 2);\n      symbolRectangle.addChild(symbolText);\n    });\n    symbolRectangle.centerX = 7.5 / 18 * periodicTable.width;\n    symbolRectangle.top = 0;\n    periodicTable.top = symbolRectangle.bottom - periodicTable.height / 7 * 2.5;\n    periodicTable.left = 0;\n  }\n  inherit(Node, PeriodicTableAndSymbol);\n  return PeriodicTableAndSymbol;\n});",
    "\ndefine('imageLoader',['require'],function (require) {\n  'use strict';\n  return {\n    imageNames: [\n      'baa_atom_icon.png',\n      'baa_element_icon.png',\n      'blue-stopwatch.png',\n      'game_icon.png',\n      'mass_charge_icon.png',\n      'periodic_table_icon.png',\n      'question_mark_icon.png',\n      'reset_button_disabled.png',\n      'reset_button_down.png',\n      'reset_button_over.png',\n      'reset_button_up.png',\n      'scale.png',\n      'symbol_question_icon.png'\n    ]\n  };\n});",
    "\ndefine('SUN/PushButton',['require','SCENERY/input/ButtonListener','PHET_CORE/inherit','SCENERY/nodes/Node','AXON/Property'],function (require) {\n  'use strict';\n  var ButtonListener = require('SCENERY/input/ButtonListener');\n  var inherit = require('PHET_CORE/inherit');\n  var Node = require('SCENERY/nodes/Node');\n  var Property = require('AXON/Property');\n  function PushButton(upNode, overNode, downNode, disabledNode, callback, options) {\n    options = _.extend({\n      cursor: 'pointer',\n      label: 'Button',\n      enabled: true\n    }, options);\n    var thisButton = this;\n    Node.call(thisButton);\n    thisButton._upNode = upNode;\n    thisButton._overNode = overNode;\n    thisButton._downNode = downNode;\n    thisButton._disabledNode = disabledNode;\n    thisButton._state = 'up';\n    thisButton._enabled = new Property(options.enabled);\n    thisButton._listeners = [callback];\n    thisButton.addChild(upNode);\n    thisButton.addChild(overNode);\n    thisButton.addChild(downNode);\n    thisButton.addChild(disabledNode);\n    thisButton.addInputListener(new ButtonListener({\n      up: function () {\n        thisButton._state = 'up';\n        thisButton._update();\n      },\n      over: function () {\n        thisButton._state = 'over';\n        thisButton._update();\n      },\n      down: function () {\n        thisButton._state = 'down';\n        thisButton._update();\n      },\n      out: function () {\n        thisButton._state = 'up';\n        thisButton._update();\n      },\n      fire: function () {\n        if (thisButton._enabled.get()) {\n          thisButton._fire();\n        }\n      }\n    }));\n    thisButton.addPeer('<input type=\"button\" aria-label=\"' + _.escape(options.label) + '\">', { click: thisButton._fire.bind(thisButton) });\n    thisButton._enabled.link(function (enabled) {\n      thisButton.cursor = enabled ? options.cursor : 'default';\n      thisButton._update();\n    });\n    thisButton.mutate(options);\n  }\n  return inherit(Node, PushButton, {\n    addListener: function (listener) {\n      if (this._listeners.indexOf(listener) === -1) {\n        this._listeners.push(listener);\n      }\n    },\n    removeListener: function (listener) {\n      var i = this._listeners.indexOf(listener);\n      if (i !== -1) {\n        this._listeners.splice(i, 1);\n      }\n    },\n    _fire: function () {\n      var copy = this._listeners.slice(0);\n      copy.forEach(function (listener) {\n        listener();\n      });\n    },\n    _update: function () {\n      var enabled = this._enabled.get();\n      this._upNode.visible = this._state === 'up' && enabled;\n      this._downNode.visible = this._state === 'down' && enabled;\n      this._overNode.visible = this._state === 'over' && enabled;\n      this._disabledNode.visible = !enabled;\n    },\n    set enabled(value) {\n      this._enabled.set(value);\n    },\n    get enabled() {\n      return this._enabled.get();\n    }\n  });\n});",
    "\ndefine('common/view/ResetAllButton',['require','imageLoader','SCENERY/nodes/Image','PHET_CORE/inherit','SUN/PushButton','DOT/Vector2'],function (require) {\n  'use strict';\n  var imageLoader = require('imageLoader');\n  var Image = require('SCENERY/nodes/Image');\n  var inherit = require('PHET_CORE/inherit');\n  var PushButton = require('SUN/PushButton');\n  var Vector2 = require('DOT/Vector2');\n  var radius = 33;\n  var radiusSquared = radius * radius;\n  var center = new Vector2(radius, radius);\n  function ResetAllButton(callback, options) {\n    PushButton.call(this, new ResetAllImage(imageLoader.getImage('reset_button_up.png')), new ResetAllImage(imageLoader.getImage('reset_button_over.png')), new ResetAllImage(imageLoader.getImage('reset_button_down.png')), new ResetAllImage(imageLoader.getImage('reset_button_disabled.png')), callback, options);\n  }\n  function ResetAllImage(image) {\n    Image.call(this, image);\n  }\n  inherit(Image, ResetAllImage, {\n    containsPointSelf: function (point) {\n      return point.distanceSquared(center) <= radiusSquared;\n    }\n  });\n  return inherit(PushButton, ResetAllButton);\n});",
    "\ndefine('JOIST/ScreenView',['require','SCENERY/nodes/Node','PHET_CORE/inherit','DOT/Bounds2','SCENERY/nodes/Path','KITE/Shape'],function (require) {\n  'use strict';\n  var Node = require('SCENERY/nodes/Node');\n  var inherit = require('PHET_CORE/inherit');\n  var Bounds2 = require('DOT/Bounds2');\n  var Path = require('SCENERY/nodes/Path');\n  var Shape = require('KITE/Shape');\n  function ScreenView(options) {\n    Node.call(this, options);\n    if (window.phetcommon.getQueryParameter('dev')) {\n      this.addChild(new Path(Shape.bounds(this.layoutBounds), {\n        stroke: 'red',\n        lineWidth: 3,\n        pickable: false\n      }));\n    }\n  }\n  inherit(Node, ScreenView, {\n    layoutBounds: new Bounds2(0, 0, 768, 504),\n    getLayoutScale: function (width, height) {\n      return Math.min(width / this.layoutBounds.width, height / this.layoutBounds.height);\n    },\n    layout: function (width, height) {\n      this.resetTransform();\n      var scale = this.getLayoutScale(width, height);\n      this.setScaleMagnitude(scale);\n      if (scale === width / this.layoutBounds.width) {\n        this.translate(0, (height - this.layoutBounds.height * scale) / 2 / scale);\n      } else if (scale === height / this.layoutBounds.height) {\n        this.translate((width - this.layoutBounds.width * scale) / 2 / scale, 0);\n      }\n    }\n  });\n  return ScreenView;\n});",
    "\ndefine('SCENERY/nodes/VBox',['require','SCENERY/scenery','SCENERY/nodes/Node','SCENERY/util/Util'],function (require) {\n  'use strict';\n  var scenery = require('SCENERY/scenery');\n  var Node = require('SCENERY/nodes/Node');\n  var objectCreate = require('SCENERY/util/Util').objectCreate;\n  scenery.VBox = function VBox(options) {\n    this.options = options = _.extend({\n      spacing: function () {\n        return 0;\n      },\n      align: 'center'\n    }, options);\n    if (typeof options.spacing === 'number') {\n      var spacingConstant = options.spacing;\n      options.spacing = function () {\n        return spacingConstant;\n      };\n    }\n    Node.call(this, options);\n    this.updateLayout();\n    if (options) {\n      this.mutate(options);\n    }\n  };\n  var VBox = scenery.VBox;\n  VBox.prototype = objectCreate(Node.prototype);\n  VBox.prototype.updateLayout = function () {\n    var minX = _.min(_.map(this.children, function (child) {\n        return child.left;\n      }));\n    var maxX = _.max(_.map(this.children, function (child) {\n        return child.left + child.width;\n      }));\n    var centerX = (maxX + minX) / 2;\n    var y = 0;\n    for (var i = 0; i < this.children.length; i++) {\n      var child = this.children[i];\n      child.top = y;\n      if (this.options.align === 'left') {\n        child.left = minX;\n      } else if (this.options.align === 'right') {\n        child.right = maxX;\n      } else {\n        child.centerX = centerX;\n      }\n      y += child.height + this.options.spacing(child, this.children[i + 1]);\n    }\n  };\n  VBox.prototype.constructor = VBox;\n  return VBox;\n});",
    "\ndefine('SCENERY/nodes/DOM',['require','PHET_CORE/inherit','PHET_CORE/escapeHTML','DOT/Bounds2','SCENERY/scenery','SCENERY/nodes/Node','SCENERY/layers/Renderer','SCENERY/util/Util','SCENERY/util/Util'],function (require) {\n  'use strict';\n  var inherit = require('PHET_CORE/inherit');\n  var escapeHTML = require('PHET_CORE/escapeHTML');\n  var Bounds2 = require('DOT/Bounds2');\n  var scenery = require('SCENERY/scenery');\n  var Node = require('SCENERY/nodes/Node');\n  var Renderer = require('SCENERY/layers/Renderer');\n  var objectCreate = require('SCENERY/util/Util').objectCreate;\n  require('SCENERY/util/Util');\n  scenery.DOM = function DOM(element, options) {\n    options = options || {};\n    this._interactive = false;\n    if (element && element.jquery) {\n      element = element[0];\n    }\n    this._container = document.createElement('div');\n    this._$container = $(this._container);\n    this._$container.css('position', 'absolute');\n    this._$container.css('left', 0);\n    this._$container.css('top', 0);\n    this.invalidateDOMLock = false;\n    options.element = element;\n    Node.call(this, options);\n  };\n  var DOM = scenery.DOM;\n  inherit(Node, DOM, {\n    allowsMultipleDOMInstances: false,\n    calculateDOMBounds: function () {\n      var $element = $(this._element);\n      return new Bounds2(0, 0, $element.width(), $element.height());\n    },\n    createTemporaryContainer: function () {\n      var temporaryContainer = document.createElement('div');\n      $(temporaryContainer).css({\n        display: 'hidden',\n        padding: '0 !important',\n        margin: '0 !important',\n        position: 'absolute',\n        left: 0,\n        top: 0,\n        width: 65535,\n        height: 65535\n      });\n      return temporaryContainer;\n    },\n    invalidateDOM: function () {\n      if (this.invalidateDOMLock) {\n        return;\n      }\n      this.invalidateDOMLock = true;\n      var temporaryContainer = this.createTemporaryContainer();\n      this._container.removeChild(this._element);\n      temporaryContainer.appendChild(this._element);\n      document.body.appendChild(temporaryContainer);\n      var selfBounds = this.calculateDOMBounds();\n      this.invalidateSelf(selfBounds);\n      this._$container.width(selfBounds.getWidth());\n      this._$container.height(selfBounds.getHeight());\n      document.body.removeChild(temporaryContainer);\n      temporaryContainer.removeChild(this._element);\n      this._container.appendChild(this._element);\n      this.invalidateDOMLock = false;\n    },\n    getDOMElement: function () {\n      return this._container;\n    },\n    updateDOMElement: function (container) {\n    },\n    updateCSSTransform: function (transform, element) {\n      scenery.Util.applyCSSTransform(transform.getMatrix(), this._container);\n    },\n    isPainted: function () {\n      return true;\n    },\n    setElement: function (element) {\n      if (this._element !== element) {\n        if (this._element) {\n          this._container.removeChild(this._element);\n        }\n        this._element = element;\n        this._$element = $(element);\n        this._container.appendChild(this._element);\n        this.invalidateDOM();\n      }\n      return this;\n    },\n    getElement: function () {\n      return this._element;\n    },\n    setInteractive: function (interactive) {\n      if (this._interactive !== interactive) {\n        this._interactive = interactive;\n      }\n    },\n    isInteractive: function () {\n      return this._interactive;\n    },\n    set element(value) {\n      this.setElement(value);\n    },\n    get element() {\n      return this.getElement();\n    },\n    set interactive(value) {\n      this.setInteractive(value);\n    },\n    get interactive() {\n      return this.isInteractive();\n    },\n    getBasicConstructor: function (propLines) {\n      return 'new scenery.DOM( $( \\'' + escapeHTML(this._container.innerHTML.replace(/'/g, '\\\\\\'')) + '\\' ), {' + propLines + '} )';\n    },\n    getPropString: function (spaces, includeChildren) {\n      var result = Node.prototype.getPropString.call(this, spaces, includeChildren);\n      if (this.interactive) {\n        if (result) {\n          result += ',\\n';\n        }\n        result += spaces + 'interactive: true';\n      }\n      return result;\n    }\n  });\n  DOM.prototype._mutatorKeys = [\n    'element',\n    'interactive'\n  ].concat(Node.prototype._mutatorKeys);\n  DOM.prototype._supportedRenderers = [Renderer.DOM];\n  return DOM;\n});",
    "\ndefine('SCENERY/nodes/HBox',['require','SCENERY/scenery','SCENERY/nodes/Node','SCENERY/util/Util'],function (require) {\n  'use strict';\n  var scenery = require('SCENERY/scenery');\n  var Node = require('SCENERY/nodes/Node');\n  var objectCreate = require('SCENERY/util/Util').objectCreate;\n  scenery.HBox = function HBox(options) {\n    this.options = options = _.extend({\n      spacing: function () {\n        return 0;\n      },\n      align: 'center'\n    }, options);\n    if (typeof options.spacing === 'number') {\n      var spacingConstant = options.spacing;\n      options.spacing = function () {\n        return spacingConstant;\n      };\n    }\n    Node.call(this, options);\n    this.updateLayout();\n    if (options) {\n      this.mutate(options);\n    }\n  };\n  var HBox = scenery.HBox;\n  HBox.prototype = objectCreate(Node.prototype);\n  HBox.prototype.updateLayout = function () {\n    var minY = _.min(_.map(this.children, function (child) {\n        return child.top;\n      }));\n    var maxY = _.max(_.map(this.children, function (child) {\n        return child.top + child.height;\n      }));\n    var centerY = (maxY + minY) / 2;\n    var x = 0;\n    for (var i = 0; i < this.children.length; i++) {\n      var child = this.children[i];\n      child.left = x;\n      if (this.options.align === 'top') {\n        child.top = minY;\n      } else if (this.options.align === 'bottom') {\n        child.bottom = maxY;\n      } else {\n        child.centerY = centerY;\n      }\n      x += child.width + this.options.spacing(child, this.children[i + 1]);\n    }\n  };\n  HBox.prototype.constructor = HBox;\n  return HBox;\n});",
    "\ndefine('PHET_CORE/collect',['require'],function (require) {\n  'use strict';\n  return function collect(iterate) {\n    var result = [];\n    iterate(function (ob) {\n      result.push(ob);\n    });\n    return result;\n  };\n});",
    "\ndefine('SCENERY/util/AccessibilityPeer',['require','PHET_CORE/inherit','SCENERY/scenery'],function (require) {\n  'use strict';\n  var inherit = require('PHET_CORE/inherit');\n  var scenery = require('SCENERY/scenery');\n  var AccessibilityPeer = scenery.AccessibilityPeer = function AccessibilityPeer(instance, element, options) {\n      var peer = this;\n      options = options || {};\n      options.tabIndex = options.tabIndex || 1;\n      this.element = typeof element === 'string' ? $(element)[0] : element;\n      if (options.label) {\n        this.peerElement = document.createElement('div');\n        this.element.id = 'peer-' + instance.trail.getUniqueId();\n        var label = document.createElement('label');\n        label.appendChild(document.createTextNode(options.label));\n        label.setAttribute('for', this.element.id);\n        this.peerElement.appendChild(label);\n        this.peerElement.appendChild(this.element);\n      } else {\n        this.peerElement = this.element;\n      }\n      this.instance = instance;\n      this.trail = instance.trail;\n      this.element.setAttribute('tabindex', options.tabIndex);\n      this.element.style.position = 'absolute';\n      var scene = instance.getScene();\n      this.clickListener = function PeerClickListener(event) {\n        sceneryAccessibilityLog && sceneryAccessibilityLog('peer click on ' + instance.toString() + ': ' + instance.getNode().constructor.name);\n        if (options.click) {\n          options.click(event);\n        }\n      };\n      this.focusListener = function PeerFocusListener(event) {\n        sceneryAccessibilityLog && sceneryAccessibilityLog('peer focused: ' + instance.toString() + ': ' + instance.getNode().constructor.name);\n        scene.focusPeer(peer);\n      };\n      this.blurListener = function PeerBlurListener(event) {\n        sceneryAccessibilityLog && sceneryAccessibilityLog('peer blurred: ' + instance.toString() + ': ' + instance.getNode().constructor.name);\n        scene.blurPeer(peer);\n      };\n      this.element.addEventListener('click', this.clickListener);\n      this.element.addEventListener('focus', this.focusListener);\n      this.element.addEventListener('blur', this.blurListener);\n      this.keepPeerBoundsInSync = true;\n      if (this.keepPeerBoundsInSync) {\n        this.boundsSyncListener = this.syncBounds.bind(this);\n        instance.getNode().addEventListener('bounds', this.boundsSyncListener);\n        this.syncBounds();\n        instance.getScene().addEventListener('resize', this.boundsSyncListener);\n        window.setTimeout(this.syncBounds.bind(this), 30);\n      }\n    };\n  AccessibilityPeer.prototype = {\n    constructor: AccessibilityPeer,\n    dispose: function () {\n      this.element.removeEventListener('click', this.clickListener);\n      this.element.removeEventListener('focus', this.focusListener);\n      this.element.removeEventListener('blur', this.blurListener);\n      if (this.keepPeerBoundsInSync) {\n        this.instance.getNode().removeEventListener('bounds', this.boundsSyncListener);\n        this.instance.getScene().removeEventListener('resize', this.boundsSyncListener);\n      }\n    },\n    getGlobalBounds: function () {\n      return this.trail.parentToGlobalBounds(this.trail.lastNode().getBounds()).roundedOut();\n    },\n    syncBounds: function () {\n      var globalBounds = this.getGlobalBounds();\n      this.element.style.left = globalBounds.x + 'px';\n      this.element.style.top = globalBounds.y + 'px';\n      this.element.style.width = globalBounds.width + 'px';\n      this.element.style.height = globalBounds.height + 'px';\n    }\n  };\n  return AccessibilityPeer;\n});",
    "\ndefine('SCENERY/util/LiveRegion',['require','PHET_CORE/inherit','PHET_CORE/escapeHTML','SCENERY/scenery'],function (require) {\n  'use strict';\n  var inherit = require('PHET_CORE/inherit');\n  var escapeHTML = require('PHET_CORE/escapeHTML');\n  var scenery = require('SCENERY/scenery');\n  var LiveRegion = scenery.LiveRegion = function LiveRegion(instance, property, options) {\n      var liveRegion = this;\n      this.property = property;\n      options = options || {};\n      options.tabIndex = options.tabIndex || 1;\n      this.element = document.createElement('div');\n      this.element.setAttribute('aria-live', 'polite');\n      this.element.setAttribute('role', 'region');\n      this.textNode = document.createTextNode('');\n      this.element.appendChild(this.textNode);\n      this.listener = function (newText) {\n        liveRegion.element.removeChild(liveRegion.textNode);\n        liveRegion.textNode = document.createTextNode(newText);\n        liveRegion.element.appendChild(liveRegion.textNode);\n      };\n      property.link(this.listener);\n    };\n  LiveRegion.prototype = {\n    constructor: scenery.LiveRegion,\n    dispose: function () {\n      this.property.unlink(this.listener);\n    }\n  };\n  return LiveRegion;\n});",
    "\ndefine('SCENERY/util/Instance',['require','SCENERY/scenery','SCENERY/util/AccessibilityPeer','SCENERY/util/LiveRegion'],function (require) {\n  'use strict';\n  var scenery = require('SCENERY/scenery');\n  require('SCENERY/util/AccessibilityPeer');\n  require('SCENERY/util/LiveRegion');\n  var accessibility = window.has && window.has('scenery.accessibility');\n  scenery.Instance = function Instance(trail, layer, parent) {\n    this.trail = trail;\n    this.layer = layer;\n    this.oldLayer = layer;\n    this.data = {};\n    this.parent = parent;\n    this.children = [];\n    this.peers = [];\n    this.liveRegions = [];\n    this.startAffectedLayer = null;\n    this.endAffectedLayer = null;\n    trail.setImmutable();\n    if (accessibility) {\n      this.addPeers();\n      this.addLiveRegions();\n    }\n    phetAllocation && phetAllocation('Instance');\n  };\n  var Instance = scenery.Instance;\n  Instance.prototype = {\n    constructor: Instance,\n    getScene: function () {\n      return this.trail.rootNode();\n    },\n    get scene() {\n      return this.getScene();\n    },\n    getNode: function () {\n      return this.trail.lastNode();\n    },\n    get node() {\n      return this.getNode();\n    },\n    changeLayer: function (newLayer) {\n      if (newLayer !== this.layer) {\n        sceneryLayerLog && sceneryLayerLog('changing instance ' + this.trail.toString() + ' to layer ' + (newLayer ? '#' + newLayer.id : 'null'));\n        this.layer && (this.layer._instanceCount -= 1);\n        this.layer = newLayer;\n        this.layer && (this.layer._instanceCount += 1);\n      }\n    },\n    updateLayer: function () {\n      if (this.layer !== this.oldLayer) {\n        this.reindex();\n        if (sceneryLayerLog) {\n          if (this.oldLayer && this.layer) {\n            sceneryLayerLog('moving instance ' + this.trail.toString() + ' from layer #' + this.oldLayer.id + ' to layer #' + this.layer.id);\n          } else if (this.layer) {\n            sceneryLayerLog('adding instance ' + this.trail.toString() + ' to layer #' + this.layer.id);\n          } else {\n            sceneryLayerLog('remove instance ' + this.trail.toString() + ' from layer #' + this.oldLayer.id);\n          }\n        }\n        if (this.oldLayer) {\n          this.oldLayer.removeInstance(this);\n        }\n        if (this.layer) {\n          this.layer.addInstance(this);\n        }\n        this.oldLayer = this.layer;\n      }\n    },\n    createChild: function (childNode, index) {\n      var childTrail = this.trail.copy().addDescendant(childNode);\n      var childInstance = new scenery.Instance(childTrail, null, this);\n      sceneryLayerLog && sceneryLayerLog('Instance.createChild: ' + childInstance.toString());\n      this.insertInstance(index, childInstance);\n      childInstance.getNode().addInstance(childInstance);\n      return childInstance;\n    },\n    addInstance: function (instance) {\n      sceneryAssert && sceneryAssert(instance, 'Instance.addInstance cannot have falsy parameter');\n      this.children.push(instance);\n    },\n    insertInstance: function (index, instance) {\n      sceneryAssert && sceneryAssert(instance, 'Instance.insert cannot have falsy instance parameter');\n      sceneryAssert && sceneryAssert(index >= 0 && index <= this.children.length, 'Instance.insert has bad index ' + index + ' for length ' + this.children.length);\n      this.children.splice(index, 0, instance);\n    },\n    removeInstance: function (index) {\n      sceneryAssert && sceneryAssert(typeof index === 'number');\n      this.children.splice(index, 1);\n    },\n    reindex: function () {\n      this.trail.reindex();\n    },\n    dispose: function () {\n      if (this.layer) {\n        this.changeLayer(null);\n        this.updateLayer();\n      }\n      this.parent = null;\n      this.children.length = 0;\n      this.getNode().removeInstance(this);\n      if (accessibility) {\n        this.removePeers();\n        this.removeLiveRegions();\n      }\n    },\n    equals: function (other) {\n      sceneryAssert && sceneryAssert(this === other === this.trail.equals(other.trail), 'We assume a 1-1 mapping from trails to instances');\n      return this === other;\n    },\n    compare: function (other) {\n      return this.trail.compare(other.trail);\n    },\n    getLayerString: function () {\n      return this.layer ? this.layer.getName() + '#' + this.layer.getId() : '-';\n    },\n    getTrailString: function () {\n      return this.trail.toString();\n    },\n    toString: function () {\n      return '{' + this.getTrailString() + ', ' + this.getLayerString() + '}';\n    },\n    getAffectedLayers: function () {\n      this.reindex();\n      return this.getScene().affectedLayers(this.trail);\n    },\n    addPeers: function () {\n      var node = this.getNode();\n      var scene = this.getScene();\n      var len = node._peers.length;\n      if (len) {\n        for (var i = 0; i < len; i++) {\n          var desc = node._peers[i];\n          var peer = new scenery.AccessibilityPeer(this, desc.element, desc.options);\n          scene.addPeer(peer);\n          this.peers.push(peer);\n        }\n      }\n    },\n    removePeers: function () {\n      var scene = this.getScene();\n      var i = this.peers.length;\n      while (i--) {\n        var peer = this.peers[i];\n        scene.removePeer(peer);\n        peer.dispose();\n      }\n      this.peers.length = 0;\n    },\n    addLiveRegions: function () {\n      var thisInstance = this;\n      var node = this.getNode();\n      var scene = this.getScene();\n      if (node._liveRegions.length) {\n        _.each(node._liveRegions, function (item) {\n          var liveRegion = new scenery.LiveRegion(thisInstance, item.property, item.options);\n          scene.addLiveRegion(liveRegion);\n          thisInstance.liveRegions.push(liveRegion);\n        });\n      }\n    },\n    removeLiveRegions: function () {\n      var scene = this.getScene();\n      _.each(this.liveRegions, function (liveRegion) {\n        scene.removeLiveRegion(liveRegion);\n        liveRegion.dispose();\n      });\n      this.peers.length = 0;\n    },\n    notifyVisibilityChange: function () {\n      sceneryEventLog && sceneryEventLog('notifyVisibilityChange: ' + this.trail.toString() + ', ' + this.getLayerString());\n      var affectedLayers = this.getAffectedLayers();\n      var i = affectedLayers.length;\n      while (i--) {\n        affectedLayers[i].notifyVisibilityChange(this);\n      }\n    },\n    notifyOpacityChange: function () {\n      sceneryEventLog && sceneryEventLog('notifyOpacityChange: ' + this.trail.toString() + ', ' + this.getLayerString());\n      var affectedLayers = this.getAffectedLayers();\n      var i = affectedLayers.length;\n      while (i--) {\n        affectedLayers[i].notifyOpacityChange(this);\n      }\n    },\n    notifyBeforeSelfChange: function () {\n      sceneryEventLog && sceneryEventLog('notifyBeforeSelfChange: ' + this.trail.toString() + ', ' + this.getLayerString());\n      this.layer.notifyBeforeSelfChange(this);\n    },\n    notifyBeforeSubtreeChange: function () {\n      sceneryEventLog && sceneryEventLog('notifyBeforeSubtreeChange: ' + this.trail.toString() + ', ' + this.getLayerString());\n      var affectedLayers = this.getAffectedLayers();\n      var i = affectedLayers.length;\n      while (i--) {\n        affectedLayers[i].notifyBeforeSubtreeChange(this);\n      }\n    },\n    notifyDirtySelfPaint: function () {\n      sceneryEventLog && sceneryEventLog('notifyDirtySelfPaint: ' + this.trail.toString() + ', ' + this.getLayerString());\n      sceneryAssert && sceneryAssert(this.getNode().isPainted(), 'Instance needs to be painted for notifyDirtySelfPaint');\n      this.layer.notifyDirtySelfPaint(this);\n    },\n    notifyDirtySubtreePaint: function () {\n      sceneryEventLog && sceneryEventLog('notifyDirtySubtreePaint: ' + this.trail.toString() + ', ' + this.getLayerString());\n      var affectedLayers = this.getAffectedLayers();\n      var i = affectedLayers.length;\n      while (i--) {\n        affectedLayers[i].notifyDirtySubtreePaint(this);\n      }\n    },\n    notifyDirtySubtreeBounds: function () {\n      sceneryEventLog && sceneryEventLog('notifyDirtySubtreeBounds: ' + this.trail.toString() + ', ' + this.getLayerString());\n      var affectedLayers = this.getAffectedLayers();\n      var i = affectedLayers.length;\n      while (i--) {\n        affectedLayers[i].notifyDirtySubtreeBounds(this);\n      }\n    },\n    notifyTransformChange: function () {\n      sceneryEventLog && sceneryEventLog('notifyTransformChange: ' + this.trail.toString() + ', ' + this.getLayerString());\n      var affectedLayers = this.getAffectedLayers();\n      var i = affectedLayers.length;\n      while (i--) {\n        affectedLayers[i].notifyTransformChange(this);\n      }\n    },\n    notifyBoundsAccuracyChange: function () {\n      sceneryEventLog && sceneryEventLog('notifyBoundsAccuracyChange: ' + this.trail.toString() + ', ' + this.getLayerString());\n      this.layer.notifyBoundsAccuracyChange(this);\n    },\n    notifyStitch: function (match) {\n      sceneryEventLog && sceneryEventLog('notifyStitch: ' + this.trail.toString() + ' match:' + match + ', ' + this.getLayerString());\n      this.getScene().stitch(match);\n    },\n    markForLayerRefresh: function () {\n      sceneryEventLog && sceneryEventLog('markForLayerRefresh: ' + this.trail.toString() + ', ' + this.getLayerString());\n      this.getScene().markSceneForLayerRefresh(this);\n    },\n    markForInsertion: function (child, index) {\n      sceneryEventLog && sceneryEventLog('markForInsertion: ' + this.trail.toString() + ' child:' + child.id + ', index: ' + index + ', ' + this.getLayerString());\n      this.reindex();\n      this.getScene().markSceneForInsertion(this, child, index);\n    },\n    markForRemoval: function (child, index) {\n      sceneryEventLog && sceneryEventLog('markForRemoval: ' + this.trail.toString() + ' child:' + child.id + ', index: ' + index + ', ' + this.getLayerString());\n      this.reindex();\n      this.getScene().markSceneForRemoval(this, child, index);\n    }\n  };\n  return Instance;\n});",
    "\ndefine('SCENERY/util/RenderInterval',['require','SCENERY/scenery','SCENERY/util/Trail'],function (require) {\n  'use strict';\n  var scenery = require('SCENERY/scenery');\n  require('SCENERY/util/Trail');\n  scenery.RenderInterval = function RenderInterval(start, end) {\n    sceneryAssert && sceneryAssert(!start || !end || start.compare(end) <= 0, 'RenderInterval parameters must not be out of order');\n    this.start = start;\n    this.end = end;\n  };\n  var RenderInterval = scenery.RenderInterval;\n  RenderInterval.compareDisjoint = function (x, y) {\n    if (!x.start && !y.start) {\n      return 0;\n    }\n    if (!x.start || !y.start) {\n      return x.start ? 1 : -1;\n    }\n    return x.start.compare(y.start);\n  };\n  RenderInterval.prototype = {\n    constructor: RenderInterval,\n    reindex: function () {\n      this.start && this.start.reindex();\n      this.end && this.end.reindex();\n    },\n    isValidExclusive: function () {\n      return !this.start || !this.end || this.start.compare(this.end) < 0;\n    },\n    exclusiveUnionable: function (interval) {\n      sceneryAssert && sceneryAssert(this.isValidExclusive(), 'exclusiveUnionable requires exclusive intervals');\n      sceneryAssert && sceneryAssert(interval.isValidExclusive(), 'exclusiveUnionable requires exclusive intervals');\n      return (!this.start || !interval.end || this.start.compare(interval.end) === -1) && (!this.end || !interval.start || this.end.compare(interval.start) === 1);\n    },\n    exclusiveContains: function (trail) {\n      sceneryAssert && sceneryAssert(trail);\n      return (!this.start || this.start.compare(trail) < 0) && (!this.end || this.end.compare(trail) > 0);\n    },\n    union: function (interval) {\n      var thisA = !this.start || interval.start && this.start.compare(interval.start) === -1;\n      var thisB = !this.end || interval.end && this.end.compare(interval.end) === 1;\n      return new RenderInterval(thisA ? this.start : interval.start, thisB ? this.end : interval.end);\n    },\n    toString: function () {\n      return '[' + (this.start ? this.start.toString() : this.start) + ',' + (this.end ? this.end.toString() : this.end) + ']';\n    }\n  };\n  return RenderInterval;\n});",
    "\ndefine('SCENERY/input/Pointer',['require','SCENERY/scenery'],function (require) {\n  'use strict';\n  var scenery = require('SCENERY/scenery');\n  scenery.Pointer = function Pointer() {\n    this.listeners = [];\n    phetAllocation && phetAllocation('Pointer');\n  };\n  var Pointer = scenery.Pointer;\n  Pointer.prototype = {\n    constructor: Pointer,\n    addInputListener: function (listener) {\n      sceneryAssert && sceneryAssert(!_.contains(this.listeners, listener));\n      this.listeners.push(listener);\n    },\n    removeInputListener: function (listener) {\n      var index = _.indexOf(this.listeners, listener);\n      sceneryAssert && sceneryAssert(index !== -1);\n      this.listeners.splice(index, 1);\n    }\n  };\n  return Pointer;\n});",
    "\ndefine('SCENERY/input/Mouse',['require','PHET_CORE/inherit','SCENERY/scenery','SCENERY/input/Pointer'],function (require) {\n  'use strict';\n  var inherit = require('PHET_CORE/inherit');\n  var scenery = require('SCENERY/scenery');\n  var Pointer = require('SCENERY/input/Pointer');\n  scenery.Mouse = function Mouse() {\n    Pointer.call(this);\n    this.point = null;\n    this.leftDown = false;\n    this.middleDown = false;\n    this.rightDown = false;\n    this.isMouse = true;\n    this.trail = null;\n    this.type = 'mouse';\n  };\n  var Mouse = scenery.Mouse;\n  inherit(Pointer, Mouse, {\n    down: function (point, event) {\n      this.point = point;\n      switch (event.button) {\n      case 0:\n        this.leftDown = true;\n        break;\n      case 1:\n        this.middleDown = true;\n        break;\n      case 2:\n        this.rightDown = true;\n        break;\n      }\n    },\n    up: function (point, event) {\n      this.point = point;\n      switch (event.button) {\n      case 0:\n        this.leftDown = false;\n        break;\n      case 1:\n        this.middleDown = false;\n        break;\n      case 2:\n        this.rightDown = false;\n        break;\n      }\n    },\n    move: function (point, event) {\n      this.point = point;\n    },\n    over: function (point, event) {\n      this.point = point;\n    },\n    out: function (point, event) {\n      this.point = null;\n    },\n    toString: function () {\n      return 'Mouse';\n    }\n  });\n  return Mouse;\n});",
    "\ndefine('SCENERY/input/Touch',['require','PHET_CORE/inherit','SCENERY/scenery','SCENERY/input/Pointer'],function (require) {\n  'use strict';\n  var inherit = require('PHET_CORE/inherit');\n  var scenery = require('SCENERY/scenery');\n  var Pointer = require('SCENERY/input/Pointer');\n  scenery.Touch = function Touch(id, point, event) {\n    Pointer.call(this);\n    this.id = id;\n    this.point = point;\n    this.isTouch = true;\n    this.trail = null;\n    this.type = 'touch';\n  };\n  var Touch = scenery.Touch;\n  inherit(Pointer, Touch, {\n    move: function (point, event) {\n      this.point = point;\n    },\n    end: function (point, event) {\n      this.point = point;\n    },\n    cancel: function (point, event) {\n      this.point = point;\n    },\n    toString: function () {\n      return 'Touch#' + this.id;\n    }\n  });\n  return Touch;\n});",
    "\ndefine('SCENERY/input/Pen',['require','PHET_CORE/inherit','SCENERY/scenery','SCENERY/input/Pointer'],function (require) {\n  'use strict';\n  var inherit = require('PHET_CORE/inherit');\n  var scenery = require('SCENERY/scenery');\n  var Pointer = require('SCENERY/input/Pointer');\n  scenery.Pen = function Pen(id, point, event) {\n    Pointer.call(this);\n    this.id = id;\n    this.point = point;\n    this.isPen = true;\n    this.trail = null;\n    this.type = 'pen';\n  };\n  var Pen = scenery.Pen;\n  inherit(Pointer, Pen, {\n    move: function (point, event) {\n      this.point = point;\n    },\n    end: function (point, event) {\n      this.point = point;\n    },\n    cancel: function (point, event) {\n      this.point = point;\n    },\n    toString: function () {\n      return 'Pen#' + this.id;\n    }\n  });\n  return Pen;\n});",
    "\ndefine('SCENERY/input/Key',['require','PHET_CORE/inherit','SCENERY/scenery','SCENERY/input/Pointer'],function (require) {\n  'use strict';\n  var inherit = require('PHET_CORE/inherit');\n  var scenery = require('SCENERY/scenery');\n  var Pointer = require('SCENERY/input/Pointer');\n  scenery.Key = function Key(event) {\n    Pointer.call(this);\n    this.event = event;\n    this.isKey = true;\n    this.trail = null;\n    this.type = 'key';\n  };\n  var Key = scenery.Key;\n  inherit(Pointer, Key, {});\n  return Key;\n});",
    "\ndefine('SCENERY/input/Event',['require','SCENERY/scenery'],function (require) {\n  'use strict';\n  var scenery = require('SCENERY/scenery');\n  scenery.Event = function Event(args) {\n    sceneryAssert && sceneryAssert(args.trail && args.type && args.pointer && args.target, 'Missing required scenery.Event argument');\n    this.handled = false;\n    this.aborted = false;\n    this.trail = args.trail;\n    this.type = args.type;\n    this.pointer = args.pointer;\n    this.domEvent = args.domEvent;\n    this.currentTarget = args.currentTarget;\n    this.target = args.target;\n  };\n  var Event = scenery.Event;\n  Event.prototype = {\n    constructor: Event,\n    handle: function () {\n      this.handled = true;\n    },\n    abort: function () {\n      this.handled = true;\n      this.aborted = true;\n    }\n  };\n  return Event;\n});",
    "\ndefine('SCENERY/input/Input',['require','SCENERY/scenery','SCENERY/util/Trail','SCENERY/input/Mouse','SCENERY/input/Touch','SCENERY/input/Pen','SCENERY/input/Key','SCENERY/input/Event'],function (require) {\n  'use strict';\n  var scenery = require('SCENERY/scenery');\n  require('SCENERY/util/Trail');\n  require('SCENERY/input/Mouse');\n  require('SCENERY/input/Touch');\n  require('SCENERY/input/Pen');\n  require('SCENERY/input/Key');\n  require('SCENERY/input/Event');\n  scenery.Input = function Input(scene, listenerTarget, batchDOMEvents) {\n    this.scene = scene;\n    this.listenerTarget = listenerTarget;\n    this.batchDOMEvents = batchDOMEvents;\n    this.batchedCallbacks = [];\n    this.mouse = new scenery.Mouse();\n    this.pointers = [this.mouse];\n    this.listenerReferences = [];\n    this.eventLog = [];\n    this.logEvents = false;\n  };\n  var Input = scenery.Input;\n  Input.prototype = {\n    constructor: Input,\n    addPointer: function (pointer) {\n      this.pointers.push(pointer);\n    },\n    removePointer: function (pointer) {\n      for (var i = this.pointers.length - 1; i >= 0; i--) {\n        if (this.pointers[i] === pointer) {\n          this.pointers.splice(i, 1);\n        }\n      }\n    },\n    findTouchById: function (id) {\n      var i = this.pointers.length;\n      while (i--) {\n        var pointer = this.pointers[i];\n        if (pointer.id === id) {\n          return pointer;\n        }\n      }\n      return undefined;\n    },\n    findKeyByEvent: function (event) {\n      sceneryAssert && sceneryAssert(event.keyCode && event.charCode, 'Assumes the KeyboardEvent has keyCode and charCode properties');\n      var result = _.find(this.pointers, function (pointer) {\n          return pointer.keyCode === event.keyCode && pointer.charCode === event.charCode;\n        });\n      return result;\n    },\n    mouseDown: function (point, event) {\n      if (this.logEvents) {\n        this.eventLog.push('mouseDown(' + Input.serializeVector2(point) + ',' + Input.serializeDomEvent(event) + ');');\n      }\n      this.mouse.down(point, event);\n      this.downEvent(this.mouse, event);\n    },\n    mouseUp: function (point, event) {\n      if (this.logEvents) {\n        this.eventLog.push('mouseUp(' + Input.serializeVector2(point) + ',' + Input.serializeDomEvent(event) + ');');\n      }\n      this.mouse.up(point, event);\n      this.upEvent(this.mouse, event);\n    },\n    mouseUpImmediate: function (point, event) {\n      if (this.logEvents) {\n        this.eventLog.push('mouseUpImmediate(' + Input.serializeVector2(point) + ',' + Input.serializeDomEvent(event) + ');');\n      }\n      this.upImmediateEvent(this.mouse, event);\n    },\n    mouseMove: function (point, event) {\n      if (this.logEvents) {\n        this.eventLog.push('mouseMove(' + Input.serializeVector2(point) + ',' + Input.serializeDomEvent(event) + ');');\n      }\n      this.mouse.move(point, event);\n      this.moveEvent(this.mouse, event);\n    },\n    mouseOver: function (point, event) {\n      if (this.logEvents) {\n        this.eventLog.push('mouseOver(' + Input.serializeVector2(point) + ',' + Input.serializeDomEvent(event) + ');');\n      }\n      this.mouse.over(point, event);\n    },\n    mouseOut: function (point, event) {\n      if (this.logEvents) {\n        this.eventLog.push('mouseOut(' + Input.serializeVector2(point) + ',' + Input.serializeDomEvent(event) + ');');\n      }\n      this.mouse.out(point, event);\n    },\n    keyDown: function (event) {\n      if (this.logEvents) {\n        this.eventLog.push('keyDown(' + Input.serializeDomEvent(event) + ');');\n      }\n      var key = new scenery.Key(event);\n      this.addPointer(key);\n      var trail = this.scene.getTrailFromKeyboardFocus();\n      this.dispatchEvent(trail, 'keyDown', key, event, true);\n    },\n    keyUp: function (event) {\n      if (this.logEvents) {\n        this.eventLog.push('keyUp(' + Input.serializeDomEvent(event) + ');');\n      }\n      var key = this.findKeyByEvent(event);\n      if (key) {\n        this.removePointer(key);\n        var trail = this.scene.getTrailFromKeyboardFocus();\n        this.dispatchEvent(trail, 'keyUp', key, event, true);\n      }\n    },\n    keyPress: function (event) {\n      if (this.logEvents) {\n        this.eventLog.push('keyPress(' + Input.serializeDomEvent(event) + ');');\n      }\n    },\n    touchStart: function (id, point, event) {\n      if (this.logEvents) {\n        this.eventLog.push('touchStart(\\'' + id + '\\',' + Input.serializeVector2(point) + ',' + Input.serializeDomEvent(event) + ');');\n      }\n      var touch = new scenery.Touch(id, point, event);\n      this.addPointer(touch);\n      this.downEvent(touch, event);\n    },\n    touchEnd: function (id, point, event) {\n      if (this.logEvents) {\n        this.eventLog.push('touchEnd(\\'' + id + '\\',' + Input.serializeVector2(point) + ',' + Input.serializeDomEvent(event) + ');');\n      }\n      var touch = this.findTouchById(id);\n      if (touch) {\n        touch.end(point, event);\n        this.removePointer(touch);\n        this.upEvent(touch, event);\n      } else {\n        sceneryAssert && sceneryAssert(false, 'Touch not found for touchEnd: ' + id);\n      }\n    },\n    touchEndImmediate: function (id, point, event) {\n      if (this.logEvents) {\n        this.eventLog.push('touchEndImmediate(\\'' + id + '\\',' + Input.serializeVector2(point) + ',' + Input.serializeDomEvent(event) + ');');\n      }\n      var touch = this.findTouchById(id);\n      if (touch) {\n        this.upImmediateEvent(touch, event);\n      } else {\n        sceneryAssert && sceneryAssert(false, 'Touch not found for touchEndImmediate: ' + id);\n      }\n    },\n    touchMove: function (id, point, event) {\n      if (this.logEvents) {\n        this.eventLog.push('touchMove(\\'' + id + '\\',' + Input.serializeVector2(point) + ',' + Input.serializeDomEvent(event) + ');');\n      }\n      var touch = this.findTouchById(id);\n      if (touch) {\n        touch.move(point, event);\n        this.moveEvent(touch, event);\n      } else {\n        sceneryAssert && sceneryAssert(false, 'Touch not found for touchMove: ' + id);\n      }\n    },\n    touchCancel: function (id, point, event) {\n      if (this.logEvents) {\n        this.eventLog.push('touchCancel(\\'' + id + '\\',' + Input.serializeVector2(point) + ',' + Input.serializeDomEvent(event) + ');');\n      }\n      var touch = this.findTouchById(id);\n      if (touch) {\n        touch.cancel(point, event);\n        this.removePointer(touch);\n        this.cancelEvent(touch, event);\n      } else {\n        sceneryAssert && sceneryAssert(false, 'Touch not found for touchCancel: ' + id);\n      }\n    },\n    penStart: function (id, point, event) {\n      if (this.logEvents) {\n        this.eventLog.push('penStart(\\'' + id + '\\',' + Input.serializeVector2(point) + ',' + Input.serializeDomEvent(event) + ');');\n      }\n      var pen = new scenery.Pen(id, point, event);\n      this.addPointer(pen);\n      this.downEvent(pen, event);\n    },\n    penEnd: function (id, point, event) {\n      if (this.logEvents) {\n        this.eventLog.push('penEnd(\\'' + id + '\\',' + Input.serializeVector2(point) + ',' + Input.serializeDomEvent(event) + ');');\n      }\n      var pen = this.findTouchById(id);\n      if (pen) {\n        pen.end(point, event);\n        this.removePointer(pen);\n        this.upEvent(pen, event);\n      } else {\n        sceneryAssert && sceneryAssert(false, 'Pen not found for penEnd: ' + id);\n      }\n    },\n    penEndImmediate: function (id, point, event) {\n      if (this.logEvents) {\n        this.eventLog.push('penEndImmediate(\\'' + id + '\\',' + Input.serializeVector2(point) + ',' + Input.serializeDomEvent(event) + ');');\n      }\n      var pen = this.findTouchById(id);\n      if (pen) {\n        this.upImmediateEvent(pen, event);\n      } else {\n        sceneryAssert && sceneryAssert(false, 'Pen not found for penEndImmediate: ' + id);\n      }\n    },\n    penMove: function (id, point, event) {\n      if (this.logEvents) {\n        this.eventLog.push('penMove(\\'' + id + '\\',' + Input.serializeVector2(point) + ',' + Input.serializeDomEvent(event) + ');');\n      }\n      var pen = this.findTouchById(id);\n      if (pen) {\n        pen.move(point, event);\n        this.moveEvent(pen, event);\n      } else {\n        sceneryAssert && sceneryAssert(false, 'Pen not found for penMove: ' + id);\n      }\n    },\n    penCancel: function (id, point, event) {\n      if (this.logEvents) {\n        this.eventLog.push('penCancel(\\'' + id + '\\',' + Input.serializeVector2(point) + ',' + Input.serializeDomEvent(event) + ');');\n      }\n      var pen = this.findTouchById(id);\n      if (pen) {\n        pen.cancel(point, event);\n        this.removePointer(pen);\n        this.cancelEvent(pen, event);\n      } else {\n        sceneryAssert && sceneryAssert(false, 'Pen not found for penCancel: ' + id);\n      }\n    },\n    pointerDown: function (id, type, point, event) {\n      switch (type) {\n      case 'mouse':\n        this.mouseDown(point, event);\n        break;\n      case 'touch':\n        this.touchStart(id, point, event);\n        break;\n      case 'pen':\n        this.penStart(id, point, event);\n        break;\n      default:\n        if (console.log) {\n          console.log('Unknown pointer type: ' + type);\n        }\n      }\n    },\n    pointerUp: function (id, type, point, event) {\n      switch (type) {\n      case 'mouse':\n        this.mouseUp(point, event);\n        break;\n      case 'touch':\n        this.touchEnd(id, point, event);\n        break;\n      case 'pen':\n        this.penEnd(id, point, event);\n        break;\n      default:\n        if (console.log) {\n          console.log('Unknown pointer type: ' + type);\n        }\n      }\n    },\n    pointerUpImmediate: function (id, type, point, event) {\n      switch (type) {\n      case 'mouse':\n        this.mouseUpImmediate(point, event);\n        break;\n      case 'touch':\n        this.touchEndImmediate(id, point, event);\n        break;\n      case 'pen':\n        this.penEndImmediate(id, point, event);\n        break;\n      default:\n        if (console.log) {\n          console.log('Unknown pointer type: ' + type);\n        }\n      }\n    },\n    pointerCancel: function (id, type, point, event) {\n      switch (type) {\n      case 'mouse':\n        if (console && console.log) {\n          console.log('WARNING: Pointer mouse cancel was received');\n        }\n        break;\n      case 'touch':\n        this.touchCancel(id, point, event);\n        break;\n      case 'pen':\n        this.penCancel(id, point, event);\n        break;\n      default:\n        if (console.log) {\n          console.log('Unknown pointer type: ' + type);\n        }\n      }\n    },\n    pointerMove: function (id, type, point, event) {\n      switch (type) {\n      case 'mouse':\n        this.mouseMove(point, event);\n        break;\n      case 'touch':\n        this.touchMove(id, point, event);\n        break;\n      case 'pen':\n        this.penMove(id, point, event);\n        break;\n      default:\n        if (console.log) {\n          console.log('Unknown pointer type: ' + type);\n        }\n      }\n    },\n    pointerOver: function (id, type, point, event) {\n    },\n    pointerOut: function (id, type, point, event) {\n    },\n    pointerEnter: function (id, type, point, event) {\n    },\n    pointerLeave: function (id, type, point, event) {\n    },\n    upEvent: function (pointer, event) {\n      var trail = this.scene.trailUnderPointer(pointer) || new scenery.Trail(this.scene);\n      this.dispatchEvent(trail, 'up', pointer, event, true);\n      if (pointer.isTouch) {\n        this.exitEvents(pointer, event, trail, 0, true);\n      }\n      pointer.trail = trail;\n    },\n    upImmediateEvent: function (pointer, event) {\n      var trail = this.scene.trailUnderPointer(pointer) || new scenery.Trail(this.scene);\n      this.dispatchEvent(trail, 'upImmediate', pointer, event, true);\n    },\n    downEvent: function (pointer, event) {\n      var trail = this.scene.trailUnderPointer(pointer) || new scenery.Trail(this.scene);\n      if (pointer.isTouch) {\n        this.enterEvents(pointer, event, trail, 0, true);\n      }\n      this.dispatchEvent(trail, 'down', pointer, event, true);\n      pointer.trail = trail;\n    },\n    moveEvent: function (pointer, event) {\n      this.branchChangeEvents(pointer, event, true);\n    },\n    cancelEvent: function (pointer, event) {\n      var trail = this.scene.trailUnderPointer(pointer) || new scenery.Trail(this.scene);\n      this.dispatchEvent(trail, 'cancel', pointer, event, true);\n      if (pointer.isTouch) {\n        this.exitEvents(pointer, event, trail, 0, true);\n      }\n      pointer.trail = trail;\n    },\n    branchChangeEvents: function (pointer, event, isMove) {\n      var trail = this.scene.trailUnderPointer(pointer) || new scenery.Trail(this.scene);\n      var oldTrail = pointer.trail || new scenery.Trail(this.scene);\n      var lastNodeChanged = oldTrail.lastNode() !== trail.lastNode();\n      if (!lastNodeChanged && !isMove) {\n        return;\n      }\n      var branchIndex;\n      for (branchIndex = 0; branchIndex < Math.min(trail.length, oldTrail.length); branchIndex++) {\n        if (trail.nodes[branchIndex] !== oldTrail.nodes[branchIndex]) {\n          break;\n        }\n      }\n      if (isMove) {\n        this.dispatchEvent(trail, 'move', pointer, event, true);\n      }\n      this.exitEvents(pointer, event, oldTrail, branchIndex, lastNodeChanged);\n      this.enterEvents(pointer, event, trail, branchIndex, lastNodeChanged);\n      pointer.trail = trail;\n    },\n    enterEvents: function (pointer, event, trail, branchIndex, lastNodeChanged) {\n      if (trail.length > branchIndex) {\n        for (var newIndex = trail.length - 1; newIndex >= branchIndex; newIndex--) {\n          this.dispatchEvent(trail.slice(0, newIndex + 1), 'enter', pointer, event, false);\n        }\n      }\n      if (lastNodeChanged) {\n        this.dispatchEvent(trail, 'over', pointer, event, true);\n      }\n    },\n    exitEvents: function (pointer, event, trail, branchIndex, lastNodeChanged) {\n      if (lastNodeChanged) {\n        this.dispatchEvent(trail, 'out', pointer, event, true);\n      }\n      if (trail.length > branchIndex) {\n        for (var oldIndex = branchIndex; oldIndex < trail.length; oldIndex++) {\n          this.dispatchEvent(trail.slice(0, oldIndex + 1), 'exit', pointer, event, false);\n        }\n      }\n    },\n    validatePointers: function () {\n      var that = this;\n      var i = this.pointers.length;\n      while (i--) {\n        var pointer = this.pointers[i];\n        if (pointer.point) {\n          that.branchChangeEvents(pointer, null, false);\n        }\n      }\n    },\n    dispatchEvent: function (trail, type, pointer, event, bubbles) {\n      sceneryEventLog && sceneryEventLog('Input: ' + type + ' on ' + trail.toString() + ' for pointer ' + pointer.toString());\n      if (!trail) {\n        try {\n          throw new Error('falsy trail for dispatchEvent');\n        } catch (e) {\n          console.log(e.stack);\n          throw e;\n        }\n      }\n      var inputEvent = new scenery.Event({\n          trail: trail,\n          type: type,\n          pointer: pointer,\n          domEvent: event,\n          currentTarget: null,\n          target: trail.lastNode()\n        });\n      this.dispatchToPointer(type, pointer, inputEvent);\n      this.dispatchToTargets(trail, pointer, type, inputEvent, bubbles);\n      if (!trail.lastNode().interactive && !pointer.isKey && event && event.preventDefault) {\n        event.preventDefault();\n      }\n    },\n    dispatchToPointer: function (type, pointer, inputEvent) {\n      if (inputEvent.aborted || inputEvent.handled) {\n        return;\n      }\n      var specificType = pointer.type + type;\n      var pointerListeners = pointer.listeners.slice(0);\n      for (var i = 0; i < pointerListeners.length; i++) {\n        var listener = pointerListeners[i];\n        var aborted = false;\n        if (!aborted && listener[specificType]) {\n          listener[specificType](inputEvent);\n          aborted = inputEvent.aborted;\n        }\n        if (!aborted && listener[type]) {\n          listener[type](inputEvent);\n          aborted = inputEvent.aborted;\n        }\n        if (aborted) {\n          return;\n        }\n      }\n    },\n    dispatchToTargets: function (trail, pointer, type, inputEvent, bubbles) {\n      if (inputEvent.aborted || inputEvent.handled) {\n        return;\n      }\n      var specificType = pointer.type + type;\n      for (var i = trail.length - 1; i >= 0; bubbles ? i-- : i = -1) {\n        var target = trail.nodes[i];\n        inputEvent.currentTarget = target;\n        var listeners = target.getInputListeners();\n        for (var k = 0; k < listeners.length; k++) {\n          var listener = listeners[k];\n          var aborted = false;\n          if (!aborted && listener[specificType]) {\n            listener[specificType](inputEvent);\n            aborted = inputEvent.aborted;\n          }\n          if (!aborted && listener[type]) {\n            listener[type](inputEvent);\n            aborted = inputEvent.aborted;\n          }\n          if (aborted) {\n            return;\n          }\n        }\n        if (inputEvent.handled) {\n          return;\n        }\n      }\n    },\n    addListener: function (type, callback, useCapture) {\n      var input = this;\n      var usePreventDefault = type !== 'keydown' && type !== 'keyup' && type !== 'keypress';\n      if (this.batchDOMEvents) {\n        var batchedCallback = function batchedEvent(domEvent) {\n          sceneryEventLog && sceneryEventLog('Batching event for ' + type);\n          if (usePreventDefault) {\n            domEvent.preventDefault();\n          }\n          input.batchedCallbacks.push(function batchedEventCallback() {\n            input.validatePointers();\n            if (input.logEvents) {\n              input.eventLog.push('validatePointers();');\n            }\n            callback(domEvent);\n          });\n        };\n        this.listenerTarget.addEventListener(type, batchedCallback, useCapture);\n        this.listenerReferences.push({\n          type: type,\n          callback: batchedCallback,\n          useCapture: useCapture\n        });\n      } else {\n        this.listenerTarget.addEventListener(type, callback, useCapture);\n        this.listenerReferences.push({\n          type: type,\n          callback: function synchronousEvent(domEvent) {\n            sceneryEventLog && sceneryEventLog('Running event for ' + type);\n            input.validatePointers();\n            if (input.logEvents) {\n              input.eventLog.push('validatePointers();');\n            }\n            callback(domEvent);\n          },\n          useCapture: useCapture\n        });\n      }\n    },\n    addImmediateListener: function (type, callback, useCapture) {\n      var input = this;\n      this.listenerTarget.addEventListener(type, callback, useCapture);\n      this.listenerReferences.push({\n        type: type,\n        callback: function immediateEvent(domEvent) {\n          sceneryEventLog && sceneryEventLog('Running immediate event for ' + type);\n          callback(domEvent);\n        },\n        useCapture: useCapture\n      });\n    },\n    disposeListeners: function () {\n      var input = this;\n      _.each(this.listenerReferences, function (ref) {\n        input.listenerTarget.removeEventListener(ref.type, ref.callback, ref.useCapture);\n      });\n    },\n    fireBatchedEvents: function () {\n      if (this.batchedCallbacks.length) {\n        sceneryEventLog && sceneryEventLog('Input.fireBatchedEvents length:' + this.batchedCallbacks.length);\n        var len = this.batchedCallbacks.length;\n        for (var i = 0; i < len; i++) {\n          this.batchedCallbacks[i]();\n        }\n        this.batchedCallbacks.length = 0;\n      }\n    }\n  };\n  Input.serializeDomEvent = function serializeDomEvent(domEvent) {\n    var lines = [];\n    for (var prop in domEvent) {\n      if (domEvent.hasOwnProperty(prop)) {\n        if (prop === 'touches' || prop === 'targetTouches' || prop === 'changedTouches') {\n          var arr = [];\n          for (var i = 0; i < domEvent[prop].length; i++) {\n            var touch = domEvent[prop].item(i);\n            arr.push(serializeDomEvent(touch));\n          }\n          lines.push(prop + ':[' + arr.join(',') + ']');\n        } else {\n          lines.push(prop + ':' + (typeof domEvent[prop] === 'object' && domEvent[prop] !== null ? '{}' : JSON.stringify(domEvent[prop])));\n        }\n      }\n    }\n    return '{' + lines.join(',') + '}';\n  };\n  Input.serializeVector2 = function (vector) {\n    return 'dot(' + vector.x + ',' + vector.y + ')';\n  };\n  return Input;\n});",
    "\ndefine('SCENERY/layers/LayerBoundary',['require','SCENERY/scenery'],function (require) {\n  'use strict';\n  var scenery = require('SCENERY/scenery');\n  scenery.LayerBoundary = function LayerBoundary() {\n    this.previousLayerType = null;\n    this.nextLayerType = null;\n    this.previousPaintedTrail = null;\n    this.nextPaintedTrail = null;\n  };\n  var LayerBoundary = scenery.LayerBoundary;\n  LayerBoundary.prototype = {\n    constructor: LayerBoundary,\n    hasPrevious: function () {\n      return !!this.previousPaintedTrail;\n    },\n    hasNext: function () {\n      return !!this.nextPaintedTrail;\n    },\n    reindex: function () {\n      this.previousPaintedTrail && this.previousPaintedTrail.reindex();\n      this.nextPaintedTrail && this.nextPaintedTrail.reindex();\n    },\n    equivalentPreviousTrail: function (trail) {\n      if (this.previousPaintedTrail && trail) {\n        this.previousPaintedTrail.reindex();\n        return this.previousPaintedTrail.equals(trail);\n      } else {\n        return this.previousPaintedTrail === trail;\n      }\n    },\n    equivalentNextTrail: function (trail) {\n      if (this.nextPaintedTrail && trail) {\n        this.nextPaintedTrail.reindex();\n        return this.nextPaintedTrail.equals(trail);\n      } else {\n        return this.nextPaintedTrail === trail;\n      }\n    },\n    toString: function () {\n      return 'boundary:' + '\\n    types:    ' + (this.previousLayerType ? this.previousLayerType.name : '') + ' => ' + (this.nextLayerType ? this.nextLayerType.name : '') + '\\n    trails:   ' + (this.previousPaintedTrail ? this.previousPaintedTrail.getUniqueId() : '') + ' => ' + (this.nextPaintedTrail ? this.nextPaintedTrail.getUniqueId() : '');\n    }\n  };\n  return LayerBoundary;\n});",
    "\ndefine('SCENERY/layers/LayerBuilder',['require','SCENERY/scenery','SCENERY/layers/LayerBoundary','SCENERY/util/Trail','SCENERY/util/TrailPointer'],function (require) {\n  'use strict';\n  var scenery = require('SCENERY/scenery');\n  require('SCENERY/layers/LayerBoundary');\n  require('SCENERY/util/Trail');\n  require('SCENERY/util/TrailPointer');\n  scenery.LayerBuilder = function LayerBuilder(scene, previousLayerType, previousPaintedTrail, nextPaintedTrail) {\n    this.layerTypeStack = [];\n    this.boundaries = [];\n    this.pendingBoundary = new scenery.LayerBoundary();\n    this.pendingBoundary.previousLayerType = previousLayerType;\n    this.pendingBoundary.previousPaintedTrail = previousPaintedTrail;\n    this.currentLayerType = previousLayerType;\n    this.layerChangePending = previousPaintedTrail === null;\n    if (previousPaintedTrail) {\n      this.startPointer = new scenery.TrailPointer(previousPaintedTrail.copy(), true);\n      this.startPointer.nestedForwards();\n    } else {\n      this.startPointer = new scenery.TrailPointer(new scenery.Trail(scene), true);\n    }\n    if (nextPaintedTrail) {\n      this.endPointer = new scenery.TrailPointer(nextPaintedTrail.copy(), true);\n    } else {\n      this.endPointer = new scenery.TrailPointer(new scenery.Trail(scene), false);\n    }\n    this.includesEndTrail = nextPaintedTrail !== null;\n  };\n  var LayerBuilder = scenery.LayerBuilder;\n  LayerBuilder.prototype = {\n    constructor: LayerBuilder,\n    prepareLayerStack: function () {\n      var pointer = new scenery.TrailPointer(new scenery.Trail(this.startPointer.trail.rootNode()), true);\n      var targetLength = this.startPointer.trail.length - (this.startPointer.isBefore ? 1 : 0);\n      while (pointer.trail.length <= targetLength) {\n        var node = pointer.trail.lastNode();\n        if (node.layerStrategy.hasPreferredLayerType(pointer, this)) {\n          this.pushPreferredLayerType(node.layerStrategy.getPreferredLayerType(pointer, this));\n        }\n        if (pointer.trail.length < this.startPointer.trail.nodes.length) {\n          pointer.trail.addDescendant(this.startPointer.trail.nodes[pointer.trail.length]);\n        } else {\n          break;\n        }\n      }\n    },\n    run: function () {\n      var builder = this;\n      this.prepareLayerStack();\n      builder.startPointer.depthFirstUntil(builder.endPointer, function (pointer) {\n        var node = pointer.trail.lastNode();\n        if (pointer.isBefore) {\n          node.layerStrategy.enter(pointer, builder);\n        } else {\n          node.layerStrategy.exit(pointer, builder);\n        }\n      }, false);\n      if (!this.includesEndTrail) {\n        this.layerChange(null);\n      }\n    },\n    layerChange: function (paintedPointer) {\n      this.layerChangePending = false;\n      var confirmedBoundary = this.pendingBoundary;\n      confirmedBoundary.nextPaintedTrail = paintedPointer ? paintedPointer.trail.copy() : null;\n      this.boundaries.push(confirmedBoundary);\n      this.pendingBoundary = new scenery.LayerBoundary();\n      this.pendingBoundary.previousLayerType = confirmedBoundary.nextLayerType;\n      this.pendingBoundary.previousPaintedTrail = confirmedBoundary.nextPaintedTrail;\n    },\n    switchToType: function (pointer, layerType) {\n      this.currentLayerType = layerType;\n      this.pendingBoundary.nextLayerType = layerType;\n      this.layerChangePending = true;\n    },\n    markPainted: function (pointer) {\n      if (this.layerChangePending) {\n        this.layerChange(pointer);\n      } else {\n        this.pendingBoundary.previousPaintedTrail = pointer.trail.copy();\n      }\n    },\n    getCurrentLayerType: function () {\n      return this.currentLayerType;\n    },\n    pushPreferredLayerType: function (layerType) {\n      this.layerTypeStack.push(layerType);\n    },\n    popPreferredLayerType: function () {\n      this.layerTypeStack.pop();\n    },\n    getPreferredLayerType: function () {\n      if (this.layerTypeStack.length !== 0) {\n        return this.layerTypeStack[this.layerTypeStack.length - 1];\n      } else {\n        return null;\n      }\n    },\n    bestPreferredLayerTypeFor: function (renderers) {\n      for (var i = this.layerTypeStack.length - 1; i >= 0; i--) {\n        var preferredType = this.layerTypeStack[i];\n        var k = renderers.length;\n        while (k--) {\n          if (preferredType.supportsRenderer(renderers[k])) {\n            return preferredType;\n          }\n        }\n      }\n      return null;\n    }\n  };\n  return LayerBuilder;\n});",
    "\ndefine('SCENERY/Scene',['require','PHET_CORE/collect','PHET_CORE/inherit','DOT/Bounds2','DOT/Vector2','DOT/Matrix3','KITE/Shape','SCENERY/scenery','SCENERY/nodes/Node','SCENERY/util/Instance','SCENERY/util/Trail','SCENERY/util/RenderInterval','SCENERY/util/TrailPointer','SCENERY/input/Input','SCENERY/layers/LayerBuilder','SCENERY/layers/Renderer','SCENERY/util/Util'],function (require) {\n  'use strict';\n  var collect = require('PHET_CORE/collect');\n  var inherit = require('PHET_CORE/inherit');\n  var Bounds2 = require('DOT/Bounds2');\n  var Vector2 = require('DOT/Vector2');\n  var Matrix3 = require('DOT/Matrix3');\n  var Shape = require('KITE/Shape');\n  var scenery = require('SCENERY/scenery');\n  var Node = require('SCENERY/nodes/Node');\n  require('SCENERY/util/Instance');\n  require('SCENERY/util/Trail');\n  require('SCENERY/util/RenderInterval');\n  require('SCENERY/util/TrailPointer');\n  require('SCENERY/input/Input');\n  require('SCENERY/layers/LayerBuilder');\n  require('SCENERY/layers/Renderer');\n  var Util = require('SCENERY/util/Util');\n  var objectCreate = Util.objectCreate;\n  var accessibility = window.has && window.has('scenery.accessibility');\n  var forceNewLayers = true;\n  function buildInstances(instance) {\n    var node = instance.getNode();\n    var len = node._children.length;\n    for (var i = 0; i < len; i++) {\n      buildInstances(instance.createChild(node._children[i], i));\n    }\n  }\n  scenery.Scene = function Scene($main, options) {\n    sceneryAssert && sceneryAssert($main[0], 'A main container is required for a scene');\n    this.$main = $main;\n    this.main = $main[0];\n    this.main.scene = this;\n    this.scenery = scenery;\n    options = _.extend({\n      allowSceneOverflow: false,\n      allowCSSHacks: true,\n      allowDevicePixelRatioScaling: false,\n      enablePointerEvents: true,\n      preferredSceneLayerType: scenery.CanvasDefaultLayerType,\n      width: $main.width(),\n      height: $main.height()\n    }, options || {});\n    this.backingScale = options.allowDevicePixelRatioScaling ? Util.backingScale(document.createElement('canvas').getContext('2d')) : 1;\n    this.enablePointerEvents = options.enablePointerEvents;\n    Node.call(this, options);\n    var scene = this;\n    window.debugScene = scene;\n    this.layers = [];\n    this.layerChangeIntervals = [];\n    this.lastCursor = null;\n    this.defaultCursor = $main.css('cursor');\n    this.setSize(options.width, options.height);\n    this.sceneBounds = new Bounds2(0, 0, options.width, options.height);\n    this.rootInstance = new scenery.Instance(new scenery.Trail(this), null, null);\n    this.addInstance(this.rootInstance);\n    this.preferredSceneLayerType = options.preferredSceneLayerType;\n    applyCSSHacks($main, options);\n    if (accessibility) {\n      this.activePeer = null;\n      this.accessibilityLayer = document.createElement('div');\n      this.accessibilityLayer.className = 'accessibility-layer';\n      this.accessibilityLayer.style.zIndex = -1;\n      this.accessibilityLayer.style.position = 'relative';\n      $main[0].appendChild(this.accessibilityLayer);\n      this.focusRingSVGContainer = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n      this.focusRingSVGContainer.style.position = 'absolute';\n      this.focusRingSVGContainer.style.top = 0;\n      this.focusRingSVGContainer.style.left = 0;\n      this.focusRingSVGContainer.style['pointer-events'] = 'none';\n      this.resizeFocusRingSVGContainer(options.width, options.height);\n      this.focusRingPath = document.createElementNS('http://www.w3.org/2000/svg', 'path');\n      this.focusRingPath.setAttribute('style', 'fill: none; stroke: blue; stroke-width: 5;');\n      this.focusRingPath.setAttribute('id', 'p1');\n      this.focusRingSVGContainer.appendChild(this.focusRingPath);\n      $main[0].appendChild(this.focusRingSVGContainer);\n      this.updateFocusRing = function () {\n        sceneryAssert && sceneryAssert(scene.activePeer, 'scene should have an active peer when changing the focus ring bounds');\n        scene.focusRingPath.setAttribute('d', Shape.bounds(scene.activePeer.getGlobalBounds()).getSVGPath());\n      };\n      this.liveRegionLayer = document.createElement('div');\n      this.liveRegionLayer.className = 'live-region-layer';\n      this.liveRegionLayer.style.zIndex = -2;\n      this.liveRegionLayer.style.position = 'relative';\n      $main[0].appendChild(this.liveRegionLayer);\n    }\n  };\n  var Scene = scenery.Scene;\n  inherit(Node, Scene, {\n    updateScene: function (args) {\n      var scene = this;\n      if (this.input) {\n        this.input.validatePointers();\n      }\n      this.validateBounds();\n      this.validatePaint();\n      if (!this.layers.length) {\n        return;\n      }\n      var i = this.layers.length;\n      while (i--) {\n        this.layers[i].render(scene, args);\n      }\n      this.updateCursor();\n    },\n    renderScene: function () {\n      this.updateScene();\n    },\n    addPeer: function (peer) {\n      this.accessibilityLayer.appendChild(peer.peerElement);\n    },\n    removePeer: function (peer) {\n      this.accessibilityLayer.removeChild(peer.peerElement);\n    },\n    addLiveRegion: function (liveRegion) {\n      this.liveRegionLayer.appendChild(liveRegion.element);\n    },\n    removeLiveRegion: function (liveRegion) {\n      this.liveRegionLayer.removeChild(liveRegion.element);\n    },\n    setActivePeer: function (peer) {\n      if (this.activePeer !== peer) {\n        var scene = this;\n        if (this.activePeer) {\n          this.activePeer.instance.node.removeEventListener('bounds', this.updateFocusRing);\n        }\n        this.activePeer = peer;\n        if (peer) {\n          this.activePeer.instance.node.addEventListener('bounds', this.updateFocusRing);\n          this.updateFocusRing();\n        } else {\n          this.focusRingPath.setAttribute('d', 'M 0 0');\n        }\n      }\n    },\n    getActivePeer: function (peer) {\n      return this.activePeer;\n    },\n    focusPeer: function (peer) {\n      this.setActivePeer(peer);\n    },\n    blurPeer: function (peer) {\n      sceneryAssert && sceneryAssert(this.getActivePeer() === peer, 'Can only blur an active peer');\n      this.setActivePeer(null);\n    },\n    markInterval: function (affectedTrail) {\n      affectedTrail.reindex();\n      var beforeTrail = affectedTrail.previousPainted();\n      var afterTrailPointer = new scenery.TrailPointer(affectedTrail.copy(), false);\n      while (afterTrailPointer.hasTrail() && (!afterTrailPointer.isBefore || !afterTrailPointer.trail.isPainted())) {\n        afterTrailPointer.nestedForwards();\n      }\n      var afterTrail = afterTrailPointer.trail;\n      sceneryAssert && sceneryAssert(!beforeTrail || beforeTrail.areIndicesValid(), 'beforeTrail needs to be valid');\n      sceneryAssert && sceneryAssert(!afterTrail || afterTrail.areIndicesValid(), 'afterTrail needs to be valid');\n      sceneryAssert && sceneryAssert(!beforeTrail || !afterTrail || beforeTrail.compare(afterTrail) !== 0, 'Marked interval needs to be exclusive');\n      this.addLayerChangeInterval(new scenery.RenderInterval(beforeTrail, afterTrail));\n    },\n    addLayerChangeInterval: function (interval) {\n      if (sceneryLayerLog) {\n        sceneryLayerLog('adding interval: ' + interval.toString() + ' to intervals:');\n        _.each(this.layerChangeIntervals, function (interval) {\n          sceneryLayerLog('  ' + interval.toString());\n        });\n      }\n      for (var i = 0; i < this.layerChangeIntervals.length; i++) {\n        var other = this.layerChangeIntervals[i];\n        other.reindex();\n        if (interval.exclusiveUnionable(other)) {\n          interval = interval.union(other);\n          this.layerChangeIntervals.splice(i--, 1);\n          sceneryLayerLog && sceneryLayerLog('removing interval: ' + other.toString());\n        }\n      }\n      this.layerChangeIntervals.push(interval);\n      if (sceneryLayerLog) {\n        sceneryLayerLog('new intervals: ');\n        _.each(this.layerChangeIntervals, function (interval) {\n          sceneryLayerLog('  ' + interval.toString());\n        });\n        sceneryLayerLog('---');\n      }\n    },\n    createLayer: function (layerType, layerArgs, startBoundary, endBoundary) {\n      var layer = layerType.createLayer(_.extend({\n          startBoundary: startBoundary,\n          endBoundary: endBoundary\n        }, layerArgs));\n      layer.type = layerType;\n      sceneryLayerLog && sceneryLayerLog('created layer: ' + layer.getId() + ' of type ' + layer.type.name);\n      return layer;\n    },\n    insertLayer: function (layer) {\n      for (var i = 0; i < this.layers.length; i++) {\n        if (layer.endPaintedTrail.isBefore(this.layers[i].startPaintedTrail)) {\n          this.layers.splice(i, 0, layer);\n          return;\n        }\n      }\n      this.layers.push(layer);\n    },\n    getBoundaries: function () {\n      return [this.layers[0].startBoundary].concat(_.pluck(this.layers, 'endBoundary'));\n    },\n    calculateBoundaries: function (beforeLayerType, beforeTrail, afterTrail) {\n      sceneryLayerLog && sceneryLayerLog('build between ' + (beforeTrail ? beforeTrail.toString() : beforeTrail) + ',' + (afterTrail ? afterTrail.toString() : afterTrail) + ' with beforeType: ' + (beforeLayerType ? beforeLayerType.name : null));\n      var builder = new scenery.LayerBuilder(this, beforeLayerType, beforeTrail, afterTrail);\n      if (this.preferredSceneLayerType) {\n        builder.pushPreferredLayerType(this.preferredSceneLayerType);\n      }\n      builder.run();\n      return builder.boundaries;\n    },\n    stitch: function (match) {\n      var scene = this;\n      var i;\n      sceneryLayerLog && sceneryLayerLog('-----------------------------------\\nbeginning stitch');\n      if (!this.layerChangeIntervals.length) {\n        return;\n      }\n      var stitchData = {\n          affectedInstances: [],\n          newLayers: []\n        };\n      var layerArgs = {\n          $main: this.$main,\n          scene: this,\n          baseNode: this\n        };\n      i = this.layerChangeIntervals.length;\n      while (i--) {\n        this.layerChangeIntervals[i].reindex();\n      }\n      this.layerChangeIntervals.sort(scenery.RenderInterval.compareDisjoint);\n      sceneryLayerLog && sceneryLayerLog('stitching on intervals: \\n' + this.layerChangeIntervals.join('\\n'));\n      for (i = 0; i < this.layerChangeIntervals.length; i++) {\n        var interval = this.layerChangeIntervals[i];\n        sceneryLayerLog && sceneryLayerLog('stitch on interval ' + interval.toString());\n        var beforeTrail = interval.start;\n        var afterTrail = interval.end;\n        var beforeInstance = beforeTrail ? beforeTrail.getInstance() : null;\n        var afterInstance = afterTrail ? afterTrail.getInstance() : null;\n        var beforeLayer = beforeInstance ? beforeInstance.layer : null;\n        var afterLayer = afterInstance ? afterInstance.layer : null;\n        var boundaries = this.calculateBoundaries(beforeLayer ? beforeLayer.type : null, beforeTrail, afterTrail);\n        this.stitchInterval(stitchData, layerArgs, beforeTrail, afterTrail, beforeLayer, afterLayer, boundaries, match);\n      }\n      this.layerChangeIntervals.length = 0;\n      sceneryLayerLog && sceneryLayerLog('------ finished intervals in stitching');\n      i = this.layers.length;\n      while (i--) {\n        var layer = this.layers[i];\n        layer.startBoundary.reindex();\n        layer.endBoundary.reindex();\n        if (layer._instanceCount === 0) {\n          sceneryLayerLog && sceneryLayerLog('disposing layer: ' + layer.getId());\n          this.disposeLayer(layer);\n        }\n      }\n      i = stitchData.newLayers.length;\n      while (i--) {\n        var newLayer = stitchData.newLayers[i];\n        newLayer.startBoundary.reindex();\n        newLayer.endBoundary.reindex();\n        sceneryAssert && sceneryAssert(newLayer._instanceCount, 'ensure we are not adding empty layers');\n        sceneryLayerLog && sceneryLayerLog('inserting layer: ' + newLayer.getId());\n        scene.insertLayer(newLayer);\n      }\n      this.reindexLayers();\n      sceneryLayerLog && sceneryLayerLog('------ updating layer references');\n      var affectedLen = stitchData.affectedInstances.length;\n      for (i = 0; i < affectedLen; i++) {\n        stitchData.affectedInstances[i].updateLayer();\n      }\n      sceneryAssertExtra && sceneryAssertExtra(this.layerAudit());\n      sceneryLayerLog && sceneryLayerLog('finished stitch\\n-----------------------------------');\n    },\n    stitchInterval: function (stitchData, layerArgs, beforeTrail, afterTrail, beforeLayer, afterLayer, boundaries, match) {\n      var scene = this;\n      beforeTrail && beforeTrail.setImmutable();\n      afterTrail && afterTrail.setImmutable();\n      var afterLayerEndBoundary = afterLayer ? afterLayer.endBoundary : null;\n      var beforeLayerIndex = beforeLayer ? _.indexOf(this.layers, beforeLayer) : -1;\n      var afterLayerIndex = afterLayer ? _.indexOf(this.layers, afterLayer) : this.layers.length;\n      var beforePointer = beforeTrail ? new scenery.TrailPointer(beforeTrail, true) : new scenery.TrailPointer(new scenery.Trail(this), true);\n      var afterPointer = afterTrail ? new scenery.TrailPointer(afterTrail, true) : new scenery.TrailPointer(new scenery.Trail(this), false);\n      sceneryLayerLog && sceneryLayerLog('\\nstitching with boundaries:\\n' + _.map(boundaries, function (boundary) {\n        return boundary.toString();\n      }).join('\\n'));\n      sceneryLayerLog && sceneryLayerLog('               layers: ' + (beforeLayer ? beforeLayer.getId() : '-') + ' to ' + (afterLayer ? afterLayer.getId() : '-'));\n      sceneryLayerLog && sceneryLayerLog('               trails: ' + (beforeTrail ? beforeTrail.toString() : '-') + ' to ' + (afterTrail ? afterTrail.toString() : '-'));\n      sceneryLayerLog && sceneryLayerLog('               match: ' + match);\n      var nextBoundaryIndex = 0;\n      var nextBoundary = boundaries[nextBoundaryIndex];\n      var instancesToAddToLayer = [];\n      var currentTrail = beforeTrail;\n      var currentLayer = beforeLayer;\n      var currentLayerType = beforeLayer ? beforeLayer.type : null;\n      var currentStartBoundary = null;\n      var matchingLayer = null;\n      function addPendingTrailsToLayer() {\n        var len = instancesToAddToLayer.length;\n        for (var i = 0; i < len; i++) {\n          var instance = instancesToAddToLayer[i];\n          instance.changeLayer(currentLayer);\n          stitchData.affectedInstances.push(instance);\n        }\n        instancesToAddToLayer.length = 0;\n      }\n      function addAndCreateLayer(startBoundary, endBoundary) {\n        currentLayer = scene.createLayer(currentLayerType, layerArgs, startBoundary, endBoundary);\n        stitchData.newLayers.push(currentLayer);\n      }\n      function step(trail, isEnd) {\n        sceneryLayerLog && sceneryLayerLog('step: ' + (trail ? trail.toString() : trail));\n        trail && trail.setImmutable();\n        if (nextBoundary && nextBoundary.equivalentPreviousTrail(currentTrail)) {\n          sceneryAssert && sceneryAssert(nextBoundary.equivalentNextTrail(trail));\n          sceneryLayerLog && sceneryLayerLog(nextBoundary.toString());\n          if (currentLayer || currentStartBoundary) {\n            if (currentLayer) {\n              sceneryLayerLog && sceneryLayerLog('has currentLayer: ' + currentLayer.getId());\n              currentLayer.setEndBoundary(nextBoundary);\n            } else {\n              sceneryAssert && sceneryAssert(currentStartBoundary);\n              if (matchingLayer) {\n                sceneryLayerLog && sceneryLayerLog('matching layer used: ' + matchingLayer.getId());\n                matchingLayer.setStartBoundary(currentStartBoundary);\n                matchingLayer.setEndBoundary(nextBoundary);\n                currentLayer = matchingLayer;\n              } else {\n                sceneryLayerLog && sceneryLayerLog('creating layer');\n                addAndCreateLayer(currentStartBoundary, nextBoundary);\n              }\n            }\n            sceneryAssert && sceneryAssert(currentLayer.startPaintedTrail);\n            sceneryAssert && sceneryAssert(currentLayer.endPaintedTrail);\n            addPendingTrailsToLayer();\n          } else {\n            sceneryLayerLog && sceneryLayerLog('was first layer');\n            sceneryAssert && sceneryAssert(instancesToAddToLayer.length === 0);\n          }\n          currentLayer = null;\n          currentLayerType = nextBoundary.nextLayerType;\n          currentStartBoundary = nextBoundary;\n          matchingLayer = null;\n          nextBoundaryIndex++;\n          nextBoundary = boundaries[nextBoundaryIndex];\n        }\n        if (trail && !isEnd) {\n          instancesToAddToLayer.push(trail.getInstance());\n        }\n        if (match && !isEnd) {\n          var layer = trail.getInstance().layer;\n          if (layer.type === currentLayerType && !forceNewLayers) {\n            matchingLayer = layer;\n          }\n        }\n        currentTrail = trail;\n      }\n      function startStep(trail) {\n        sceneryLayerLog && sceneryLayerLog('startStep: ' + (trail ? trail.toString() : trail));\n      }\n      function middleStep(trail) {\n        sceneryLayerLog && sceneryLayerLog('middleStep: ' + trail.toString());\n        step(trail, false);\n      }\n      function endStep(trail) {\n        sceneryLayerLog && sceneryLayerLog('endStep: ' + (trail ? trail.toString() : trail));\n        step(trail, true);\n        if (beforeLayer !== afterLayer && boundaries.length === 0) {\n          sceneryLayerLog && sceneryLayerLog('gluing layer');\n          sceneryLayerLog && sceneryLayerLog('endBoundary: ' + afterLayer.endBoundary.toString());\n          beforeLayer.setEndBoundary(afterLayer.endBoundary);\n          currentLayer = beforeLayer;\n          addPendingTrailsToLayer();\n          var len = afterLayer._layerTrails.length;\n          for (var i = 0; i < len; i++) {\n            var endTrail = afterLayer._layerTrails[i];\n            endTrail.reindex();\n            var instance = endTrail.getInstance();\n            instance.changeLayer(beforeLayer);\n            stitchData.affectedInstances.push(instance);\n          }\n        } else if (beforeLayer && beforeLayer === afterLayer && boundaries.length > 0) {\n          sceneryLayerLog && sceneryLayerLog('ungluing layer');\n          sceneryAssert && sceneryAssert(currentStartBoundary);\n          addAndCreateLayer(currentStartBoundary, afterLayerEndBoundary);\n          addPendingTrailsToLayer();\n          currentLayer.endPaintedTrail.reindex();\n          scenery.Trail.eachPaintedTrailBetween(afterTrail, currentLayer.endPaintedTrail, function (subtrail) {\n            var instance = subtrail.getInstance();\n            instance.changeLayer(currentLayer);\n            stitchData.affectedInstances.push(instance);\n          }, false, scene);\n        } else if (!beforeLayer && !afterLayer && boundaries.length === 1 && !boundaries[0].hasNext() && !boundaries[0].hasPrevious()) {\n        } else {\n          currentLayer = afterLayer;\n          if (currentLayer && currentStartBoundary) {\n            currentLayer.setStartBoundary(currentStartBoundary);\n          }\n          addPendingTrailsToLayer();\n        }\n      }\n      startStep(beforeTrail);\n      beforePointer.eachTrailBetween(afterPointer, function (trail) {\n        if (!trail.isPainted() || beforeTrail && trail.equals(beforeTrail)) {\n          return;\n        }\n        middleStep(trail.copy());\n      });\n      endStep(afterTrail);\n    },\n    rebuildLayers: function () {\n      sceneryLayerLog && sceneryLayerLog('Scene: rebuildLayers');\n      this.markInterval(new scenery.Trail(this));\n      this.stitch(true);\n    },\n    reindexLayers: function () {\n      sceneryLayerLog && sceneryLayerLog('Scene: reindexLayers');\n      var index = 1;\n      if (accessibility && this.accessibiltyLayer) {\n        this.accessibilityLayer.style.zIndex = 9999;\n        index++;\n      }\n      var len = this.layers.length;\n      for (var i = 0; i < len; i++) {\n        index = this.layers[i].reindex(index);\n      }\n      if (accessibility) {\n        if (this.focusRingSVGContainer) {\n          this.focusRingSVGContainer.style.zIndex = index;\n        }\n      }\n    },\n    dispose: function () {\n      this.disposeLayers();\n      if (this.input) {\n        this.input.disposeListeners();\n      }\n      delete this.main.scene;\n    },\n    disposeLayer: function (layer) {\n      layer.dispose();\n      this.layers.splice(_.indexOf(this.layers, layer), 1);\n    },\n    disposeLayers: function () {\n      var scene = this;\n      var i = this.layers.length;\n      while (i--) {\n        this.disposeLayer(this.layers[i]);\n      }\n    },\n    affectedLayers: function (trail) {\n      sceneryAssert && sceneryAssert(!(trail.isEmpty() || trail.nodes[0] !== this), 'layerLookup root matches');\n      var n = this.layers.length;\n      if (n === 0) {\n        sceneryAssert && sceneryAssert(!trail.lastNode().isPainted(), 'There should be at least one layer for a painted trail');\n        return [];\n      }\n      sceneryAssert && sceneryAssert(trail.areIndicesValid());\n      var layers = this.layers;\n      var low = -1;\n      var high = n;\n      var mid;\n      while (high - 1 > low) {\n        mid = high + low >> 1;\n        var endTrail = layers[mid].endPaintedTrail;\n        sceneryAssert && sceneryAssert(endTrail.areIndicesValid());\n        var notAfter = scenery.TrailPointer.compareNested(trail, true, endTrail, true) !== 1;\n        if (notAfter) {\n          high = mid;\n        } else {\n          low = mid;\n        }\n      }\n      var firstIndex = high;\n      low = -1;\n      high = n;\n      while (high - 1 > low) {\n        mid = high + low >> 1;\n        var startTrail = layers[mid].startPaintedTrail;\n        startTrail.reindex();\n        sceneryAssert && sceneryAssert(startTrail.areIndicesValid());\n        var notBefore = scenery.TrailPointer.compareNested(trail, false, startTrail, true) !== -1;\n        if (notBefore) {\n          low = mid;\n        } else {\n          high = mid;\n        }\n      }\n      var lastIndex = low;\n      return layers.slice(firstIndex, lastIndex + 1);\n    },\n    renderToCanvas: function (canvas, context, callback) {\n      var count = 0;\n      var started = false;\n      var delayCounts = {\n          increment: function () {\n            count++;\n          },\n          decrement: function () {\n            count--;\n            if (count === 0 && callback && started) {\n              callback();\n            }\n          }\n        };\n      context.clearRect(0, 0, canvas.width, canvas.height);\n      var len = this.layers.length;\n      for (var i = 0; i < len; i++) {\n        this.layers[i].renderToCanvas(canvas, context, delayCounts);\n      }\n      if (count === 0) {\n        if (callback) {\n          callback();\n        }\n      } else {\n        started = true;\n      }\n    },\n    canvasDataURL: function (callback) {\n      this.canvasSnapshot(function (canvas) {\n        callback(canvas.toDataURL());\n      });\n    },\n    canvasSnapshot: function (callback) {\n      var canvas = document.createElement('canvas');\n      canvas.width = this.sceneBounds.getWidth();\n      canvas.height = this.sceneBounds.getHeight();\n      var context = canvas.getContext('2d');\n      this.renderToCanvas(canvas, context, function () {\n        callback(canvas, context.getImageData(0, 0, canvas.width, canvas.height));\n      });\n    },\n    setSize: function (width, height) {\n      this.$main.width(width);\n      this.$main.height(height);\n      this.$main.css('clip', 'rect(0px,' + width + 'px,' + height + 'px,0px)');\n      this.sceneBounds = new Bounds2(0, 0, width, height);\n    },\n    resize: function (width, height) {\n      if (this.sceneBounds.width !== width || this.sceneBounds.height !== height) {\n        this.setSize(width, height);\n        this.rebuildLayers();\n        if (accessibility) {\n          this.resizeAccessibilityLayer(width, height);\n          this.resizeFocusRingSVGContainer(width, height);\n          if (this.updateFocusRing && this.activePeer) {\n            this.updateFocusRing();\n          }\n        }\n        if (this.input) {\n          this.input.validatePointers();\n        }\n        this.fireEvent('resize', {\n          width: width,\n          height: height\n        });\n      }\n    },\n    resizeAccessibilityLayer: function (width, height) {\n      if (this.accessibilityLayer) {\n        this.accessibilityLayer.setAttribute('width', width);\n        this.accessibilityLayer.setAttribute('height', height);\n        this.accessibilityLayer.style.clip = 'rect(0px,' + width + 'px,' + height + 'px,0px)';\n      }\n    },\n    resizeFocusRingSVGContainer: function (width, height) {\n      if (this.focusRingSVGContainer) {\n        this.focusRingSVGContainer.setAttribute('width', width);\n        this.focusRingSVGContainer.setAttribute('height', height);\n        this.focusRingSVGContainer.style.clip = 'rect(0px,' + width + 'px,' + height + 'px,0px)';\n      }\n    },\n    getSceneWidth: function () {\n      return this.sceneBounds.getWidth();\n    },\n    getSceneHeight: function () {\n      return this.sceneBounds.getHeight();\n    },\n    markSceneForLayerRefresh: function (instance) {\n      sceneryLayerLog && sceneryLayerLog('Scene: marking layer refresh: ' + instance.trail.toString());\n      this.markInterval(instance.trail);\n    },\n    markSceneForInsertion: function (instance, child, index) {\n      var affectedTrail = instance.trail.copy().addDescendant(child);\n      sceneryLayerLog && sceneryLayerLog('Scene: marking insertion: ' + affectedTrail.toString());\n      sceneryLayerLog && sceneryLayerLog('inserting instances onto ' + instance.toString() + ' with child ' + child.id + ' and index ' + index);\n      var baseInstance = instance.createChild(child, index);\n      buildInstances(baseInstance);\n      this.markInterval(affectedTrail);\n    },\n    markSceneForRemoval: function (instance, child, index) {\n      var affectedTrail = instance.trail.copy().addDescendant(child);\n      sceneryLayerLog && sceneryLayerLog('Scene: marking removal: ' + affectedTrail.toString());\n      this.markInterval(affectedTrail);\n      var toRemove = [instance.children[index]];\n      instance.removeInstance(index);\n      while (toRemove.length) {\n        var item = toRemove.pop();\n        sceneryAssert && sceneryAssert(item, 'item instance should always exist');\n        Array.prototype.push.apply(toRemove, item.children);\n        item.dispose();\n      }\n    },\n    updateCursor: function () {\n      if (this.input && this.input.mouse.point) {\n        var mouseTrail = this.trailUnderPoint(this.input.mouse.point, { isMouse: true });\n        if (mouseTrail) {\n          for (var i = mouseTrail.length - 1; i >= 0; i--) {\n            var cursor = mouseTrail.nodes[i].getCursor();\n            if (cursor) {\n              this.setSceneCursor(cursor);\n              return;\n            }\n          }\n        }\n      }\n      this.setSceneCursor(this.defaultCursor);\n    },\n    setSceneCursor: function (cursor) {\n      if (cursor !== this.lastCursor) {\n        this.lastCursor = cursor;\n        this.$main.css('cursor', cursor);\n      }\n    },\n    updateOnRequestAnimationFrame: function (element) {\n      var scene = this;\n      (function step() {\n        window.requestAnimationFrame(step, element);\n        scene.updateScene();\n      }());\n    },\n    initializeStandaloneEvents: function (parameters) {\n      var element = this.$main[0];\n      this.initializeEvents(_.extend({}, {\n        listenerTarget: element,\n        pointFromEvent: function pointFromEvent(evt) {\n          var mainBounds = element.getBoundingClientRect();\n          return Vector2.createFromPool(evt.clientX - mainBounds.left, evt.clientY - mainBounds.top);\n        }\n      }, parameters));\n    },\n    initializeFullscreenEvents: function (parameters) {\n      var element = this.$main[0];\n      this.initializeEvents(_.extend({}, {\n        listenerTarget: document,\n        pointFromEvent: function pointFromEvent(evt) {\n          var mainBounds = element.getBoundingClientRect();\n          return Vector2.createFromPool(evt.clientX - mainBounds.left, evt.clientY - mainBounds.top);\n        }\n      }, parameters));\n    },\n    initializeWindowEvents: function (parameters) {\n      var element = this.$main[0];\n      this.initializeEvents(_.extend({}, {\n        listenerTarget: window,\n        pointFromEvent: function pointFromEvent(evt) {\n          var mainBounds = element.getBoundingClientRect();\n          return Vector2.createFromPool(evt.clientX - mainBounds.left, evt.clientY - mainBounds.top);\n        }\n      }, parameters));\n    },\n    initializeEvents: function (parameters) {\n      var scene = this;\n      if (scene.input) {\n        throw new Error('Attempt to attach events twice to the scene');\n      }\n      var pointFromEvent = parameters.pointFromEvent;\n      var listenerTarget = parameters.listenerTarget;\n      var batchDOMEvents = parameters.batchDOMEvents;\n      var input = new scenery.Input(scene, listenerTarget, !!batchDOMEvents);\n      scene.input = input;\n      function msPointerType(evt) {\n        if (evt.pointerType === window.MSPointerEvent.MSPOINTER_TYPE_TOUCH) {\n          return 'touch';\n        } else if (evt.pointerType === window.MSPointerEvent.MSPOINTER_TYPE_PEN) {\n          return 'pen';\n        } else if (evt.pointerType === window.MSPointerEvent.MSPOINTER_TYPE_MOUSE) {\n          return 'mouse';\n        } else {\n          return evt.pointerType;\n        }\n      }\n      function forEachChangedTouch(evt, callback) {\n        for (var i = 0; i < evt.changedTouches.length; i++) {\n          var touch = evt.changedTouches.item(i);\n          callback(touch.identifier, pointFromEvent(touch));\n        }\n      }\n      var implementsPointerEvents = window.navigator && window.navigator.pointerEnabled;\n      var implementsMSPointerEvents = window.navigator && window.navigator.msPointerEnabled;\n      if (this.enablePointerEvents && implementsPointerEvents) {\n        sceneryEventLog && sceneryEventLog('Detected pointer events support, using that instead of mouse/touch events');\n        input.addListener('pointerdown', function pointerDownCallback(domEvent) {\n          input.pointerDown(domEvent.pointerId, domEvent.pointerType, pointFromEvent(domEvent), domEvent);\n        });\n        input.addListener('pointerup', function pointerUpCallback(domEvent) {\n          input.pointerUp(domEvent.pointerId, domEvent.pointerType, pointFromEvent(domEvent), domEvent);\n        });\n        input.addListener('pointermove', function pointerMoveCallback(domEvent) {\n          input.pointerMove(domEvent.pointerId, domEvent.pointerType, pointFromEvent(domEvent), domEvent);\n        });\n        input.addListener('pointerover', function pointerOverCallback(domEvent) {\n          input.pointerOver(domEvent.pointerId, domEvent.pointerType, pointFromEvent(domEvent), domEvent);\n        });\n        input.addListener('pointerout', function pointerOutCallback(domEvent) {\n          input.pointerOut(domEvent.pointerId, domEvent.pointerType, pointFromEvent(domEvent), domEvent);\n        });\n        input.addListener('pointercancel', function pointerCancelCallback(domEvent) {\n          input.pointerCancel(domEvent.pointerId, domEvent.pointerType, pointFromEvent(domEvent), domEvent);\n        });\n        input.addImmediateListener('pointerup', function pointerUpCallback(domEvent) {\n          input.pointerUpImmediate(domEvent.pointerId, domEvent.pointerType, pointFromEvent(domEvent), domEvent);\n        });\n      } else if (this.enablePointerEvents && implementsMSPointerEvents) {\n        sceneryEventLog && sceneryEventLog('Detected MS pointer events support, using that instead of mouse/touch events');\n        input.addListener('MSPointerDown', function msPointerDownCallback(domEvent) {\n          input.pointerDown(domEvent.pointerId, msPointerType(domEvent), pointFromEvent(domEvent), domEvent);\n        });\n        input.addListener('MSPointerUp', function msPointerUpCallback(domEvent) {\n          input.pointerUp(domEvent.pointerId, msPointerType(domEvent), pointFromEvent(domEvent), domEvent);\n        });\n        input.addListener('MSPointerMove', function msPointerMoveCallback(domEvent) {\n          input.pointerMove(domEvent.pointerId, msPointerType(domEvent), pointFromEvent(domEvent), domEvent);\n        });\n        input.addListener('MSPointerOver', function msPointerOverCallback(domEvent) {\n          input.pointerOver(domEvent.pointerId, msPointerType(domEvent), pointFromEvent(domEvent), domEvent);\n        });\n        input.addListener('MSPointerOut', function msPointerOutCallback(domEvent) {\n          input.pointerOut(domEvent.pointerId, msPointerType(domEvent), pointFromEvent(domEvent), domEvent);\n        });\n        input.addListener('MSPointerCancel', function msPointerCancelCallback(domEvent) {\n          input.pointerCancel(domEvent.pointerId, msPointerType(domEvent), pointFromEvent(domEvent), domEvent);\n        });\n        input.addImmediateListener('MSPointerUp', function msPointerUpCallback(domEvent) {\n          input.pointerUpImmediate(domEvent.pointerId, msPointerType(domEvent), pointFromEvent(domEvent), domEvent);\n        });\n      } else {\n        sceneryEventLog && sceneryEventLog('No pointer events support detected, using mouse/touch events');\n        input.addListener('mousedown', function mouseDownCallback(domEvent) {\n          input.mouseDown(pointFromEvent(domEvent), domEvent);\n        });\n        input.addListener('mouseup', function mouseUpCallback(domEvent) {\n          input.mouseUp(pointFromEvent(domEvent), domEvent);\n        });\n        input.addListener('mousemove', function mouseMoveCallback(domEvent) {\n          input.mouseMove(pointFromEvent(domEvent), domEvent);\n        });\n        input.addListener('mouseover', function mouseOverCallback(domEvent) {\n          input.mouseOver(pointFromEvent(domEvent), domEvent);\n        });\n        input.addListener('mouseout', function mouseOutCallback(domEvent) {\n          input.mouseOut(pointFromEvent(domEvent), domEvent);\n        });\n        input.addImmediateListener('mouseup', function mouseUpCallback(domEvent) {\n          input.mouseUpImmediate(pointFromEvent(domEvent), domEvent);\n        });\n        input.addListener('touchstart', function touchStartCallback(domEvent) {\n          sceneryEventLog && sceneryEventLog('touchstart (multiple events)');\n          forEachChangedTouch(domEvent, function touchStartTouch(id, point) {\n            input.touchStart(id, point, domEvent);\n          });\n        });\n        input.addListener('touchend', function touchEndCallback(domEvent) {\n          sceneryEventLog && sceneryEventLog('touchend (multiple events)');\n          forEachChangedTouch(domEvent, function touchEndTouch(id, point) {\n            input.touchEnd(id, point, domEvent);\n          });\n        });\n        input.addListener('touchmove', function touchMoveCallback(domEvent) {\n          sceneryEventLog && sceneryEventLog('touchmove (multiple events)');\n          forEachChangedTouch(domEvent, function touchMoveTouch(id, point) {\n            input.touchMove(id, point, domEvent);\n          });\n        });\n        input.addListener('touchcancel', function touchCancelCallback(domEvent) {\n          sceneryEventLog && sceneryEventLog('touchcancel (multiple events)');\n          forEachChangedTouch(domEvent, function touchCancelTouch(id, point) {\n            input.touchCancel(id, point, domEvent);\n          });\n        });\n        input.addImmediateListener('touchend', function touchEndCallback(domEvent) {\n          sceneryEventLog && sceneryEventLog('touchend immediate (multiple events)');\n          forEachChangedTouch(domEvent, function touchEndTouch(id, point) {\n            input.touchEndImmediate(id, point, domEvent);\n          });\n        });\n      }\n      input.addListener('keyup', function keyUpCallback(domEvent) {\n        input.keyUp(domEvent);\n      });\n      input.addListener('keydown', function keyDownCallback(domEvent) {\n        input.keyDown(domEvent);\n      });\n      input.addListener('keypress', function keyPressCallback(domEvent) {\n        input.keyPress(domEvent);\n      });\n    },\n    getTrailFromKeyboardFocus: function () {\n      return new scenery.Trail(this);\n    },\n    fireBatchedEvents: function () {\n      this.input.fireBatchedEvents();\n    },\n    resizeOnWindowResize: function () {\n      var scene = this;\n      var resizer = function () {\n        scene.resize(window.innerWidth, window.innerHeight);\n      };\n      $(window).resize(resizer);\n      resizer();\n    },\n    layerAudit: function () {\n      var scene = this;\n      var boundaries = this.calculateBoundaries(null, null, null);\n      sceneryAssert && sceneryAssert(boundaries.length === this.layers.length + 1, 'boundary count (' + boundaries.length + ') does not match layer count (' + this.layers.length + ') + 1');\n      var eachTrailUnderPaintedCount = 0;\n      new scenery.Trail(this).eachTrailUnder(function (trail) {\n        if (trail.isPainted()) {\n          eachTrailUnderPaintedCount++;\n          sceneryAssert && sceneryAssert(trail.getInstance(), 'every painted trail must have an instance');\n        }\n        sceneryAssert && sceneryAssert(trail.getInstance() && trail.getInstance().trail.equals(trail), 'every trail must have a single corresponding instance');\n      });\n      var layerPaintedCount = 0;\n      _.each(this.layers, function (layer) {\n        layerPaintedCount += layer.getLayerTrails().length;\n        layer.startPaintedTrail.reindex();\n        layer.endPaintedTrail.reindex();\n      });\n      var layerIterationPaintedCount = 0;\n      _.each(this.layers, function (layer) {\n        var selfCount = 0;\n        scenery.Trail.eachPaintedTrailBetween(layer.startPaintedTrail, layer.endPaintedTrail, function (trail) {\n          selfCount++;\n        }, false, scene);\n        sceneryAssert && sceneryAssert(selfCount > 0, 'every layer must have at least one self trail');\n        layerIterationPaintedCount += selfCount;\n      });\n      sceneryAssert && sceneryAssert(eachTrailUnderPaintedCount === layerPaintedCount, 'cross-referencing self trail counts: layerPaintedCount, ' + eachTrailUnderPaintedCount + ' vs ' + layerPaintedCount);\n      sceneryAssert && sceneryAssert(eachTrailUnderPaintedCount === layerIterationPaintedCount, 'cross-referencing self trail counts: layerIterationPaintedCount, ' + eachTrailUnderPaintedCount + ' vs ' + layerIterationPaintedCount);\n      _.each(this.layers, function (layer) {\n        sceneryAssert && sceneryAssert(layer.startPaintedTrail.compare(layer.endPaintedTrail) <= 0, 'proper ordering on layer trails');\n      });\n      for (var i = 1; i < this.layers.length; i++) {\n        sceneryAssert && sceneryAssert(this.layers[i - 1].endPaintedTrail.compare(this.layers[i].startPaintedTrail) === -1, 'proper ordering of layer trail boundaries in scene.layers array');\n        sceneryAssert && sceneryAssert(this.layers[i - 1].endBoundary === this.layers[i].startBoundary, 'proper sharing of boundaries');\n      }\n      _.each(this.layers, function (layer) {\n        var layerTrails = layer.getLayerTrails();\n        var computedTrails = [];\n        scenery.Trail.eachPaintedTrailBetween(layer.startPaintedTrail, layer.endPaintedTrail, function (trail) {\n          computedTrails.push(trail.copy());\n        }, false, scene);\n        sceneryAssert && sceneryAssert(layerTrails.length === computedTrails.length, 'layer has incorrect number of tracked trails');\n        _.each(layerTrails, function (trail) {\n          sceneryAssert && sceneryAssert(_.some(computedTrails, function (otherTrail) {\n            return trail.equals(otherTrail);\n          }), 'layer has a tracked trail discrepancy');\n        });\n        scenery.Trail.eachTrailBetween(layer.startPaintedTrail, layer.endPaintedTrail, function (trail) {\n          var node = trail.lastNode();\n          sceneryAssert && sceneryAssert(!node.renderer || node.renderer.name === layer.type.name, 'specified renderers should match the layer renderer');\n        }, false, scene);\n      });\n      new scenery.Trail(this).eachTrailUnder(function (trail) {\n        var beforeSplitTrail;\n        var afterSplitTrail;\n        if (trail.lastNode().layerSplitBefore) {\n          beforeSplitTrail = trail.previousPainted();\n          afterSplitTrail = trail.lastNode().isPainted() ? trail : trail.nextPainted();\n          sceneryAssert && sceneryAssert(!beforeSplitTrail || !afterSplitTrail || beforeSplitTrail.getInstance().layer !== afterSplitTrail.getInstance().layer, 'layerSplitBefore layers need to be different');\n        }\n        if (trail.lastNode().layerSplitAfter) {\n          var ptr = new scenery.TrailPointer(trail.copy(), false);\n          while (ptr && ptr.isAfter) {\n            ptr = ptr.nestedForwards();\n          }\n          if (ptr) {\n            beforeSplitTrail = ptr.trail.previousPainted();\n            afterSplitTrail = ptr.trail.lastNode().isPainted() ? ptr.trail : ptr.trail.nextPainted();\n            sceneryAssert && sceneryAssert(!beforeSplitTrail || !afterSplitTrail || beforeSplitTrail.getInstance().layer !== afterSplitTrail.getInstance().layer, 'layerSplitAfter layers need to be different');\n          }\n        }\n      });\n      return true;\n    },\n    getDebugHTML: function () {\n      var startPointer = new scenery.TrailPointer(new scenery.Trail(this), true);\n      var endPointer = new scenery.TrailPointer(new scenery.Trail(this), false);\n      function str(ob) {\n        return ob ? ob.toString() : ob;\n      }\n      var depth = 0;\n      var result = '';\n      var layerStartEntries = {};\n      var layerEndEntries = {};\n      _.each(this.layers, function (layer) {\n        var startIdx = layer.startPaintedTrail.getUniqueId();\n        var endIndex = layer.endPaintedTrail.getUniqueId();\n        layerStartEntries[startIdx] = '';\n        layerEndEntries[endIndex] = '';\n        layer.startPaintedTrail.reindex();\n        layer.endPaintedTrail.reindex();\n        var layerInfo = layer.getId() + ' <strong>' + layer.type.name + '</strong>' + ' trails: ' + (layer.startPaintedTrail ? str(layer.startPaintedTrail) : layer.startPaintedTrail) + ',' + (layer.endPaintedTrail ? str(layer.endPaintedTrail) : layer.endPaintedTrail);\n        layerInfo += '<span style=\"color: #008\">';\n        if (layer.canUseDirtyRegions && !layer.canUseDirtyRegions()) {\n          layerInfo += ' dirtyRegionsDisabled';\n        }\n        if (layer.cssTranslation) {\n          layerInfo += ' cssTranslation';\n        }\n        if (layer.cssRotation) {\n          layerInfo += ' cssTranslation';\n        }\n        if (layer.cssScale) {\n          layerInfo += ' cssTranslation';\n        }\n        if (layer.cssTransform) {\n          layerInfo += ' cssTranslation';\n        }\n        if (layer.dirtyBounds && layer.dirtyBounds.isFinite()) {\n          layerInfo += ' dirtyBounds:' + layer.dirtyBounds.toString();\n        }\n        layerInfo += '</span>';\n        layerStartEntries[startIdx] += '<div style=\"color: #080\">+Layer ' + layerInfo + '</div>';\n        layerEndEntries[endIndex] += '<div style=\"color: #800\">-Layer ' + layerInfo + '</div>';\n      });\n      startPointer.depthFirstUntil(endPointer, function (pointer) {\n        var div;\n        var ptr = str(pointer);\n        var node = pointer.trail.lastNode();\n        function addQualifier(text) {\n          div += ' <span style=\"color: #008\">' + text + '</span>';\n        }\n        if (pointer.isBefore && layerStartEntries[pointer.trail.getUniqueId()]) {\n          result += layerStartEntries[pointer.trail.getUniqueId()];\n        }\n        if (pointer.isBefore) {\n          div = '<div style=\"margin-left: ' + depth * 20 + 'px\">';\n          if (node.constructor.name) {\n            div += ' ' + node.constructor.name;\n          }\n          div += ' <span style=\"font-weight: ' + (node.isPainted() ? 'bold' : 'normal') + '\">' + pointer.trail.lastNode().getId() + '</span>';\n          div += ' <span style=\"color: #888\">' + str(pointer.trail) + '</span>';\n          if (!node._visible) {\n            addQualifier('invisible');\n          }\n          if (!node._pickable) {\n            addQualifier('unpickable');\n          }\n          if (node._clipShape) {\n            addQualifier('clipShape');\n          }\n          if (node._renderer) {\n            addQualifier('renderer:' + node._renderer.name);\n          }\n          if (node._rendererOptions) {\n          }\n          if (node._layerSplitBefore) {\n            addQualifier('layerSplitBefore');\n          }\n          if (node._layerSplitAfter) {\n            addQualifier('layerSplitAfter');\n          }\n          if (node._opacity < 1) {\n            addQualifier('opacity:' + node._opacity);\n          }\n          var transformType = '';\n          switch (node.transform.getMatrix().type) {\n          case Matrix3.Types.IDENTITY:\n            transformType = '';\n            break;\n          case Matrix3.Types.TRANSLATION_2D:\n            transformType = 'translated';\n            break;\n          case Matrix3.Types.SCALING:\n            transformType = 'scale';\n            break;\n          case Matrix3.Types.AFFINE:\n            transformType = 'affine';\n            break;\n          case Matrix3.Types.OTHER:\n            transformType = 'other';\n            break;\n          }\n          if (transformType) {\n            div += ' <span style=\"color: #88f\" title=\"' + node.transform.getMatrix().toString().replace('\\n', '&#10;') + '\">' + transformType + '</span>';\n          }\n          div += '</div>';\n          result += div;\n        }\n        if (pointer.isAfter && layerEndEntries[pointer.trail.getUniqueId()]) {\n          result += layerEndEntries[pointer.trail.getUniqueId()];\n        }\n        depth += pointer.isBefore ? 1 : -1;\n      }, false);\n      return result;\n    },\n    popupDebug: function () {\n      var htmlContent = '<!DOCTYPE html>' + '<html lang=\"en\">' + '<head><title>Scenery Debug Snapshot</title></head>' + '<body>' + this.getDebugHTML() + '</body>' + '</html>';\n      window.open('data:text/html;charset=utf-8,' + encodeURIComponent(htmlContent));\n    },\n    getBasicConstructor: function (propLines) {\n      return 'new scenery.Scene( $( \\'#main\\' ), {' + propLines + '} )';\n    },\n    toStringWithChildren: function (mutateScene) {\n      var scene = this;\n      var result = '';\n      var nodes = this.getTopologicallySortedNodes().slice(0).reverse();\n      function name(node) {\n        return node === scene ? 'scene' : node.constructor.name.toLowerCase() + node.id;\n      }\n      _.each(nodes, function (node) {\n        if (result) {\n          result += '\\n';\n        }\n        if (mutateScene && node === scene) {\n          var props = scene.getPropString('  ', false);\n          result += 'scene.mutate( {' + (props ? '\\n' + props + '\\n' : '') + '} )';\n        } else {\n          result += 'var ' + name(node) + ' = ' + node.toString('', false);\n        }\n        _.each(node.children, function (child) {\n          result += '\\n' + name(node) + '.addChild( ' + name(child) + ' );';\n        });\n      });\n      return result;\n    }\n  });\n  function applyCSSHacks($main, options) {\n    if (!options.allowSceneOverflow) {\n      $main.css('overflow', 'hidden');\n    }\n    $main.css('-ms-touch-action', 'none');\n    if (options.allowCSSHacks) {\n      (function () {\n        var prefixes = [\n            '-webkit-',\n            '-moz-',\n            '-ms-',\n            '-o-',\n            ''\n          ];\n        var properties = {\n            userSelect: 'none',\n            touchCallout: 'none',\n            touchAction: 'none',\n            userDrag: 'none',\n            tapHighlightColor: 'rgba(0,0,0,0)'\n          };\n        _.each(prefixes, function (prefix) {\n          _.each(properties, function (propertyValue, propertyName) {\n            $main.css(prefix + propertyName, propertyValue);\n          });\n        });\n      }());\n    }\n  }\n  return Scene;\n});",
    "\ndefine('SUN/FontAwesomeNode',['require','SCENERY/nodes/Image','SCENERY/nodes/VBox','SCENERY/nodes/DOM','SCENERY/nodes/Node','SCENERY/nodes/HBox','SCENERY/Scene','SCENERY/nodes/Text','SCENERY/nodes/Path','SCENERY/nodes/Rectangle','KITE/Shape','SCENERY/input/SimpleDragHandler','DOT/Bounds2','DOT/Matrix3','PHET_CORE/inherit'],function (require) {\n  'use strict';\n  var Image = require('SCENERY/nodes/Image');\n  var VBox = require('SCENERY/nodes/VBox');\n  var DOM = require('SCENERY/nodes/DOM');\n  var Node = require('SCENERY/nodes/Node');\n  var HBox = require('SCENERY/nodes/HBox');\n  var Scene = require('SCENERY/Scene');\n  var Text = require('SCENERY/nodes/Text');\n  var Path = require('SCENERY/nodes/Path');\n  var Rectangle = require('SCENERY/nodes/Rectangle');\n  var Shape = require('KITE/Shape');\n  var SimpleDragHandler = require('SCENERY/input/SimpleDragHandler');\n  var Bounds2 = require('DOT/Bounds2');\n  var Matrix3 = require('DOT/Matrix3');\n  var inherit = require('PHET_CORE/inherit');\n  var icons = {\n      fullscreen: 'M1283 995l-355 -355l355 -355l144 144q29 31 70 14q39 -17 39 -59v-448q0 -26 -19 -45t-45 -19h-448q-42 0 -59 40q-17 39 14 69l144 144l-355 355l-355 -355l144 -144q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19t-19 45v448q0 42 40 59q39 17 69 -14l144 -144 l355 355l-355 355l-144 -144q-19 -19 -45 -19q-12 0 -24 5q-40 17 -40 59v448q0 26 19 45t45 19h448q42 0 59 -40q17 -39 -14 -69l-144 -144l355 -355l355 355l-144 144q-31 30 -14 69q17 40 59 40h448q26 0 45 -19t19 -45v-448q0 -42 -39 -59q-13 -5 -25 -5q-26 0 -45 19z',\n      reorder: 'M1536 192v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1536 704v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1536 1216v-128q0 -26 -19 -45 t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z',\n      home: 'M1408 544v-480q0 -26 -19 -45t-45 -19h-384v384h-256v-384h-384q-26 0 -45 19t-19 45v480q0 1 0.5 3t0.5 3l575 474l575 -474q1 -2 1 -6zM1631 613l-62 -74q-8 -9 -21 -11h-3q-13 0 -21 7l-692 577l-692 -577q-12 -8 -24 -7q-13 2 -21 11l-62 74q-8 10 -7 23.5t11 21.5 l719 599q32 26 76 26t76 -26l244 -204v195q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-408l219 -182q10 -8 11 -21.5t-7 -23.5z',\n      volume_off: 'M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45z',\n      volume_up: 'M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45zM1152 640q0 -76 -42.5 -141.5t-112.5 -93.5q-10 -5 -25 -5q-26 0 -45 18.5t-19 45.5q0 21 12 35.5t29 25t34 23t29 35.5 t12 57t-12 57t-29 35.5t-34 23t-29 25t-12 35.5q0 27 19 45.5t45 18.5q15 0 25 -5q70 -27 112.5 -93t42.5 -142zM1408 640q0 -153 -85 -282.5t-225 -188.5q-13 -5 -25 -5q-27 0 -46 19t-19 45q0 39 39 59q56 29 76 44q74 54 115.5 135.5t41.5 173.5t-41.5 173.5 t-115.5 135.5q-20 15 -76 44q-39 20 -39 59q0 26 19 45t45 19q13 0 26 -5q140 -59 225 -188.5t85 -282.5zM1664 640q0 -230 -127 -422.5t-338 -283.5q-13 -5 -26 -5q-26 0 -45 19t-19 45q0 36 39 59q7 4 22.5 10.5t22.5 10.5q46 25 82 51q123 91 192 227t69 289t-69 289 t-192 227q-36 26 -82 51q-7 4 -22.5 10.5t-22.5 10.5q-39 23 -39 59q0 26 19 45t45 19q13 0 26 -5q211 -91 338 -283.5t127 -422.5z',\n      check: 'M1408 606v-318q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q63 0 117 -25q15 -7 18 -23q3 -17 -9 -29l-49 -49q-10 -10 -23 -10q-3 0 -9 2q-23 6 -45 6h-832q-66 0 -113 -47t-47 -113v-832 q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v254q0 13 9 22l64 64q10 10 23 10q6 0 12 -3q20 -8 20 -29zM1639 1095l-814 -814q-24 -24 -57 -24t-57 24l-430 430q-24 24 -24 57t24 57l110 110q24 24 57 24t57 -24l263 -263l647 647q24 24 57 24t57 -24l110 -110 q24 -24 24 -57t-24 -57z',\n      check_empty: 'M1120 1280h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v832q0 66 -47 113t-113 47zM1408 1120v-832q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832 q119 0 203.5 -84.5t84.5 -203.5z',\n      undo: 'M1536 640q0 -156 -61 -298t-164 -245t-245 -164t-298 -61q-179 0 -336.5 76t-266 213t-147.5 312q-3 14 7 27q9 12 25 12h199q23 0 30 -23q50 -162 185 -261.5t304 -99.5q104 0 198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5t-40.5 198.5t-109.5 163.5t-163.5 109.5 t-198.5 40.5q-98 0 -188 -35.5t-160 -101.5l137 -138q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19t-19 45v448q0 42 40 59q39 17 69 -14l130 -129q107 101 244.5 156.5t284.5 55.5q156 0 298 -61t245 -164t164 -245t61 -298z'\n    };\n  function FontAwesomeNode(iconName, options) {\n    options = _.extend({\n      fill: '#000',\n      pickable: false\n    }, options);\n    options = _.extend(options, { matrix: new Matrix3(0.025, 0, 0, 0, -0.025, 0, 0, 0, 1) });\n    Path.call(this, new Shape(icons[iconName]), options);\n  }\n  inherit(Path, FontAwesomeNode);\n  return FontAwesomeNode;\n});",
    "\ndefine('SUN/CheckBox',['require','SCENERY/input/ButtonListener','SUN/FontAwesomeNode','SCENERY/nodes/Image','PHET_CORE/inherit','SCENERY/nodes/Node','SCENERY/nodes/Rectangle','KITE/Shape','SCENERY/nodes/Text'],function (require) {\n  'use strict';\n  var ButtonListener = require('SCENERY/input/ButtonListener');\n  var FontAwesomeNode = require('SUN/FontAwesomeNode');\n  var Image = require('SCENERY/nodes/Image');\n  var inherit = require('PHET_CORE/inherit');\n  var Node = require('SCENERY/nodes/Node');\n  var Rectangle = require('SCENERY/nodes/Rectangle');\n  var Shape = require('KITE/Shape');\n  var Text = require('SCENERY/nodes/Text');\n  function CheckBox(content, property, options) {\n    var checkBox = this;\n    options = _.extend({\n      spacing: 5,\n      boxScale: 0.6,\n      cursor: 'pointer',\n      checkBoxColor: 'black',\n      checkBoxColorDisabled: 'gray',\n      touchAreaTopPadding: 0,\n      touchAreaBottomPadding: 0,\n      touchAreaLeftPadding: 0,\n      touchAreaRightPadding: 0\n    }, options);\n    var thisNode = this;\n    Node.call(this);\n    thisNode._options = options;\n    thisNode._content = content;\n    thisNode._enabled = true;\n    var x = options.boxScale / 0.75;\n    var whiteBackground = new Rectangle(0, -25 * x, 25 * x, 25 * x, 5 * x, 5 * x, { fill: 'white' });\n    thisNode._checkedNode = new FontAwesomeNode('check', {\n      scale: options.boxScale,\n      fill: options.checkBoxColor\n    });\n    thisNode._uncheckedNode = new FontAwesomeNode('check_empty', {\n      scale: options.boxScale,\n      fill: options.checkBoxColor\n    });\n    thisNode.addChild(whiteBackground);\n    thisNode.addChild(thisNode._checkedNode);\n    thisNode.addChild(thisNode._uncheckedNode);\n    thisNode.addChild(content);\n    content.left = thisNode._checkedNode.right + options.spacing;\n    content.centerY = thisNode._checkedNode.centerY;\n    thisNode.mouseArea = thisNode.touchArea = Shape.rectangle(thisNode.left - options.touchAreaLeftPadding, thisNode.top - options.touchAreaTopPadding, thisNode.width + options.touchAreaLeftPadding + options.touchAreaRightPadding, thisNode.height + options.touchAreaTopPadding + options.touchAreaBottomPadding);\n    content.pickable = false;\n    thisNode.addInputListener(new ButtonListener({\n      fire: function () {\n        if (thisNode._enabled) {\n          property.value = !property.value;\n        }\n      }\n    }));\n    property.link(function (checked) {\n      thisNode._checkedNode.visible = checked;\n      thisNode._uncheckedNode.visible = !checked;\n    });\n    thisNode.addPeer('<input type=\"checkbox\">', {\n      click: function () {\n        property.value = !property.value;\n      },\n      label: options.label\n    });\n    property.link(function (value) {\n      _.each(checkBox.instances, function (instance) {\n        _.each(instance.peers, function (peer) {\n          peer.element.setAttribute('checked', value);\n        });\n      });\n    });\n    thisNode.mutate(options);\n  }\n  return inherit(Node, CheckBox, {\n    get enabled() {\n      return this._enabled;\n    },\n    set enabled(value) {\n      this._enabled = value;\n      this._checkedNode.fill = value ? this._options.checkBoxColor : this._options.checkBoxColorDisabled;\n      this._uncheckedNode.fill = this._checkedNode.fill;\n      if (this._content.setEnabled) {\n        this._content.setEnabled(value);\n      }\n    }\n  }, {\n    createTextCheckBox: function (text, textOptions, property, checkBoxOptions) {\n      textOptions = _.extend({\n        stroke: 'black',\n        strokeDisabled: 'rgb(220,220,220)'\n      }, textOptions);\n      checkBoxOptions = _.extend({\n        icon: null,\n        iconSpacing: 5\n      }, checkBoxOptions);\n      var content = new Node();\n      var textNode = new Text(text, textOptions);\n      content.addChild(textNode);\n      if (checkBoxOptions.icon) {\n        content.addChild(checkBoxOptions.icon);\n        checkBoxOptions.icon.left = textNode.right + checkBoxOptions.iconSpacing;\n        checkBoxOptions.icon.centerY = textNode.centerY;\n      }\n      content.setEnabled = function (enabled) {\n        textNode.stroke = enabled ? textOptions.stroke : textOptions.strokeDisabled;\n        if (checkBoxOptions.icon && checkBoxOptions.icon.setEnabled) {\n          checkBoxOptions.icon.setEnabled(enabled);\n        }\n      };\n      return new CheckBox(content, property, checkBoxOptions);\n    }\n  });\n});",
    "\ndefine('SUN/VerticalCheckBoxGroup',['require','SCENERY/nodes/Path','SUN/CheckBox','SCENERY/nodes/VBox','SCENERY/nodes/HBox','SCENERY/nodes/Rectangle','KITE/Shape','PHET_CORE/inherit'],function (require) {\n  'use strict';\n  var Path = require('SCENERY/nodes/Path');\n  var CheckBox = require('SUN/CheckBox');\n  var VBox = require('SCENERY/nodes/VBox');\n  var HBox = require('SCENERY/nodes/HBox');\n  var Rectangle = require('SCENERY/nodes/Rectangle');\n  var Shape = require('KITE/Shape');\n  var inherit = require('PHET_CORE/inherit');\n  function VerticalCheckBoxGroup(items, options) {\n    options = _.extend({\n      spacing: 10,\n      checkBoxColor: 'black'\n    }, options);\n    var padding = options.padding ? options.padding : 8;\n    var width = 0;\n    for (var i = 0; i < items.length; i++) {\n      width = Math.max(width, items[i].content.width);\n    }\n    var children = [];\n    for (i = 0; i < items.length; i++) {\n      var offset = items[i].indent || 0;\n      var content = new Path(Shape.rect(0, 0, width + padding - offset, 0), {\n          children: [items[i].content],\n          renderer: 'svg'\n        });\n      var checkBox = new CheckBox(content, items[i].property, {\n          label: items[i].label,\n          checkBoxColor: options.checkBoxColor,\n          touchAreaTopPadding: 5,\n          touchAreaBottomPadding: 5,\n          touchAreaLeftPadding: 5,\n          touchAreaRightPadding: 5\n        });\n      if (items[i].indent) {\n        children.push(new HBox({\n          children: [\n            new Rectangle(0, 0, items[i].indent, 1),\n            checkBox\n          ]\n        }));\n      } else {\n        children.push(new HBox({ children: [checkBox] }));\n      }\n    }\n    options.children = children;\n    options.renderer = 'svg';\n    options.align = 'left';\n    VBox.call(this, options);\n  }\n  return inherit(VBox, VerticalCheckBoxGroup);\n});",
    "\ndefine('common/view/AtomView',['require','SUN/AccordionBox','SUN/AquaRadioButton','common/view/AtomNode','SCENERY_PHET/PhetFont','buildanatom/view/BucketDragHandler','SCENERY_PHET/bucket/BucketFront','SCENERY_PHET/bucket/BucketHole','PHET_CORE/inherit','PHETCOMMON/view/ModelViewTransform2','SCENERY/nodes/Node','SUN/Panel','common/view/ParticleCountDisplay','common/view/ParticleView','SCENERY/nodes/Path','buildanatom/view/PeriodicTableAndSymbol','common/view/ResetAllButton','JOIST/ScreenView','KITE/Shape','common/SharedConstants','SCENERY/nodes/Text','SUN/VerticalCheckBoxGroup'],function (require) {\n  'use strict';\n  var AccordionBox = require('SUN/AccordionBox');\n  var AquaRadioButton = require('SUN/AquaRadioButton');\n  var AtomNode = require('common/view/AtomNode');\n  var PhetFont = require('SCENERY_PHET/PhetFont');\n  var BucketDragHandler = require('buildanatom/view/BucketDragHandler');\n  var BucketFront = require('SCENERY_PHET/bucket/BucketFront');\n  var BucketHole = require('SCENERY_PHET/bucket/BucketHole');\n  var inherit = require('PHET_CORE/inherit');\n  var ModelViewTransform2 = require('PHETCOMMON/view/ModelViewTransform2');\n  var Node = require('SCENERY/nodes/Node');\n  var Panel = require('SUN/Panel');\n  var ParticleCountDisplay = require('common/view/ParticleCountDisplay');\n  var ParticleView = require('common/view/ParticleView');\n  var Path = require('SCENERY/nodes/Path');\n  var PeriodicTableAndSymbol = require('buildanatom/view/PeriodicTableAndSymbol');\n  var ResetAllButton = require('common/view/ResetAllButton');\n  var ScreenView = require('JOIST/ScreenView');\n  var Shape = require('KITE/Shape');\n  var SharedConstants = require('common/SharedConstants');\n  var Text = require('SCENERY/nodes/Text');\n  var VerticalCheckBoxGroup = require('SUN/VerticalCheckBoxGroup');\n  var CONTROLS_INSET = 10;\n  var LABEL_CONTROL_FONT = new PhetFont(32);\n  var ELECTRON_VIEW_CONTROL_FONT = new PhetFont(14);\n  var ACCORDION_BOX_FONT = new PhetFont(18);\n  var NUM_NUCLEON_LAYERS = 5;\n  function AtomView(model) {\n    ScreenView.call(this, { renderer: 'svg' });\n    var thisView = this;\n    this.model = model;\n    this.resetFunctions = [];\n    var mvt = ModelViewTransform2.createSinglePointScaleInvertedYMapping({\n        x: 0,\n        y: 0\n      }, {\n        x: thisView.layoutBounds.width * 0.275,\n        y: thisView.layoutBounds.height * 0.45\n      }, 1);\n    var atomNode = new AtomNode(model.particleAtom, mvt, {\n        showElementNameProperty: model.showElementNameProperty,\n        showNeutralOrIonProperty: model.showNeutralOrIonProperty,\n        showStableOrUnstableProperty: model.showStableOrUnstableProperty,\n        electronShellDepictionProperty: model.electronShellDepictionProperty\n      });\n    this.addChild(atomNode);\n    _.each(model.buckets, function (bucket) {\n      thisView.addChild(new BucketHole(bucket, mvt));\n    });\n    var nucleonLayers = [];\n    _.times(NUM_NUCLEON_LAYERS, function () {\n      var nucleonLayer = new Node();\n      nucleonLayers.push(nucleonLayer);\n      thisView.addChild(nucleonLayer);\n    });\n    nucleonLayers.reverse();\n    var electronLayer = new Node({ layerSplit: true });\n    this.addChild(electronLayer);\n    model.nucleons.forEach(function (nucleon) {\n      nucleonLayers[nucleon.zLayer].addChild(new ParticleView(nucleon, mvt));\n      nucleon.zLayerProperty.link(function (zLayer) {\n        null;\n        var onCorrectLayer = false;\n        nucleonLayers[zLayer].children.forEach(function (particleView) {\n          if (particleView.particle === nucleon) {\n            onCorrectLayer = true;\n          }\n        });\n        if (!onCorrectLayer) {\n          var particleView = null;\n          for (var layerIndex = 0; layerIndex < nucleonLayers.length && particleView === null; layerIndex++) {\n            for (var childIndex = 0; childIndex < nucleonLayers[layerIndex].children.length; childIndex++) {\n              if (nucleonLayers[layerIndex].children[childIndex].particle === nucleon) {\n                particleView = nucleonLayers[layerIndex].children[childIndex];\n                nucleonLayers[layerIndex].removeChildAt(childIndex);\n                break;\n              }\n            }\n          }\n          null;\n          nucleonLayers[zLayer].addChild(particleView);\n        }\n      });\n    });\n    model.electrons.forEach(function (electron) {\n      electronLayer.addChild(new ParticleView(electron, mvt));\n    });\n    var updateElectronVisibility = function () {\n      electronLayer.getChildren().forEach(function (electronNode) {\n        electronNode.visible = model.electronShellDepiction === 'orbits' || !model.particleAtom.electrons.contains(electronNode.particle);\n      });\n    };\n    model.particleAtom.electrons.lengthProperty.link(updateElectronVisibility);\n    model.electronShellDepictionProperty.link(updateElectronVisibility);\n    _.each(model.buckets, function (bucket) {\n      var bucketFront = new BucketFront(bucket, mvt);\n      thisView.addChild(bucketFront);\n      bucketFront.addInputListener(new BucketDragHandler(bucket, bucketFront, mvt));\n    });\n    var particleCountDisplay = new ParticleCountDisplay(model.numberAtom, 13, 250);\n    this.addChild(particleCountDisplay);\n    var periodicTable = new PeriodicTableAndSymbol(model.numberAtom).mutate({ pickable: false });\n    periodicTable.scale(0.55);\n    this.periodicTableBox = new AccordionBox(periodicTable, {\n      title: 'Element',\n      fill: SharedConstants.DISPLAY_PANEL_BACKGROUND_COLOR,\n      contentPosition: 'left',\n      titlePosition: 'left',\n      buttonPosition: 'right',\n      font: ACCORDION_BOX_FONT\n    });\n    this.addChild(this.periodicTableBox);\n    var labelVizControlPanel = new Panel(new VerticalCheckBoxGroup([\n        {\n          content: new Text('Element Name', { font: LABEL_CONTROL_FONT }),\n          property: model.showElementNameProperty,\n          label: 'Element Name'\n        },\n        {\n          content: new Text('Neutral/Ion', { font: LABEL_CONTROL_FONT }),\n          property: model.showNeutralOrIonProperty,\n          label: 'Neutral/Ion'\n        },\n        {\n          content: new Text('Stable/Unstable', { font: LABEL_CONTROL_FONT }),\n          property: model.showStableOrUnstableProperty,\n          label: 'Stable/Unstable'\n        }\n      ]), {\n        fill: 'rgb( 245, 245, 245 )',\n        xMargin: 15\n      });\n    var numDividerLines = 2;\n    var dividerLineShape = new Shape().moveTo(0, 0).lineTo(labelVizControlPanel.width, 0);\n    for (var dividerLines = 0; dividerLines < numDividerLines; dividerLines++) {\n      var dividerLine1 = new Path(dividerLineShape, {\n          lineWidth: 1,\n          stroke: 'gray',\n          centerY: labelVizControlPanel.height * (dividerLines + 1) / (numDividerLines + 1)\n        });\n      labelVizControlPanel.addChild(dividerLine1);\n    }\n    labelVizControlPanel.scale(0.55);\n    this.addChild(labelVizControlPanel);\n    var labelVizControlPanelTitle = new Text('Show', new PhetFont({\n        size: 16,\n        weight: 'bold'\n      }));\n    this.addChild(labelVizControlPanelTitle);\n    var radioButtonRadius = 6;\n    var orbitsButton = new AquaRadioButton(model.electronShellDepictionProperty, 'orbits', new Text('Orbits', ELECTRON_VIEW_CONTROL_FONT), { radius: radioButtonRadius });\n    var cloudButton = new AquaRadioButton(model.electronShellDepictionProperty, 'cloud', new Text('Cloud', ELECTRON_VIEW_CONTROL_FONT), { radius: radioButtonRadius });\n    var electronViewButtonGroup = new Node();\n    electronViewButtonGroup.addChild(new Text('Model:', {\n      font: new PhetFont({\n        size: 18,\n        weight: 'bold'\n      })\n    }));\n    orbitsButton.top = electronViewButtonGroup.bottom;\n    orbitsButton.left = electronViewButtonGroup.left + 5;\n    electronViewButtonGroup.addChild(orbitsButton);\n    cloudButton.top = electronViewButtonGroup.bottom + 3;\n    cloudButton.left = electronViewButtonGroup.left + 5;\n    electronViewButtonGroup.addChild(cloudButton);\n    this.addChild(electronViewButtonGroup);\n    this.resetFunctions.push(function () {\n      thisView.model.reset();\n      thisView.periodicTableBox.open.reset();\n    });\n    var resetButton = new ResetAllButton(function () {\n        thisView.resetFunctions.forEach(function (resetFunction) {\n          resetFunction();\n        });\n      });\n    resetButton.scale(0.8);\n    this.addChild(resetButton);\n    particleCountDisplay.top = CONTROLS_INSET;\n    particleCountDisplay.left = CONTROLS_INSET;\n    this.periodicTableBox.top = CONTROLS_INSET;\n    this.periodicTableBox.right = this.layoutBounds.width - CONTROLS_INSET;\n    labelVizControlPanel.left = this.periodicTableBox.left + 10;\n    labelVizControlPanel.bottom = this.layoutBounds.height - CONTROLS_INSET;\n    labelVizControlPanelTitle.bottom = labelVizControlPanel.top;\n    labelVizControlPanelTitle.centerX = labelVizControlPanel.centerX;\n    resetButton.centerX = (labelVizControlPanel.right + this.periodicTableBox.right) / 2;\n    resetButton.centerY = labelVizControlPanel.centerY;\n    electronViewButtonGroup.right = this.periodicTableBox.left - 30;\n    electronViewButtonGroup.bottom = atomNode.bottom + 5;\n  }\n  inherit(ScreenView, AtomView);\n  return AtomView;\n});",
    "\ndefine('KITE/shape',['require','ASSERT/assert','KITE/kite','DOT/Vector2','DOT/Bounds2','DOT/Ray2','DOT/Matrix3','DOT/Transform3','DOT/Util','DOT/Util','KITE/util/Subpath','KITE/../parser/svgPath','KITE/util/LineStyles','KITE/segments/Arc','KITE/segments/Cubic','KITE/segments/EllipticalArc','KITE/segments/Line','KITE/segments/Quadratic'],function (require) {\n  'use strict';\n  var assertExtra = require('ASSERT/assert')('kite.extra', true);\n  var kite = require('KITE/kite');\n  var Vector2 = require('DOT/Vector2');\n  var Bounds2 = require('DOT/Bounds2');\n  var Ray2 = require('DOT/Ray2');\n  var Matrix3 = require('DOT/Matrix3');\n  var Transform3 = require('DOT/Transform3');\n  var toDegrees = require('DOT/Util').toDegrees;\n  var lineLineIntersection = require('DOT/Util').lineLineIntersection;\n  var Subpath = require('KITE/util/Subpath');\n  var svgPath = require('KITE/../parser/svgPath');\n  require('KITE/util/LineStyles');\n  require('KITE/segments/Arc');\n  require('KITE/segments/Cubic');\n  require('KITE/segments/EllipticalArc');\n  require('KITE/segments/Line');\n  require('KITE/segments/Quadratic');\n  function p(x, y) {\n    return new Vector2(x, y);\n  }\n  function v(x, y) {\n    return new Vector2(x, y);\n  }\n  kite.Shape = function Shape(subpaths, bounds) {\n    this.subpaths = typeof subpaths === 'object' ? subpaths : [];\n    null;\n    this.bounds = bounds || Bounds2.NOTHING;\n    var that = this;\n    if (subpaths && typeof subpaths !== 'object') {\n      null;\n      _.each(svgPath.parse(subpaths), function (item) {\n        null;\n        that[item.cmd].apply(that, item.args);\n      });\n    }\n    phetAllocation && phetAllocation('Shape');\n  };\n  var Shape = kite.Shape;\n  Shape.prototype = {\n    constructor: Shape,\n    moveTo: function (x, y) {\n      return this.moveToPoint(v(x, y));\n    },\n    moveToRelative: function (x, y) {\n      return this.moveToPointRelative(v(x, y));\n    },\n    moveToPointRelative: function (point) {\n      return this.moveToPoint(this.getRelativePoint().plus(point));\n    },\n    moveToPoint: function (point) {\n      return this.addSubpath(new kite.Subpath().addPoint(point));\n    },\n    lineTo: function (x, y) {\n      return this.lineToPoint(v(x, y));\n    },\n    lineToRelative: function (x, y) {\n      return this.lineToPointRelative(v(x, y));\n    },\n    lineToPointRelative: function (point) {\n      return this.lineToPoint(this.getRelativePoint().plus(point));\n    },\n    lineToPoint: function (point) {\n      if (this.hasSubpaths()) {\n        var start = this.getLastSubpath().getLastPoint();\n        var end = point;\n        var line = new kite.Segment.Line(start, end);\n        this.getLastSubpath().addPoint(end);\n        if (!line.invalid) {\n          this.getLastSubpath().addSegment(line);\n          this.bounds = this.bounds.withPoint(start).withPoint(end);\n          null;\n        }\n      } else {\n        this.ensure(point);\n      }\n      return this;\n    },\n    horizontalLineTo: function (x) {\n      return this.lineTo(x, this.getRelativePoint().y);\n    },\n    horizontalLineToRelative: function (x) {\n      return this.lineToRelative(x, 0);\n    },\n    verticalLineTo: function (y) {\n      return this.lineTo(this.getRelativePoint().x, y);\n    },\n    verticalLineToRelative: function (y) {\n      return this.lineToRelative(0, y);\n    },\n    quadraticCurveTo: function (cpx, cpy, x, y) {\n      return this.quadraticCurveToPoint(v(cpx, cpy), v(x, y));\n    },\n    quadraticCurveToRelative: function (cpx, cpy, x, y) {\n      return this.quadraticCurveToPointRelative(v(cpx, cpy), v(x, y));\n    },\n    quadraticCurveToPointRelative: function (controlPoint, point) {\n      var relativePoint = this.getRelativePoint();\n      return this.quadraticCurveToPoint(relativePoint.plus(controlPoint), relativePoint.plus(point));\n    },\n    smoothQuadraticCurveTo: function (x, y) {\n      return this.quadraticCurveToPoint(this.getSmoothQuadraticControlPoint(), v(x, y));\n    },\n    smoothQuadraticCurveToRelative: function (x, y) {\n      return this.quadraticCurveToPoint(this.getSmoothQuadraticControlPoint(), v(x, y).plus(this.getRelativePoint()));\n    },\n    quadraticCurveToPoint: function (controlPoint, point) {\n      this.ensure(controlPoint);\n      var start = this.getLastSubpath().getLastPoint();\n      var quadratic = new kite.Segment.Quadratic(start, controlPoint, point);\n      this.getLastSubpath().addPoint(point);\n      if (!quadratic.invalid) {\n        this.getLastSubpath().addSegment(quadratic);\n        this.bounds = this.bounds.union(quadratic.bounds);\n      }\n      return this;\n    },\n    cubicCurveTo: function (cp1x, cp1y, cp2x, cp2y, x, y) {\n      return this.cubicCurveToPoint(v(cp1x, cp1y), v(cp2x, cp2y), v(x, y));\n    },\n    cubicCurveToRelative: function (cp1x, cp1y, cp2x, cp2y, x, y) {\n      return this.cubicCurveToPointRelative(v(cp1x, cp1y), v(cp2x, cp2y), v(x, y));\n    },\n    cubicCurveToPointRelative: function (control1, control2, point) {\n      var relativePoint = this.getRelativePoint();\n      return this.cubicCurveToPoint(relativePoint.plus(control1), relativePoint.plus(control2), relativePoint.plus(point));\n    },\n    smoothCubicCurveTo: function (cp2x, cp2y, x, y) {\n      return this.cubicCurveToPoint(this.getSmoothCubicControlPoint(), v(cp2x, cp2y), v(x, y));\n    },\n    smoothCubicCurveToRelative: function (cp2x, cp2y, x, y) {\n      return this.cubicCurveToPoint(this.getSmoothCubicControlPoint(), v(cp2x, cp2y).plus(this.getRelativePoint()), v(x, y).plus(this.getRelativePoint()));\n    },\n    cubicCurveToPoint: function (control1, control2, point) {\n      this.ensure(control1);\n      var start = this.getLastSubpath().getLastPoint();\n      var cubic = new kite.Segment.Cubic(start, control1, control2, point);\n      if (!cubic.invalid) {\n        if (cubic.hasCusp()) {\n          this.getLastSubpath().addSegment(cubic.startQuadratic);\n          this.getLastSubpath().addSegment(cubic.endQuadratic);\n        } else {\n          this.getLastSubpath().addSegment(cubic);\n        }\n        this.bounds = this.bounds.union(cubic.bounds);\n      }\n      this.getLastSubpath().addPoint(point);\n      return this;\n    },\n    arc: function (centerX, centerY, radius, startAngle, endAngle, anticlockwise) {\n      return this.arcPoint(v(centerX, centerY), radius, startAngle, endAngle, anticlockwise);\n    },\n    arcPoint: function (center, radius, startAngle, endAngle, anticlockwise) {\n      var arc = new kite.Segment.Arc(center, radius, startAngle, endAngle, anticlockwise);\n      var startPoint = arc.start;\n      var endPoint = arc.end;\n      if (this.hasSubpaths() && this.getLastSubpath().getLength() > 0 && !startPoint.equals(this.getLastSubpath().getLastPoint(), 0)) {\n        this.getLastSubpath().addSegment(new kite.Segment.Line(this.getLastSubpath().getLastPoint(), startPoint));\n      }\n      if (!this.hasSubpaths()) {\n        this.addSubpath(new kite.Subpath());\n      }\n      this.getLastSubpath().addPoint(startPoint);\n      this.getLastSubpath().addPoint(endPoint);\n      if (!arc.invalid) {\n        this.getLastSubpath().addSegment(arc);\n        this.bounds = this.bounds.union(arc.bounds);\n      }\n      return this;\n    },\n    ellipticalArc: function (centerX, centerY, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise) {\n      return this.ellipticalArcPoint(v(centerX, centerY), radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise);\n    },\n    ellipticalArcPoint: function (center, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise) {\n      var ellipticalArc = new kite.Segment.EllipticalArc(center, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise);\n      var startPoint = ellipticalArc.start;\n      var endPoint = ellipticalArc.end;\n      if (this.hasSubpaths() && this.getLastSubpath().getLength() > 0 && !startPoint.equals(this.getLastSubpath().getLastPoint(), 0)) {\n        this.getLastSubpath().addSegment(new kite.Segment.Line(this.getLastSubpath().getLastPoint(), startPoint));\n      }\n      if (!this.hasSubpaths()) {\n        this.addSubpath(new kite.Subpath());\n      }\n      this.getLastSubpath().addPoint(startPoint);\n      this.getLastSubpath().addPoint(endPoint);\n      if (!ellipticalArc.invalid) {\n        this.getLastSubpath().addSegment(ellipticalArc);\n        this.bounds = this.bounds.union(ellipticalArc.bounds);\n      }\n      return this;\n    },\n    close: function () {\n      if (this.hasSubpaths()) {\n        var previousPath = this.getLastSubpath();\n        var nextPath = new kite.Subpath();\n        previousPath.close();\n        this.addSubpath(nextPath);\n        nextPath.addPoint(previousPath.getFirstPoint());\n      }\n      return this;\n    },\n    ellipticalArcToRelative: function (radiusX, radiusY, rotation, largeArc, sweep, x, y) {\n      var relativePoint = this.getRelativePoint();\n      return this.ellipticalArcTo(radiusX, radiusY, rotation, largeArc, sweep, x + relativePoint.x, y + relativePoint.y);\n    },\n    ellipticalArcTo: function (radiusX, radiusY, rotation, largeArc, sweep, x, y) {\n      throw new Error('ellipticalArcTo unimplemented');\n    },\n    circle: function (centerX, centerY, radius) {\n      if (typeof centerX === 'object') {\n        var center = centerX;\n        radius = centerY;\n        return this.arcPoint(center, radius, 0, Math.PI * 2, false);\n      } else {\n        return this.arcPoint(p(centerX, centerY), radius, 0, Math.PI * 2, false);\n      }\n    },\n    ellipse: function (centerX, centerY, radiusX, radiusY, rotation) {\n      if (typeof centerX === 'object') {\n        var center = centerX;\n        rotation = radiusY;\n        radiusY = radiusX;\n        radiusX = centerY;\n        return this.ellipticalArcPoint(center, radiusX, radiusY, rotation || 0, 0, Math.PI * 2, false);\n      } else {\n        return this.ellipticalArcPoint(v(centerX, centerY), radiusX, radiusY, rotation || 0, 0, Math.PI * 2, false);\n      }\n    },\n    rect: function (x, y, width, height) {\n      var subpath = new kite.Subpath();\n      this.addSubpath(subpath);\n      subpath.addPoint(v(x, y));\n      subpath.addPoint(v(x + width, y));\n      subpath.addPoint(v(x + width, y + height));\n      subpath.addPoint(v(x, y + height));\n      subpath.addSegment(new kite.Segment.Line(subpath.points[0], subpath.points[1]));\n      subpath.addSegment(new kite.Segment.Line(subpath.points[1], subpath.points[2]));\n      subpath.addSegment(new kite.Segment.Line(subpath.points[2], subpath.points[3]));\n      subpath.close();\n      this.addSubpath(new kite.Subpath());\n      this.getLastSubpath().addPoint(v(x, y));\n      this.bounds = this.bounds.withCoordinates(x, y).withCoordinates(x + width, y + height);\n      null;\n      return this;\n    },\n    roundRect: function (x, y, width, height, arcw, arch) {\n      var lowX = x + arcw;\n      var highX = x + width - arcw;\n      var lowY = y + arch;\n      var highY = y + height - arch;\n      if (arcw === arch) {\n        this.arc(highX, lowY, arcw, -Math.PI / 2, 0, false).arc(highX, highY, arcw, 0, Math.PI / 2, false).arc(lowX, highY, arcw, Math.PI / 2, Math.PI, false).arc(lowX, lowY, arcw, Math.PI, Math.PI * 3 / 2, false).close();\n      } else {\n        this.ellipticalArc(highX, lowY, arcw, arch, 0, -Math.PI / 2, 0, false).ellipticalArc(highX, highY, arcw, arch, 0, 0, Math.PI / 2, false).ellipticalArc(lowX, highY, arcw, arch, 0, Math.PI / 2, Math.PI, false).ellipticalArc(lowX, lowY, arcw, arch, 0, Math.PI, Math.PI * 3 / 2, false).close();\n      }\n      return this;\n    },\n    polygon: function (vertices) {\n      var length = vertices.length;\n      if (length > 0) {\n        this.moveToPoint(vertices[0]);\n        for (var i = 1; i < length; i++) {\n          this.lineToPoint(vertices[i]);\n        }\n      }\n      return this.close();\n    },\n    copy: function () {\n      return new Shape(_.map(this.subpaths, function (subpath) {\n        return subpath.copy();\n      }), this.bounds);\n    },\n    writeToContext: function (context) {\n      var len = this.subpaths.length;\n      for (var i = 0; i < len; i++) {\n        this.subpaths[i].writeToContext(context);\n      }\n    },\n    getSVGPath: function () {\n      var subpathStrings = [];\n      var len = this.subpaths.length;\n      for (var i = 0; i < len; i++) {\n        var subpath = this.subpaths[i];\n        if (subpath.isDrawable()) {\n          var startPoint = subpath.getFirstSegment().start;\n          null;\n          var string = 'M ' + startPoint.x + ' ' + startPoint.y + ' ';\n          string += _.map(subpath.segments, function (segment) {\n            return segment.getSVGPathFragment();\n          }).join(' ');\n          if (subpath.isClosed()) {\n            string += ' Z';\n          }\n          subpathStrings.push(string);\n        }\n      }\n      return subpathStrings.join(' ');\n    },\n    transformed: function (matrix) {\n      var subpaths = _.map(this.subpaths, function (subpath) {\n          return subpath.transformed(matrix);\n        });\n      var bounds = _.reduce(subpaths, function (bounds, subpath) {\n          return bounds.union(subpath.computeBounds());\n        }, Bounds2.NOTHING);\n      return new Shape(subpaths, bounds);\n    },\n    computeBounds: function (lineStyles) {\n      if (lineStyles) {\n        return this.bounds.union(this.getStrokedShape(lineStyles).bounds);\n      } else {\n        return this.bounds;\n      }\n    },\n    containsPoint: function (point) {\n      var ray = new Ray2(point, Vector2.X_UNIT);\n      return this.windingIntersection(ray) !== 0;\n    },\n    intersection: function (ray) {\n      var hits = [];\n      var numSubpaths = this.subpaths.length;\n      for (var i = 0; i < numSubpaths; i++) {\n        var subpath = this.subpaths[i];\n        if (subpath.isDrawable()) {\n          var numSegments = subpath.segments.length;\n          for (var k = 0; k < numSegments; k++) {\n            var segment = subpath.segments[k];\n            hits = hits.concat(segment.intersection(ray));\n          }\n          if (subpath.hasClosingSegment()) {\n            hits = hits.concat(subpath.getClosingSegment().intersection(ray));\n          }\n        }\n      }\n      return _.sortBy(hits, function (hit) {\n        return hit.distance;\n      });\n    },\n    windingIntersection: function (ray) {\n      var wind = 0;\n      var numSubpaths = this.subpaths.length;\n      for (var i = 0; i < numSubpaths; i++) {\n        var subpath = this.subpaths[i];\n        if (subpath.isDrawable()) {\n          var numSegments = subpath.segments.length;\n          for (var k = 0; k < numSegments; k++) {\n            wind += subpath.segments[k].windingIntersection(ray);\n          }\n          if (subpath.hasClosingSegment()) {\n            wind += subpath.getClosingSegment().windingIntersection(ray);\n          }\n        }\n      }\n      return wind;\n    },\n    intersectsBounds: function (bounds) {\n      var numSubpaths = this.subpaths.length;\n      for (var i = 0; i < numSubpaths; i++) {\n        var subpath = this.subpaths[i];\n        if (subpath.isDrawable()) {\n          var numSegments = subpath.segments.length;\n          for (var k = 0; k < numSegments; k++) {\n            if (subpath.segments[k].intersectsBounds(bounds)) {\n              return true;\n            }\n          }\n          if (subpath.hasClosingSegment()) {\n            if (subpath.getClosingSegment().intersectsBounds(bounds)) {\n              return true;\n            }\n          }\n        }\n      }\n      return false;\n    },\n    getStrokedShape: function (lineStyles) {\n      var subpaths = [];\n      var bounds = Bounds2.NOTHING.copy();\n      var subLen = this.subpaths.length;\n      for (var i = 0; i < subLen; i++) {\n        var subpath = this.subpaths[i];\n        var strokedSubpath = subpath.stroked(lineStyles);\n        subpaths = subpaths.concat(strokedSubpath);\n      }\n      subLen = subpaths.length;\n      for (i = 0; i < subLen; i++) {\n        bounds.includeBounds(subpaths[i].computeBounds());\n      }\n      return new Shape(subpaths, bounds);\n    },\n    toString: function () {\n      return 'new kite.Shape( \\'' + this.getSVGPath() + '\\' )';\n    },\n    ensure: function (point) {\n      if (!this.hasSubpaths()) {\n        this.addSubpath(new Subpath());\n        this.getLastSubpath().addPoint(point);\n      }\n    },\n    addSubpath: function (subpath) {\n      this.subpaths.push(subpath);\n      return this;\n    },\n    hasSubpaths: function () {\n      return this.subpaths.length > 0;\n    },\n    getLastSubpath: function () {\n      return _.last(this.subpaths);\n    },\n    getLastPoint: function () {\n      return this.hasSubpaths() ? this.getLastSubpath().getLastPoint() : null;\n    },\n    getLastSegment: function () {\n      if (!this.hasSubpaths()) {\n        return null;\n      }\n      var subpath = this.getLastSubpath();\n      if (!subpath.isDrawable()) {\n        return null;\n      }\n      return subpath.getLastSegment();\n    },\n    getSmoothQuadraticControlPoint: function () {\n      var lastPoint = this.getLastPoint();\n      var segment = this.getLastSegment();\n      if (!segment || !(segment instanceof kite.Segment.Quadratic)) {\n        return lastPoint;\n      }\n      return lastPoint.plus(lastPoint.minus(segment.control));\n    },\n    getSmoothCubicControlPoint: function () {\n      var lastPoint = this.getLastPoint();\n      var segment = this.getLastSegment();\n      if (!segment || !(segment instanceof kite.Segment.Cubic)) {\n        return lastPoint;\n      }\n      return lastPoint.plus(lastPoint.minus(segment.control2));\n    },\n    getRelativePoint: function () {\n      var lastPoint = this.getLastPoint();\n      return lastPoint ? lastPoint : Vector2.ZERO;\n    }\n  };\n  Shape.rectangle = function (x, y, width, height) {\n    return new Shape().rect(x, y, width, height);\n  };\n  Shape.rect = Shape.rectangle;\n  Shape.roundRect = function (x, y, width, height, arcw, arch) {\n    return new Shape().roundRect(x, y, width, height, arcw, arch);\n  };\n  Shape.roundRectangle = Shape.roundRect;\n  Shape.polygon = function (vertices) {\n    return new Shape().polygon(vertices);\n  };\n  Shape.bounds = function (bounds) {\n    return new Shape().rect(bounds.minX, bounds.minY, bounds.maxX - bounds.minX, bounds.maxY - bounds.minY);\n  };\n  Shape.lineSegment = function (a, b, c, d) {\n    if (typeof a === 'number') {\n      return new Shape().moveTo(a, b).lineTo(c, d);\n    } else {\n      return new Shape().moveToPoint(a).lineToPoint(b);\n    }\n  };\n  Shape.regularPolygon = function (sides, radius) {\n    var shape = new Shape();\n    _.each(_.range(sides), function (k) {\n      var point = Vector2.createPolar(radius, 2 * Math.PI * k / sides);\n      k === 0 ? shape.moveToPoint(point) : shape.lineToPoint(point);\n    });\n    return shape.close();\n  };\n  Shape.circle = function (centerX, centerY, radius) {\n    if (centerY === undefined) {\n      return new Shape().circle(0, 0, centerX);\n    }\n    return new Shape().circle(centerX, centerY, radius).close();\n  };\n  Shape.ellipse = function (centerX, centerY, radiusX, radiusY) {\n    if (radiusX === undefined) {\n      return new Shape().ellipse(0, 0, centerX, centerY);\n    }\n    return new Shape().ellipse(centerX, centerY, radiusX, radiusY).close();\n  };\n  Shape.arc = function (centerX, centerY, radius, startAngle, endAngle, anticlockwise) {\n    return new Shape().arc(centerX, centerY, radius, startAngle, endAngle, anticlockwise);\n  };\n  return Shape;\n});",
    "\ndefine('buildanatom/view/ChargeComparisonDisplay',['require','SCENERY/nodes/Node','KITE/shape','SCENERY/nodes/Rectangle','SCENERY/nodes/Path','PHET_CORE/inherit'],function (require) {\n  'use strict';\n  var Node = require('SCENERY/nodes/Node');\n  var Shape = require('KITE/shape');\n  var Rectangle = require('SCENERY/nodes/Rectangle');\n  var Path = require('SCENERY/nodes/Path');\n  var inherit = require('PHET_CORE/inherit');\n  var SYMBOL_WIDTH = 12;\n  var VERTICAL_INSET = 5;\n  var INTER_SYMBOL_DISTANCE = SYMBOL_WIDTH * 0.4;\n  var SYMBOL_LINE_WIDTH = SYMBOL_WIDTH * 0.3;\n  var ChargeComparisonDisplay = function ChargeComparisonDisplay(numberAtom) {\n    Node.call(this);\n    var MAX_CHARGE = 10;\n    var i;\n    var symbolLayer = new Node();\n    var minusSymbolShape = new Shape();\n    minusSymbolShape.moveTo(-SYMBOL_WIDTH / 2, -SYMBOL_LINE_WIDTH / 2);\n    minusSymbolShape.lineTo(SYMBOL_WIDTH / 2, -SYMBOL_LINE_WIDTH / 2);\n    minusSymbolShape.lineTo(SYMBOL_WIDTH / 2, SYMBOL_LINE_WIDTH / 2);\n    minusSymbolShape.lineTo(-SYMBOL_WIDTH / 2, SYMBOL_LINE_WIDTH / 2);\n    minusSymbolShape.close();\n    var minusSymbolPath = new Path(minusSymbolShape, {\n        stroke: 'black',\n        lineWidth: 1,\n        fill: 'rgb( 100, 100, 255 )',\n        left: INTER_SYMBOL_DISTANCE / 2,\n        centerY: VERTICAL_INSET + SYMBOL_WIDTH * 1.5\n      });\n    var minuses = [];\n    for (i = 0; i < MAX_CHARGE; i++) {\n      var minusSymbol = new Node({\n          children: [minusSymbolPath],\n          x: i * (SYMBOL_WIDTH + INTER_SYMBOL_DISTANCE)\n        });\n      minuses.push(minusSymbol);\n      symbolLayer.addChild(minusSymbol);\n    }\n    var plusSymbolShape = new Shape();\n    plusSymbolShape.moveTo(-SYMBOL_LINE_WIDTH / 2, -SYMBOL_LINE_WIDTH / 2);\n    plusSymbolShape.lineTo(-SYMBOL_LINE_WIDTH / 2, -SYMBOL_WIDTH / 2);\n    plusSymbolShape.lineTo(SYMBOL_LINE_WIDTH / 2, -SYMBOL_WIDTH / 2);\n    plusSymbolShape.lineTo(SYMBOL_LINE_WIDTH / 2, -SYMBOL_LINE_WIDTH / 2);\n    plusSymbolShape.lineTo(SYMBOL_WIDTH / 2, -SYMBOL_LINE_WIDTH / 2);\n    plusSymbolShape.lineTo(SYMBOL_WIDTH / 2, SYMBOL_LINE_WIDTH / 2);\n    plusSymbolShape.lineTo(SYMBOL_LINE_WIDTH / 2, SYMBOL_LINE_WIDTH / 2);\n    plusSymbolShape.lineTo(SYMBOL_LINE_WIDTH / 2, SYMBOL_WIDTH / 2);\n    plusSymbolShape.lineTo(-SYMBOL_LINE_WIDTH / 2, SYMBOL_WIDTH / 2);\n    plusSymbolShape.lineTo(-SYMBOL_LINE_WIDTH / 2, SYMBOL_LINE_WIDTH / 2);\n    plusSymbolShape.lineTo(-SYMBOL_WIDTH / 2, SYMBOL_LINE_WIDTH / 2);\n    plusSymbolShape.lineTo(-SYMBOL_WIDTH / 2, -SYMBOL_LINE_WIDTH / 2);\n    plusSymbolShape.close();\n    var plusSymbolPath = new Path(plusSymbolShape, {\n        stroke: 'black',\n        lineWidth: 1,\n        fill: 'red',\n        left: INTER_SYMBOL_DISTANCE / 2,\n        centerY: VERTICAL_INSET + SYMBOL_WIDTH / 2\n      });\n    var plusses = [];\n    for (i = 0; i < MAX_CHARGE; i++) {\n      var plusSymbol = new Node({\n          children: [plusSymbolPath],\n          x: i * (SYMBOL_WIDTH + INTER_SYMBOL_DISTANCE)\n        });\n      plusses.push(plusSymbol);\n      symbolLayer.addChild(plusSymbol);\n    }\n    var matchBox = new Rectangle(0, 0, INTER_SYMBOL_DISTANCE / 2, 2 * SYMBOL_WIDTH + 2 * VERTICAL_INSET, 4, 4, {\n        lineWidth: 1,\n        stroke: 'black',\n        visible: false\n      });\n    symbolLayer.addChild(matchBox);\n    var update = function (atom) {\n      for (var numProtons = 0; numProtons < MAX_CHARGE; numProtons++) {\n        plusses[numProtons].visible = numProtons < atom.protonCount;\n      }\n      for (var numElectrons = 0; numElectrons < MAX_CHARGE; numElectrons++) {\n        minuses[numElectrons].visible = numElectrons < atom.electronCount;\n      }\n      var numMatchedSymbols = Math.min(atom.protonCount, atom.electronCount);\n      matchBox.visible = numMatchedSymbols > 0;\n      matchBox.rectWidth = INTER_SYMBOL_DISTANCE / 2 + numMatchedSymbols * SYMBOL_WIDTH + (numMatchedSymbols - 0.5) * INTER_SYMBOL_DISTANCE;\n    };\n    this.addChild(new Rectangle(0, 0, SYMBOL_WIDTH, 2 * SYMBOL_WIDTH + 2 * VERTICAL_INSET, 0, 0, { fill: 'rgba( 0, 0, 0, 0 )' }));\n    numberAtom.particleCountProperty.link(function () {\n      update(numberAtom);\n    });\n    this.addChild(symbolLayer);\n  };\n  inherit(Node, ChargeComparisonDisplay);\n  return ChargeComparisonDisplay;\n});",
    "\ndefine('SCENERY_PHET/ArrowShape',['require','PHET_CORE/inherit','KITE/Shape','DOT/Vector2'],function (require) {\n  'use strict';\n  var inherit = require('PHET_CORE/inherit');\n  var Shape = require('KITE/Shape');\n  var Vector2 = require('DOT/Vector2');\n  function ArrowShape(tailX, tailY, tipX, tipY, options) {\n    options = _.extend({\n      tailWidth: 5,\n      headWidth: 10,\n      headHeight: 10,\n      doubleHead: false\n    }, options);\n    var thisShape = this;\n    Shape.call(thisShape);\n    if (tipX !== tailX || tipY !== tailY) {\n      var vector = new Vector2(tipX - tailX, tipY - tailY);\n      var xHatUnit = vector.normalized();\n      var yHatUnit = xHatUnit.rotated(Math.PI / 2);\n      var length = vector.magnitude();\n      options.headHeight = Math.min(options.headHeight, options.doubleHead ? 0.35 * length : 0.5 * length);\n      var getPoint = function (xHat, yHat) {\n        var x = xHatUnit.x * xHat + yHatUnit.x * yHat + tailX;\n        var y = xHatUnit.y * xHat + yHatUnit.y * yHat + tailY;\n        return new Vector2(x, y);\n      };\n      var points = [];\n      if (options.doubleHead) {\n        points.push(getPoint(0, 0));\n        points.push(getPoint(options.headHeight, options.headWidth / 2));\n        points.push(getPoint(options.headHeight, options.tailWidth / 2));\n      } else {\n        points.push(getPoint(0, options.tailWidth / 2));\n      }\n      points.push(getPoint(length - options.headHeight, options.tailWidth / 2));\n      points.push(getPoint(length - options.headHeight, options.headWidth / 2));\n      points.push(getPoint(length, 0));\n      points.push(getPoint(length - options.headHeight, -options.headWidth / 2));\n      points.push(getPoint(length - options.headHeight, -options.tailWidth / 2));\n      if (options.doubleHead) {\n        points.push(getPoint(options.headHeight, -options.tailWidth / 2));\n        points.push(getPoint(options.headHeight, -options.headWidth / 2));\n      } else {\n        points.push(getPoint(0, -options.tailWidth / 2));\n      }\n      thisShape.moveTo(points[0].x, points[0].y);\n      var tail = _.tail(points);\n      _.each(tail, function (element) {\n        thisShape.lineTo(element.x, element.y);\n      });\n      thisShape.close();\n    }\n  }\n  return inherit(Shape, ArrowShape);\n});",
    "\ndefine('SCENERY_PHET/ArrowNode',['require','SCENERY_PHET/ArrowShape','PHET_CORE/inherit','SCENERY/nodes/Path','SCENERY/nodes/Node'],function (require) {\n  'use strict';\n  var ArrowShape = require('SCENERY_PHET/ArrowShape');\n  var inherit = require('PHET_CORE/inherit');\n  var Path = require('SCENERY/nodes/Path');\n  var Node = require('SCENERY/nodes/Node');\n  function ArrowNode(tailX, tailY, tipX, tipY, options) {\n    options = _.extend({\n      headHeight: 10,\n      headWidth: 10,\n      tailWidth: 5,\n      doubleHead: false,\n      fill: 'black',\n      stroke: 'black',\n      lineWidth: 1\n    }, options);\n    null;\n    Path.call(this, new ArrowShape(tailX, tailY, tipX, tipY, options), options);\n  }\n  return inherit(Path, ArrowNode);\n});",
    "\ndefine('common/view/ChargeMeter',['require','SCENERY_PHET/ArrowNode','SCENERY_PHET/PhetFont','DOT/Dimension2','PHET_CORE/inherit','SCENERY/util/LinearGradient','SCENERY/nodes/Node','SCENERY/nodes/Path','SCENERY/nodes/Rectangle','KITE/Shape','SCENERY/nodes/Text','DOT/Vector2'],function (require) {\n  'use strict';\n  var ArrowNode = require('SCENERY_PHET/ArrowNode');\n  var PhetFont = require('SCENERY_PHET/PhetFont');\n  var Dimension2 = require('DOT/Dimension2');\n  var inherit = require('PHET_CORE/inherit');\n  var LinearGradient = require('SCENERY/util/LinearGradient');\n  var Node = require('SCENERY/nodes/Node');\n  var Path = require('SCENERY/nodes/Path');\n  var Rectangle = require('SCENERY/nodes/Rectangle');\n  var Shape = require('KITE/Shape');\n  var Text = require('SCENERY/nodes/Text');\n  var Vector2 = require('DOT/Vector2');\n  var WIDTH = 70;\n  var _MAX_CHARGE = 10;\n  var CHARGE_SYMBOL_WIDTH = 7;\n  var SYMBOL_LINE_WIDTH = 2;\n  var ChargeMeter = function ChargeMeter(numberAtom, options) {\n    Node.call(this);\n    options = _.extend({ showNumericalReadout: true }, options);\n    var backgroundHeight = options.showNumericalReadout ? WIDTH * 0.9 : WIDTH * 0.55;\n    var background = new Rectangle(0, 0, WIDTH, backgroundHeight, 7, 7, {\n        fill: 'rgb( 210, 210, 210 )',\n        stroke: 'gray',\n        lineWidth: 1\n      });\n    this.addChild(background);\n    var meterWindowShape = new Shape();\n    var meterWindowWidth = background.width * 0.8;\n    var meterWindowHeight = meterWindowWidth * 0.5;\n    meterWindowShape.moveTo(0, meterWindowHeight);\n    meterWindowShape.quadraticCurveTo(0, 0, meterWindowWidth / 2, 0);\n    meterWindowShape.quadraticCurveTo(meterWindowWidth, 0, meterWindowWidth, meterWindowHeight);\n    meterWindowShape.close();\n    var meterWindow = new Path(meterWindowShape, {\n        stroke: 'gray',\n        lineWidth: 2,\n        fill: new LinearGradient(0, 0, meterWindowWidth, 0).addColorStop(0, 'rgb( 0, 0, 255 )').addColorStop(0.5, 'white').addColorStop(1, 'rgb( 255, 0, 0 )'),\n        centerX: background.centerX,\n        top: 3\n      });\n    this.addChild(meterWindow);\n    var shadowOffset = 0.5;\n    var plusShape = new Shape().moveTo(-CHARGE_SYMBOL_WIDTH / 2, 0).lineTo(CHARGE_SYMBOL_WIDTH / 2, 0).moveTo(0, -CHARGE_SYMBOL_WIDTH / 2).lineTo(0, CHARGE_SYMBOL_WIDTH / 2);\n    var plusSymbol = new Node();\n    plusSymbol.addChild(new Path(plusShape, {\n      lineWidth: SYMBOL_LINE_WIDTH,\n      stroke: 'black',\n      centerX: shadowOffset,\n      centerY: shadowOffset\n    }));\n    plusSymbol.addChild(new Path(plusShape, {\n      lineWidth: SYMBOL_LINE_WIDTH,\n      stroke: 'rgb(255, 0, 0 )'\n    }));\n    plusSymbol.center = new Vector2(meterWindow.width * 0.7, meterWindow.height * 0.5);\n    meterWindow.addChild(plusSymbol);\n    var minusShape = new Shape().moveTo(-CHARGE_SYMBOL_WIDTH / 2, 0).lineTo(CHARGE_SYMBOL_WIDTH / 2, 0);\n    var minusSymbol = new Node();\n    minusSymbol.addChild(new Path(minusShape, {\n      lineWidth: SYMBOL_LINE_WIDTH,\n      stroke: 'black',\n      centerX: shadowOffset,\n      centerY: shadowOffset\n    }));\n    minusSymbol.addChild(new Path(minusShape, {\n      lineWidth: SYMBOL_LINE_WIDTH,\n      stroke: 'rgb(0, 0, 255 )'\n    }));\n    minusSymbol.center = new Vector2(meterWindow.width * 0.3, meterWindow.height * 0.5);\n    meterWindow.addChild(minusSymbol);\n    var meterNeedleLayer = new Node({\n        x: meterWindow.centerX,\n        y: meterWindow.bottom - 3\n      });\n    meterNeedleLayer.setScaleMagnitude(1, 0.9);\n    var meterNeedle = new ArrowNode(0, 0, 0, 3 - meterWindowHeight, {\n        headHeight: 7,\n        headWidth: 5,\n        tailWidth: 1\n      });\n    meterNeedleLayer.addChild(meterNeedle);\n    this.addChild(meterNeedleLayer);\n    var numericalReadout;\n    var readoutText;\n    var readoutSize = new Dimension2(WIDTH * 0.6, (background.height - meterWindow.height) * 0.6);\n    if (options.showNumericalReadout) {\n      numericalReadout = new Rectangle(0, 0, readoutSize.width, readoutSize.height, 3, 3, {\n        fill: 'white',\n        stroke: 'black',\n        lineWidth: 1,\n        top: meterWindow.bottom + 3,\n        centerX: background.centerX\n      });\n      this.addChild(numericalReadout);\n      readoutText = new Text(' ', {\n        font: new PhetFont({\n          size: 24,\n          weight: 'bold'\n        })\n      });\n      numericalReadout.addChild(readoutText);\n    }\n    numberAtom.chargeProperty.link(function (charge) {\n      meterNeedle.rotation = charge / _MAX_CHARGE * Math.PI * 0.4;\n      if (numericalReadout !== undefined) {\n        var sign = '';\n        var textColor;\n        if (charge > 0) {\n          sign = '+';\n          textColor = 'red';\n        } else if (charge < 0) {\n          textColor = 'blue';\n        } else {\n          textColor = 'black';\n        }\n        readoutText.fill = textColor;\n        var newText = sign + numberAtom.charge;\n        if (newText !== readoutText.text) {\n          readoutText.text = newText;\n          readoutText.resetTransform();\n          readoutText.scale(Math.min(Math.min(readoutSize.width * 0.8 / readoutText.width, readoutSize.height * 0.8 / readoutText.height), 1));\n          readoutText.center = new Vector2(readoutSize.width / 2, readoutSize.height / 2);\n        }\n      }\n    });\n  };\n  inherit(Node, ChargeMeter);\n  return ChargeMeter;\n});",
    "\ndefine('buildanatom/view/MassNumberDisplay',['require','SCENERY_PHET/PhetFont','DOT/Dimension2','SCENERY/nodes/Image','imageLoader','PHET_CORE/inherit','SCENERY/nodes/Node','SCENERY/nodes/Rectangle','SCENERY/nodes/Text','DOT/Vector2'],function (require) {\n  'use strict';\n  var PhetFont = require('SCENERY_PHET/PhetFont');\n  var Dimension2 = require('DOT/Dimension2');\n  var Image = require('SCENERY/nodes/Image');\n  var imageLoader = require('imageLoader');\n  var inherit = require('PHET_CORE/inherit');\n  var Node = require('SCENERY/nodes/Node');\n  var Rectangle = require('SCENERY/nodes/Rectangle');\n  var Text = require('SCENERY/nodes/Text');\n  var Vector2 = require('DOT/Vector2');\n  var WIDTH = 122;\n  var READOUT_SIZE = new Dimension2(WIDTH * 0.25, WIDTH * 0.165);\n  function MassNumberDisplay(numberAtom) {\n    Node.call(this);\n    var scaleImage = new Image(imageLoader.getImage('scale.png'));\n    scaleImage.scale(WIDTH / scaleImage.width);\n    this.addChild(scaleImage);\n    var readoutBackground = new Rectangle(0, 0, READOUT_SIZE.width, READOUT_SIZE.height, 4, 4, {\n        fill: 'white',\n        stroke: 'black',\n        lineWidth: 1,\n        bottom: scaleImage.bottom - 6,\n        centerX: scaleImage.centerX\n      });\n    this.addChild(readoutBackground);\n    var numericalText = new Text(' ', {\n        font: new PhetFont({\n          size: 24,\n          weight: 'bold'\n        })\n      });\n    readoutBackground.addChild(numericalText);\n    numberAtom.massNumberProperty.link(function (massNumber) {\n      var newText = '' + massNumber;\n      if (newText !== numericalText.text) {\n        numericalText.text = newText;\n        numericalText.resetTransform();\n        numericalText.scale(Math.min(READOUT_SIZE.height * 0.9 / numericalText.height, READOUT_SIZE.width * 0.9 / numericalText.width));\n        numericalText.center = new Vector2(READOUT_SIZE.width / 2, READOUT_SIZE.height / 2);\n      }\n    });\n  }\n  inherit(Node, MassNumberDisplay);\n  return MassNumberDisplay;\n});",
    "\ndefine('buildanatom/view/BuildAnAtomView',['require','SUN/AccordionBox','common/view/AtomView','SCENERY_PHET/PhetFont','buildanatom/view/ChargeComparisonDisplay','common/view/ChargeMeter','PHET_CORE/inherit','buildanatom/view/MassNumberDisplay','SCENERY/nodes/Node','common/SharedConstants'],function (require) {\n  'use strict';\n  var AccordionBox = require('SUN/AccordionBox');\n  var AtomView = require('common/view/AtomView');\n  var PhetFont = require('SCENERY_PHET/PhetFont');\n  var ChargeComparisonDisplay = require('buildanatom/view/ChargeComparisonDisplay');\n  var ChargeMeter = require('common/view/ChargeMeter');\n  var inherit = require('PHET_CORE/inherit');\n  var MassNumberDisplay = require('buildanatom/view/MassNumberDisplay');\n  var Node = require('SCENERY/nodes/Node');\n  var SharedConstants = require('common/SharedConstants');\n  var INTER_BOX_SPACING = 7;\n  var ACCORDION_BOX_FONT = new PhetFont(18);\n  function BuildAnAtomView(model) {\n    AtomView.call(this, model);\n    var thisView = this;\n    var chargeMeterBoxContents = new Node({ pickable: false });\n    chargeMeterBoxContents.addChild(new ChargeMeter(model.numberAtom));\n    var chargeComparisonDisplay = new ChargeComparisonDisplay(model.numberAtom).mutate({ pickable: false });\n    chargeComparisonDisplay.left = chargeMeterBoxContents.right + 5;\n    chargeComparisonDisplay.centerY = chargeMeterBoxContents.centerY;\n    chargeMeterBoxContents.addChild(chargeComparisonDisplay);\n    var chargeMeterBox = new AccordionBox(chargeMeterBoxContents, {\n        title: 'Net Charge',\n        fill: SharedConstants.DISPLAY_PANEL_BACKGROUND_COLOR,\n        initiallyOpen: false,\n        minWidth: this.periodicTableBox.width,\n        contentPosition: 'left',\n        titlePosition: 'left',\n        buttonPosition: 'right',\n        font: ACCORDION_BOX_FONT\n      });\n    this.addChild(chargeMeterBox);\n    var massNumberBox = new AccordionBox(new MassNumberDisplay(model.numberAtom).mutate({ pickable: false }), {\n        title: 'Mass Number',\n        fill: SharedConstants.DISPLAY_PANEL_BACKGROUND_COLOR,\n        initiallyOpen: false,\n        minWidth: this.periodicTableBox.width,\n        contentPosition: 'left',\n        titlePosition: 'left',\n        buttonPosition: 'right'\n      });\n    this.addChild(massNumberBox);\n    this.resetFunctions.push(function () {\n      chargeMeterBox.open.reset();\n      massNumberBox.open.reset();\n    });\n    chargeMeterBox.right = this.periodicTableBox.right;\n    chargeMeterBox.top = this.periodicTableBox.bottom + INTER_BOX_SPACING;\n    massNumberBox.right = this.periodicTableBox.right;\n    massNumberBox.top = chargeMeterBox.top + chargeMeterBox.openHeight + INTER_BOX_SPACING;\n  }\n  inherit(AtomView, BuildAnAtomView);\n  return BuildAnAtomView;\n});",
    "\ndefine('game/model/BAAGameProblem',['require','AXON/PropertySet','PHET_CORE/inherit','common/SharedConstants'],function (require) {\n  'use strict';\n  var PropertySet = require('AXON/PropertySet');\n  var inherit = require('PHET_CORE/inherit');\n  var SharedConstants = require('common/SharedConstants');\n  function BAAGameProblem(buildAnAtomGameModel, answerAtom) {\n    PropertySet.call(this, {\n      problemState: 'presentingProblem',\n      answerAtom: answerAtom,\n      numSubmissions: 0,\n      score: 0\n    });\n    this.answerAtom = answerAtom;\n    this.model = buildAnAtomGameModel;\n  }\n  inherit(PropertySet, BAAGameProblem, {\n    checkAnswer: function (submittedAtom) {\n      null;\n      this.numSubmissions++;\n      if (this.answerAtom.equals(submittedAtom)) {\n        this.score = this.numSubmissions === 1 ? 2 : 1;\n        this.problemState = 'problemSolvedCorrectly';\n      } else {\n        if (this.numSubmissions < SharedConstants.MAX_PROBLEM_ATTEMPTS) {\n          this.problemState = 'presentingTryAgain';\n        } else {\n          this.problemState = 'attemptsExhausted';\n        }\n      }\n    },\n    tryAgain: function () {\n      this.problemState = 'presentingProblem';\n    },\n    next: function () {\n      this.model.next();\n    },\n    displayCorrectAnswer: function () {\n      this.problemState = 'displayingCorrectAnswer';\n    }\n  });\n  return BAAGameProblem;\n});",
    "\ndefine('SCENERY_PHET/MultiLineText',['require','PHET_CORE/inherit','SCENERY/nodes/Node','SCENERY/nodes/Text','SCENERY/nodes/VBox'],function (require) {\n  'use strict';\n  var inherit = require('PHET_CORE/inherit');\n  var Node = require('SCENERY/nodes/Node');\n  var Text = require('SCENERY/nodes/Text');\n  var VBox = require('SCENERY/nodes/VBox');\n  function MultiLineText(text, options) {\n    var thisNode = this;\n    thisNode._options = options = _.extend({ align: 'center' }, options);\n    Node.call(thisNode);\n    thisNode.text = text;\n    thisNode.mutate(_.omit(options, 'align'));\n  }\n  inherit(Node, MultiLineText, {\n    get text() {\n      return this._text;\n    },\n    set text(string) {\n      var thisNode = this;\n      thisNode._text = string;\n      thisNode.children = [new VBox({\n          children: string.split('\\n').map(function (line) {\n            return new Text(line, _.omit(thisNode._options, 'align'));\n          }),\n          align: thisNode._options.align\n        })];\n    }\n  });\n  return MultiLineText;\n});",
    "\ndefine('SCENERY_PHET/ArrowButton',['require','SCENERY/input/ButtonListener','PHET_CORE/inherit','SCENERY/nodes/Node','SCENERY/nodes/Path','SCENERY/nodes/Rectangle','KITE/Shape'],function (require) {\n  'use strict';\n  var ButtonListener = require('SCENERY/input/ButtonListener');\n  var inherit = require('PHET_CORE/inherit');\n  var Node = require('SCENERY/nodes/Node');\n  var Path = require('SCENERY/nodes/Path');\n  var Rectangle = require('SCENERY/nodes/Rectangle');\n  var Shape = require('KITE/Shape');\n  function ArrowButton(direction, callback, options) {\n    var thisButton = this;\n    var DEFAULT_ARROW_WIDTH = 20;\n    options = _.extend({\n      arrowHeight: DEFAULT_ARROW_WIDTH,\n      arrowWidth: DEFAULT_ARROW_WIDTH * Math.sqrt(3) / 2,\n      fill: 'white',\n      stroke: 'black',\n      lineWidth: 1,\n      xMargin: 7,\n      yMargin: 5,\n      cornerRadius: 4,\n      enabledFill: 'black',\n      disabledFill: 'rgb(175,175,175)',\n      enabledStroke: 'black',\n      disabledStroke: 'rgb(175,175,175)',\n      timerDelay: 400,\n      intervalDelay: 100\n    }, options);\n    Node.call(thisButton);\n    var arrowShape;\n    if (direction === 'up') {\n      arrowShape = new Shape().moveTo(options.arrowWidth / 2, 0).lineTo(options.arrowWidth, options.arrowHeight).lineTo(0, options.arrowHeight).close();\n    } else if (direction === 'down') {\n      arrowShape = new Shape().moveTo(0, 0).lineTo(options.arrowWidth, 0).lineTo(options.arrowWidth / 2, options.arrowHeight).close();\n    } else if (direction === 'left') {\n      arrowShape = new Shape().moveTo(0, options.arrowHeight / 2).lineTo(options.arrowWidth, 0).lineTo(options.arrowWidth, options.arrowHeight).close();\n    } else if (direction === 'right') {\n      arrowShape = new Shape().moveTo(0, 0).lineTo(options.arrowWidth, options.arrowHeight / 2).lineTo(0, options.arrowHeight).close();\n    } else {\n      throw new Error('unsupported direction: ' + direction);\n    }\n    var arrowNode = new Path(arrowShape, {\n        fill: options.enabledFill,\n        pickable: false\n      });\n    var background = new Rectangle(0, 0, arrowNode.width + 2 * options.xMargin, arrowNode.height + 2 * options.yMargin, options.cornerRadius, options.cornerRadius, {\n        stroke: options.stroke,\n        lineWidth: options.lineWidth,\n        fill: options.fill,\n        pickable: false\n      });\n    thisButton.addChild(background);\n    thisButton.addChild(arrowNode);\n    arrowNode.centerX = background.centerX;\n    arrowNode.centerY = background.centerY;\n    var dx = 0.25 * thisButton.width;\n    var dy = 0.25 * thisButton.height;\n    thisButton.touchArea = Shape.rectangle(-dx, -dy, thisButton.width + dx + dx, thisButton.height + dy + dy);\n    thisButton.mouseArea = Shape.rectangle(0, 0, thisButton.width, thisButton.height);\n    thisButton.cursor = 'pointer';\n    var enabled = true;\n    var fired = false;\n    var timeoutID = null;\n    var intervalID = null;\n    var cleanupTimer = function () {\n      if (timeoutID) {\n        window.clearTimeout(timeoutID);\n        timeoutID = null;\n      }\n      if (intervalID) {\n        window.clearInterval(intervalID);\n        intervalID = null;\n      }\n    };\n    thisButton.addInputListener(new ButtonListener({\n      over: function () {\n      },\n      down: function () {\n        fired = false;\n        timeoutID = window.setTimeout(function () {\n          timeoutID = null;\n          fired = true;\n          intervalID = window.setInterval(function () {\n            if (enabled) {\n              callback();\n            }\n          }, options.intervalDelay);\n        }, options.timerDelay);\n      },\n      up: function () {\n        cleanupTimer();\n      },\n      fire: function () {\n        cleanupTimer();\n        if (!fired && enabled) {\n          callback();\n        }\n      }\n    }));\n    thisButton.setEnabled = function (value) {\n      enabled = value;\n      if (!enabled) {\n        cleanupTimer();\n      }\n      arrowNode.fill = enabled ? options.enabledFill : options.disabledFill;\n      background.stroke = enabled ? options.enabledStroke : options.disabledStroke;\n      thisButton.pickable = enabled;\n    };\n    thisButton.setEnabled(true);\n    thisButton.mutate(options);\n  }\n  inherit(Node, ArrowButton);\n  return ArrowButton;\n});",
    "\ndefine('game/view/NumberEntryNode',['require','SCENERY_PHET/ArrowButton','PHET_CORE/inherit','SCENERY/nodes/Node','SCENERY_PHET/PhetFont','SCENERY/nodes/Rectangle','KITE/Shape','SCENERY/nodes/Text'],function (require) {\n  'use strict';\n  var ArrowButton = require('SCENERY_PHET/ArrowButton');\n  var inherit = require('PHET_CORE/inherit');\n  var Node = require('SCENERY/nodes/Node');\n  var PhetFont = require('SCENERY_PHET/PhetFont');\n  var Rectangle = require('SCENERY/nodes/Rectangle');\n  var Shape = require('KITE/Shape');\n  var Text = require('SCENERY/nodes/Text');\n  var NUMBER_BOX_SIZE = {\n      width: 50,\n      height: 40\n    };\n  function NumberEntryNode(numberProperty, options) {\n    Node.call(this);\n    var thisNode = this;\n    options = _.extend({\n      font: new PhetFont(24),\n      prependPlusSign: false,\n      getTextColor: function () {\n        return 'black';\n      },\n      minValue: Number.NEGATIVE_INFINITY,\n      maxValue: Number.POSITIVE_INFINITY\n    }, options);\n    var arrowButtonOptions = {\n        arrowHeight: 12,\n        arrowWidth: 15\n      };\n    var upArrowButton = new ArrowButton('up', function () {\n        numberProperty.value = numberProperty.value + 1;\n      }, arrowButtonOptions);\n    thisNode.addChild(upArrowButton);\n    var downArrowButton = new ArrowButton('down', function () {\n        numberProperty.value = numberProperty.value - 1;\n      }, arrowButtonOptions);\n    thisNode.addChild(downArrowButton);\n    var answerValueBackground = new Rectangle(0, 0, NUMBER_BOX_SIZE.width, NUMBER_BOX_SIZE.height, 4, 4, {\n        fill: 'white',\n        stroke: 'black',\n        lineWidth: 1\n      });\n    thisNode.addChild(answerValueBackground);\n    numberProperty.link(function (newValue) {\n      answerValueBackground.removeAllChildren();\n      var prepend = options.prependPlusSign && newValue > 0 ? '+' : '';\n      var textNode = new Text(prepend + newValue, {\n          font: new PhetFont(22),\n          fill: options.getTextColor(newValue)\n        });\n      textNode.scale(Math.min(1, Math.min(answerValueBackground.width * 0.8 / textNode.width, answerValueBackground.height * 0.9 / textNode.height)));\n      textNode.centerX = answerValueBackground.width / 2;\n      textNode.centerY = answerValueBackground.height / 2;\n      answerValueBackground.addChild(textNode);\n      upArrowButton.setEnabled(newValue < options.maxValue);\n      downArrowButton.setEnabled(newValue > options.minValue);\n    });\n    var interNodeSpacing = upArrowButton.height * 0.1;\n    var totalHeight = Math.max(answerValueBackground.height, upArrowButton.height + downArrowButton.height + interNodeSpacing);\n    answerValueBackground.left = 0;\n    answerValueBackground.centerY = totalHeight / 2;\n    upArrowButton.left = answerValueBackground.right + interNodeSpacing;\n    upArrowButton.bottom = totalHeight / 2 - interNodeSpacing / 2;\n    downArrowButton.top = totalHeight / 2 + interNodeSpacing / 2;\n    downArrowButton.left = answerValueBackground.right + interNodeSpacing;\n    var extendedTouchAreaWidth = upArrowButton.width * 2.5;\n    var extendedTouchAreaHeight = upArrowButton.height * 2.5;\n    upArrowButton.touchArea = Shape.rectangle(-extendedTouchAreaWidth / 2, -extendedTouchAreaHeight + upArrowButton.height, extendedTouchAreaWidth, extendedTouchAreaHeight);\n    downArrowButton.touchArea = Shape.rectangle(-extendedTouchAreaWidth / 2, 0, extendedTouchAreaWidth, extendedTouchAreaHeight);\n    thisNode.mutate(options);\n  }\n  inherit(Node, NumberEntryNode);\n  return NumberEntryNode;\n});",
    "\ndefine('game/view/ParticleCountsNode',['require','SCENERY_PHET/PhetFont','SCENERY/nodes/Node','SCENERY/nodes/Text','PHET_CORE/inherit'],function (require) {\n  'use strict';\n  var PhetFont = require('SCENERY_PHET/PhetFont');\n  var Node = require('SCENERY/nodes/Node');\n  var Text = require('SCENERY/nodes/Text');\n  var inherit = require('PHET_CORE/inherit');\n  function ParticleCountsNode(numberAtom, options) {\n    Node.call(this, options);\n    options = _.extend({ font: new PhetFont(24) }, options);\n    var protonCountTitle = new Text('Protons:', options.font);\n    this.addChild(protonCountTitle);\n    var protonCountText = new Text(numberAtom.protonCount, options.font);\n    this.addChild(protonCountText);\n    var neutronCountTitle = new Text('Neutrons:', options.font);\n    this.addChild(neutronCountTitle);\n    var neutronCountText = new Text(numberAtom.neutronCount, options.font);\n    this.addChild(neutronCountText);\n    var electronCountTitle = new Text('Electrons:', options.font);\n    this.addChild(electronCountTitle);\n    var electronCountText = new Text(numberAtom.electronCount, options.font);\n    this.addChild(electronCountText);\n    var maxParticleLabelWidth = Math.max(Math.max(protonCountTitle.width, neutronCountTitle.width), electronCountTitle.width);\n    var interLineSpacing = protonCountTitle.height * 0.7;\n    var numberAreaWidth = new Text('000', { font: options.font }).width;\n    protonCountTitle.left = 0;\n    protonCountTitle.top = 0;\n    protonCountText.bottom = protonCountTitle.bottom;\n    protonCountText.right = maxParticleLabelWidth + numberAreaWidth;\n    neutronCountTitle.left = 0;\n    neutronCountTitle.top = protonCountTitle.bottom + interLineSpacing;\n    neutronCountText.bottom = neutronCountTitle.bottom;\n    neutronCountText.right = maxParticleLabelWidth + numberAreaWidth;\n    electronCountTitle.left = 0;\n    electronCountTitle.top = neutronCountTitle.bottom + interLineSpacing;\n    electronCountText.bottom = electronCountTitle.bottom;\n    electronCountText.right = maxParticleLabelWidth + numberAreaWidth;\n  }\n  inherit(Node, ParticleCountsNode);\n  return ParticleCountsNode;\n});",
    "\ndefine('SUN/RectangleButton',['require','SCENERY/util/Color','PHET_CORE/inherit','SCENERY/nodes/Node','SUN/PushButton','SCENERY/nodes/Rectangle'],function (require) {\n  'use strict';\n  var Color = require('SCENERY/util/Color');\n  var inherit = require('PHET_CORE/inherit');\n  var Node = require('SCENERY/nodes/Node');\n  var PushButton = require('SUN/PushButton');\n  var Rectangle = require('SCENERY/nodes/Rectangle');\n  var createNode = function (content, stroke, fill, rectangleLineWidth, rectangleXMargin, rectangleYMargin, rectangleCornerRadius) {\n    var node = new Node();\n    var rectangle = new Rectangle(0, 0, content.width + rectangleXMargin + rectangleXMargin, content.height + rectangleYMargin + rectangleYMargin, rectangleCornerRadius, rectangleCornerRadius, {\n        stroke: stroke,\n        fill: fill,\n        rectangleLineWidth: rectangleLineWidth\n      });\n    node.addChild(rectangle);\n    node.addChild(content);\n    content.centerX = rectangle.centerX;\n    content.centerY = rectangle.centerY;\n    return node;\n  };\n  function RectangleButton(content, callback, options) {\n    options = _.extend({\n      rectangleStroke: 'black',\n      rectangleStrokeDisabled: 'rgb(175,175,175)',\n      rectangleFillUp: new Color(255, 200, 0),\n      rectangleFillDisabled: 'white',\n      rectangleLineWidth: 1,\n      rectangleXMargin: 5,\n      rectangleYMargin: 5,\n      rectangleCornerRadius: 10\n    }, options);\n    null;\n    options.rectangleFillOver = options.rectangleFillOver || options.rectangleFillUp.brighterColor(0.9);\n    options.rectangleFillDown = options.rectangleFillDown || options.rectangleFillUp.darkerColor(0.9);\n    PushButton.call(this, createNode(content, options.rectangleStroke, options.rectangleFillUp, options.rectangleLineWidth, options.rectangleXMargin, options.rectangleYMargin, options.rectangleCornerRadius), createNode(content, options.rectangleStroke, options.rectangleFillOver, options.rectangleLineWidth, options.rectangleXMargin, options.rectangleYMargin, options.rectangleCornerRadius), createNode(content, options.rectangleStroke, options.rectangleFillDown, options.rectangleLineWidth, options.rectangleXMargin, options.rectangleYMargin, options.rectangleCornerRadius), createNode(content, options.rectangleStrokeDisabled, options.rectangleFillDisabled, options.rectangleLineWidth, options.rectangleXMargin, options.rectangleYMargin, options.rectangleCornerRadius), callback, options);\n  }\n  return inherit(PushButton, RectangleButton);\n});",
    "\ndefine('SUN/TextButton',['require','PHET_CORE/inherit','SUN/RectangleButton','SCENERY/nodes/Text'],function (require) {\n  'use strict';\n  var inherit = require('PHET_CORE/inherit');\n  var RectangleButton = require('SUN/RectangleButton');\n  var Text = require('SCENERY/nodes/Text');\n  function TextButton(text, callback, options) {\n    options = _.extend({\n      textFill: 'black',\n      textFillDisabled: 'rgb(175,175,175)'\n    }, options);\n    var textNode = new Text(text, options);\n    RectangleButton.call(this, textNode, callback, options);\n    this._enabled.link(function (enabled) {\n      textNode.fill = enabled ? options.textFill : options.textFillDisabled;\n    });\n  }\n  inherit(RectangleButton, TextButton);\n  return TextButton;\n});",
    "\ndefine('SCENERY_PHET/FaceNode',['require','PHET_CORE/inherit','SCENERY/nodes/Circle','SCENERY/nodes/Node','SCENERY/nodes/Path','KITE/Shape','DOT/Vector2'],function (require) {\n  'use strict';\n  var inherit = require('PHET_CORE/inherit');\n  var Circle = require('SCENERY/nodes/Circle');\n  var Node = require('SCENERY/nodes/Node');\n  var Path = require('SCENERY/nodes/Path');\n  var Shape = require('KITE/Shape');\n  var Vector2 = require('DOT/Vector2');\n  function FaceNode(headDiameter, options) {\n    options = _.extend({\n      headPaint: 'yellow',\n      eyePaint: 'black',\n      mouthPaint: 'black',\n      headStroke: null,\n      headLineWidth: '1px'\n    }, options);\n    var thisNode = this;\n    Node.call(thisNode, options);\n    this.addChild(new Circle(headDiameter / 2, {\n      fill: options.headPaint,\n      stroke: options.headStroke,\n      lineWidth: options.headLineWidth\n    }));\n    var eyeDiameter = headDiameter * 0.075;\n    this.addChild(new Circle(eyeDiameter, {\n      fill: options.eyePaint,\n      centerX: -headDiameter * 0.2,\n      centerY: -headDiameter * 0.1\n    }));\n    this.addChild(new Circle(eyeDiameter, {\n      fill: options.eyePaint,\n      centerX: headDiameter * 0.2,\n      centerY: -headDiameter * 0.1\n    }));\n    var mouthLineWidth = headDiameter * 0.05;\n    this.smileMouth = new Path(new Shape().arc(0, headDiameter * 0.05, headDiameter * 0.25, Math.PI * 0.2, Math.PI * 0.8), {\n      stroke: options.mouthPaint,\n      lineWidth: mouthLineWidth,\n      lineCap: 'round'\n    });\n    this.addChild(this.smileMouth);\n    this.frownMouth = new Path(new Shape().arc(0, headDiameter * 0.4, headDiameter * 0.25, -Math.PI * 0.8, -Math.PI * 0.2), {\n      stroke: options.mouthPaint,\n      lineWidth: mouthLineWidth,\n      lineCap: 'round'\n    });\n    this.addChild(this.frownMouth);\n    this.smile();\n  }\n  inherit(Node, FaceNode, {\n    smile: function () {\n      this.smileMouth.visible = true;\n      this.frownMouth.visible = false;\n    },\n    frown: function () {\n      this.smileMouth.visible = false;\n      this.frownMouth.visible = true;\n    }\n  });\n  return FaceNode;\n});",
    "\ndefine('game/view/ProblemView',['require','SCENERY/util/Color','SCENERY_PHET/PhetFont','SUN/TextButton','SCENERY_PHET/FaceNode','PHET_CORE/inherit','SCENERY/nodes/Node','common/model/NumberAtom','common/view/PeriodicTableNode','AXON/Property','SUN/AquaRadioButton','SCENERY/nodes/Rectangle','SCENERY/nodes/Text'],function (require) {\n  'use strict';\n  var Color = require('SCENERY/util/Color');\n  var PhetFont = require('SCENERY_PHET/PhetFont');\n  var TextButton = require('SUN/TextButton');\n  var FaceNode = require('SCENERY_PHET/FaceNode');\n  var inherit = require('PHET_CORE/inherit');\n  var Node = require('SCENERY/nodes/Node');\n  var NumberAtom = require('common/model/NumberAtom');\n  var PeriodicTableNode = require('common/view/PeriodicTableNode');\n  var Property = require('AXON/Property');\n  var AquaRadioButton = require('SUN/AquaRadioButton');\n  var Rectangle = require('SCENERY/nodes/Rectangle');\n  var Text = require('SCENERY/nodes/Text');\n  var BUTTON_FONT = new PhetFont(20);\n  var BUTTON_FILL = new Color(0, 255, 153);\n  function ProblemView(problem, layoutBounds) {\n    Node.call(this);\n    var thisNode = this;\n    this.problem = problem;\n    null;\n    this.problemPresentationNode = new Node();\n    this.addChild(this.problemPresentationNode);\n    this.interactiveAnswerNode = new Node();\n    this.addChild(this.interactiveAnswerNode);\n    var faceNode = new FaceNode(layoutBounds.width * 0.4, {\n        visible: false,\n        opacity: 0.75\n      });\n    this.addChild(faceNode);\n    this.buttons = [];\n    this.checkAnswerButton = new TextButton('Check', function () {\n      thisNode.checkAnswer();\n    }, {\n      font: BUTTON_FONT,\n      rectangleFillUp: BUTTON_FILL\n    });\n    this.addChild(this.checkAnswerButton);\n    this.buttons.push(this.checkAnswerButton);\n    this.nextButton = new TextButton('Next', function () {\n      problem.next();\n    }, {\n      font: BUTTON_FONT,\n      rectangleFillUp: BUTTON_FILL\n    });\n    this.addChild(this.nextButton);\n    this.buttons.push(this.nextButton);\n    this.tryAgainButton = new TextButton('Try Again', function () {\n      problem.tryAgain();\n    }, {\n      font: BUTTON_FONT,\n      rectangleFillUp: BUTTON_FILL\n    });\n    this.addChild(this.tryAgainButton);\n    this.buttons.push(this.tryAgainButton);\n    this.displayCorrectAnswerButton = new TextButton('Display Correct Answer', function () {\n      problem.displayCorrectAnswer();\n    }, {\n      font: BUTTON_FONT,\n      rectangleFillUp: BUTTON_FILL\n    });\n    this.addChild(this.displayCorrectAnswerButton);\n    this.buttons.push(this.displayCorrectAnswerButton);\n    var hideButtonsAndFace = function hideButtonsAndFace() {\n      thisNode.buttons.forEach(function (button) {\n        button.visible = false;\n      });\n      faceNode.visible = false;\n    };\n    hideButtonsAndFace();\n    var setAnswerNodeInteractive = function (interactive) {\n      thisNode.interactiveAnswerNode.pickable = interactive;\n    };\n    var stateChangeHandlers = {\n        presentingProblem: function () {\n          thisNode.clearAnswer();\n          setAnswerNodeInteractive(true);\n          thisNode.checkAnswerButton.visible = true;\n        },\n        problemSolvedCorrectly: function () {\n          setAnswerNodeInteractive(true);\n          faceNode.smile();\n          faceNode.visible = true;\n          thisNode.nextButton.visible = true;\n        },\n        presentingTryAgain: function () {\n          setAnswerNodeInteractive(false);\n          faceNode.frown();\n          faceNode.visible = true;\n          thisNode.tryAgainButton.visible = true;\n        },\n        attemptsExhausted: function () {\n          setAnswerNodeInteractive(false);\n          thisNode.displayCorrectAnswerButton.visible = true;\n          faceNode.frown();\n          faceNode.visible = true;\n        },\n        displayingCorrectAnswer: function () {\n          setAnswerNodeInteractive(false);\n          thisNode.nextButton.visible = true;\n          thisNode.displayCorrectAnswer();\n        }\n      };\n    problem.problemStateProperty.link(function (problemState) {\n      console.log('Problem state changed, new state = ' + problemState);\n      hideButtonsAndFace();\n      if (stateChangeHandlers[problemState] !== undefined) {\n        stateChangeHandlers[problemState]();\n      }\n    });\n    this.setButtonCenter(layoutBounds.width * 0.75, layoutBounds.height * 0.8);\n    faceNode.centerX = layoutBounds.width / 2;\n    faceNode.centerY = layoutBounds.height / 2;\n  }\n  inherit(Node, ProblemView, {\n    clearAnswer: function () {\n    },\n    displayCorrectAnswer: function () {\n    },\n    checkAnswer: function () {\n    },\n    setButtonCenter: function (x, y) {\n      this.buttons.forEach(function (button) {\n        button.centerX = x;\n        button.centerY = y;\n      });\n    }\n  });\n  return ProblemView;\n});",
    "\ndefine('game/view/CountsToChargeProblemView',['require','SCENERY_PHET/PhetFont','PHET_CORE/inherit','SCENERY_PHET/MultiLineText','SCENERY/nodes/Node','common/model/NumberAtom','game/view/NumberEntryNode','game/view/ParticleCountsNode','game/view/ProblemView','AXON/Property','common/SharedConstants'],function (require) {\n  'use strict';\n  var PhetFont = require('SCENERY_PHET/PhetFont');\n  var inherit = require('PHET_CORE/inherit');\n  var MultiLineText = require('SCENERY_PHET/MultiLineText');\n  var Node = require('SCENERY/nodes/Node');\n  var NumberAtom = require('common/model/NumberAtom');\n  var NumberEntryNode = require('game/view/NumberEntryNode');\n  var ParticleCountsNode = require('game/view/ParticleCountsNode');\n  var ProblemView = require('game/view/ProblemView');\n  var Property = require('AXON/Property');\n  var SharedConstants = require('common/SharedConstants');\n  function CountsToChargeProblemView(countsToChargeProblem, layoutBounds) {\n    this.chargeAnswer = new Property(0);\n    ProblemView.call(this, countsToChargeProblem, layoutBounds);\n    var thisNode = this;\n    var particleCountsNode = new ParticleCountsNode(countsToChargeProblem.answerAtom);\n    this.problemPresentationNode.addChild(particleCountsNode);\n    var questionPrompt = new MultiLineText('What is the\\ntotal charge?', {\n        align: 'left',\n        font: new PhetFont(24)\n      });\n    this.addChild(questionPrompt);\n    var numberEntryNode = new NumberEntryNode(thisNode.chargeAnswer, {\n        prependPlusSign: true,\n        getTextColor: SharedConstants.CHARGE_TEXT_COLOR\n      });\n    thisNode.addChild(numberEntryNode);\n    particleCountsNode.centerX = layoutBounds.width * 0.25;\n    particleCountsNode.centerY = layoutBounds.height * 0.5;\n    questionPrompt.centerX = layoutBounds.width * 0.65;\n    questionPrompt.centerY = layoutBounds.height * 0.5;\n    numberEntryNode.left = questionPrompt.right + 10;\n    numberEntryNode.centerY = questionPrompt.centerY;\n  }\n  inherit(ProblemView, CountsToChargeProblemView, {\n    checkAnswer: function () {\n      var userSubmittedAnswer = new NumberAtom({\n          protonCount: this.problem.answerAtom.protonCount,\n          neutronCount: this.problem.answerAtom.neutronCount,\n          electronCount: this.problem.answerAtom.protonCount - this.chargeAnswer.value\n        });\n      this.problem.checkAnswer(userSubmittedAnswer);\n    },\n    clearAnswer: function () {\n      this.chargeAnswer.reset();\n    },\n    displayCorrectAnswer: function () {\n      this.chargeAnswer.value = this.problem.answerAtom.charge;\n    }\n  });\n  return CountsToChargeProblemView;\n});",
    "\ndefine('game/model/CountsToChargeProblem',['require','game/model/BAAGameProblem','game/view/CountsToChargeProblemView','PHET_CORE/inherit','common/SharedConstants'],function (require) {\n  'use strict';\n  var BAAGameProblem = require('game/model/BAAGameProblem');\n  var CountsToChargeProblemView = require('game/view/CountsToChargeProblemView');\n  var inherit = require('PHET_CORE/inherit');\n  var SharedConstants = require('common/SharedConstants');\n  function CountsToChargeProblem(buildAnAtomGameModel, answerAtom) {\n    BAAGameProblem.call(this, buildAnAtomGameModel, answerAtom);\n  }\n  inherit(BAAGameProblem, CountsToChargeProblem, {\n    createView: function (layoutBounds) {\n      return new CountsToChargeProblemView(this, layoutBounds);\n    }\n  });\n  return CountsToChargeProblem;\n});",
    "\ndefine('game/view/InteractiveSymbolNode',['require','common/AtomIdentifier','SCENERY_PHET/PhetFont','PHET_CORE/inherit','SCENERY/nodes/Node','game/view/NumberEntryNode','AXON/Property','SCENERY/nodes/Rectangle','common/SharedConstants','SCENERY/nodes/Text','DOT/Vector2'],function (require) {\n  'use strict';\n  var AtomIdentifier = require('common/AtomIdentifier');\n  var PhetFont = require('SCENERY_PHET/PhetFont');\n  var inherit = require('PHET_CORE/inherit');\n  var Node = require('SCENERY/nodes/Node');\n  var NumberEntryNode = require('game/view/NumberEntryNode');\n  var Property = require('AXON/Property');\n  var Rectangle = require('SCENERY/nodes/Rectangle');\n  var SharedConstants = require('common/SharedConstants');\n  var Text = require('SCENERY/nodes/Text');\n  var Vector2 = require('DOT/Vector2');\n  var SYMBOL_BOX_WIDTH = 275;\n  var SYMBOL_BOX_HEIGHT = 300;\n  var NUMBER_FONT = new PhetFont(56);\n  var NUMBER_INSET = 20;\n  var NUMBER_ENTRY_NODE_INSET = 10;\n  function InteractiveSymbolNode(numberAtom, options) {\n    Node.call(this, options);\n    var thisNode = this;\n    options = _.extend({\n      interactiveProtonCount: false,\n      interactiveMassNumber: false,\n      interactiveCharge: false\n    }, options);\n    thisNode.protonCount = new Property(options.interactiveProtonCount ? 0 : numberAtom.protonCount);\n    thisNode.massNumber = new Property(options.interactiveMassNumber ? 0 : numberAtom.massNumber);\n    thisNode.charge = new Property(options.interactiveCharge ? 0 : numberAtom.charge);\n    var boundingBox = new Rectangle(0, 0, SYMBOL_BOX_WIDTH, SYMBOL_BOX_HEIGHT, 0, 0, {\n        stroke: 'black',\n        lineWidth: 2,\n        fill: 'white'\n      });\n    this.addChild(boundingBox);\n    var symbolText = new Text('', {\n        font: new PhetFont(150),\n        fill: 'black',\n        center: new Vector2(SYMBOL_BOX_WIDTH / 2, SYMBOL_BOX_HEIGHT / 2)\n      });\n    boundingBox.addChild(symbolText);\n    var elementCaption = new Text('', {\n        font: new PhetFont(40),\n        fill: 'red',\n        top: SYMBOL_BOX_HEIGHT + 20,\n        centerX: SYMBOL_BOX_WIDTH / 2\n      });\n    boundingBox.addChild(elementCaption);\n    var updateElement = function (protonCount) {\n      symbolText.text = protonCount > 0 ? AtomIdentifier.getSymbol(protonCount) : '';\n      symbolText.center = new Vector2(SYMBOL_BOX_WIDTH / 2, SYMBOL_BOX_HEIGHT / 2);\n      elementCaption.text = protonCount > 0 ? AtomIdentifier.getName(protonCount) : '';\n      elementCaption.centerX = SYMBOL_BOX_WIDTH / 2;\n    };\n    if (options.interactiveProtonCount) {\n      boundingBox.addChild(new NumberEntryNode(thisNode.protonCount, {\n        minValue: 0,\n        getTextColor: function () {\n          return 'red';\n        },\n        bottom: SYMBOL_BOX_HEIGHT - NUMBER_ENTRY_NODE_INSET,\n        left: NUMBER_ENTRY_NODE_INSET\n      }));\n      thisNode.protonCount.link(updateElement);\n    } else {\n      var protonCountDisplay = new Text(numberAtom.protonCount, {\n          font: NUMBER_FONT,\n          fill: 'red',\n          left: NUMBER_INSET,\n          bottom: SYMBOL_BOX_HEIGHT - NUMBER_INSET\n        });\n      boundingBox.addChild(protonCountDisplay);\n      updateElement(numberAtom.protonCount);\n    }\n    if (options.interactiveMassNumber) {\n      boundingBox.addChild(new NumberEntryNode(thisNode.massNumber, {\n        minValue: 0,\n        top: NUMBER_ENTRY_NODE_INSET,\n        left: NUMBER_ENTRY_NODE_INSET\n      }));\n    } else {\n      var massNumberDisplay = new Text(numberAtom.massNumber, {\n          font: NUMBER_FONT,\n          fill: 'black',\n          left: NUMBER_INSET,\n          top: NUMBER_INSET\n        });\n      boundingBox.addChild(massNumberDisplay);\n    }\n    if (options.interactiveCharge) {\n      boundingBox.addChild(new NumberEntryNode(thisNode.charge, {\n        prependPlusSign: true,\n        getTextColor: SharedConstants.CHARGE_TEXT_COLOR,\n        top: NUMBER_ENTRY_NODE_INSET,\n        right: SYMBOL_BOX_WIDTH - NUMBER_ENTRY_NODE_INSET\n      }));\n    } else {\n      var chargeTextPrepend = numberAtom.charge > 0 ? '+' : '';\n      var chargeDisplay = new Text(chargeTextPrepend + numberAtom.charge, {\n          font: NUMBER_FONT,\n          fill: SharedConstants.CHARGE_TEXT_COLOR(numberAtom.charge),\n          right: SYMBOL_BOX_WIDTH - NUMBER_INSET,\n          top: NUMBER_INSET\n        });\n      boundingBox.addChild(chargeDisplay);\n    }\n  }\n  inherit(Node, InteractiveSymbolNode, {\n    reset: function () {\n      this.protonCount.reset();\n      this.massNumber.reset();\n      this.charge.reset();\n    }\n  });\n  return InteractiveSymbolNode;\n});",
    "\ndefine('game/view/CountsToSymbolProblemView',['require','PHET_CORE/inherit','SCENERY/nodes/Node','common/model/NumberAtom','game/view/InteractiveSymbolNode','game/view/ParticleCountsNode','game/view/ProblemView'],function (require) {\n  'use strict';\n  var inherit = require('PHET_CORE/inherit');\n  var Node = require('SCENERY/nodes/Node');\n  var NumberAtom = require('common/model/NumberAtom');\n  var InteractiveSymbolNode = require('game/view/InteractiveSymbolNode');\n  var ParticleCountsNode = require('game/view/ParticleCountsNode');\n  var ProblemView = require('game/view/ProblemView');\n  function CountsToSymbolProblemView(toSymbolProblem, layoutBounds) {\n    this.interactiveSymbol = new InteractiveSymbolNode(toSymbolProblem.answerAtom, {\n      interactiveProtonCount: toSymbolProblem.configurableProtonCount,\n      interactiveMassNumber: toSymbolProblem.configurableMassNumber,\n      interactiveCharge: toSymbolProblem.configurableCharge\n    });\n    ProblemView.call(this, toSymbolProblem, layoutBounds);\n    var thisNode = this;\n    this.interactiveSymbol.scale(0.75);\n    this.interactiveAnswerNode.addChild(this.interactiveSymbol);\n    var particleCountsNode = new ParticleCountsNode(toSymbolProblem.answerAtom);\n    this.problemPresentationNode.addChild(particleCountsNode);\n    particleCountsNode.centerX = layoutBounds.width * 0.25;\n    particleCountsNode.centerY = layoutBounds.height * 0.5;\n    this.interactiveSymbol.centerX = layoutBounds.width * 0.75;\n    this.interactiveSymbol.centerY = layoutBounds.height * 0.4;\n  }\n  inherit(ProblemView, CountsToSymbolProblemView, {\n    checkAnswer: function () {\n      var userSubmittedAtom = new NumberAtom({\n          protonCount: this.interactiveSymbol.protonCount.value,\n          neutronCount: this.interactiveSymbol.massNumber.value - this.interactiveSymbol.protonCount.value,\n          electronCount: this.interactiveSymbol.protonCount.value - this.interactiveSymbol.charge.value\n        });\n      this.problem.checkAnswer(userSubmittedAtom);\n    },\n    clearAnswer: function () {\n      this.interactiveSymbol.reset();\n    },\n    displayCorrectAnswer: function () {\n      this.interactiveSymbol.protonCount.value = this.problem.answerAtom.protonCount;\n      this.interactiveSymbol.massNumber.value = this.problem.answerAtom.massNumber;\n      this.interactiveSymbol.charge.value = this.problem.answerAtom.charge;\n    }\n  });\n  return CountsToSymbolProblemView;\n});",
    "\ndefine('game/model/CountsToSymbolProblem',['require','game/model/BAAGameProblem','game/view/CountsToSymbolProblemView','PHET_CORE/inherit','common/SharedConstants'],function (require) {\n  'use strict';\n  var BAAGameProblem = require('game/model/BAAGameProblem');\n  var CountsToSymbolProblemView = require('game/view/CountsToSymbolProblemView');\n  var inherit = require('PHET_CORE/inherit');\n  var SharedConstants = require('common/SharedConstants');\n  function CountsToSymbolProblem(buildAnAtomGameModel, answerAtom, configurableProtonCount, configurableMassNumber, configurableCharge) {\n    BAAGameProblem.call(this, buildAnAtomGameModel, answerAtom);\n    this.configurableProtonCount = configurableProtonCount;\n    this.configurableMassNumber = configurableMassNumber;\n    this.configurableCharge = configurableCharge;\n  }\n  inherit(BAAGameProblem, CountsToSymbolProblem, {\n    createView: function (layoutBounds) {\n      return new CountsToSymbolProblemView(this, layoutBounds);\n    }\n  });\n  return CountsToSymbolProblem;\n});",
    "\ndefine('game/model/ToElementProblem',['require','game/model/BAAGameProblem','PHET_CORE/inherit','common/SharedConstants'],function (require) {\n  'use strict';\n  var BAAGameProblem = require('game/model/BAAGameProblem');\n  var inherit = require('PHET_CORE/inherit');\n  var SharedConstants = require('common/SharedConstants');\n  function ToElementProblem(buildAnAtomGameModel, answerAtom) {\n    BAAGameProblem.call(this, buildAnAtomGameModel, answerAtom);\n  }\n  inherit(BAAGameProblem, ToElementProblem, {\n    checkAnswer: function (submittedAtom, submittedNeutralOrIon) {\n      null;\n      this.numSubmissions++;\n      if (submittedAtom.protonCount === this.answerAtom.protonCount && submittedAtom.neutronCount === this.answerAtom.neutronCount && (submittedNeutralOrIon === 'neutral' && this.answerAtom.charge === 0 || submittedNeutralOrIon === 'ion' && this.answerAtom.charge !== 0)) {\n        this.score = this.numSubmissions === 1 ? 2 : 1;\n        this.problemState = 'problemSolvedCorrectly';\n      } else {\n        if (this.numSubmissions < SharedConstants.MAX_PROBLEM_ATTEMPTS) {\n          this.problemState = 'presentingTryAgain';\n        } else {\n          this.problemState = 'attemptsExhausted';\n        }\n      }\n    }\n  });\n  return ToElementProblem;\n});",
    "\ndefine('game/view/ToElementProblemView',['require','SUN/AquaRadioButton','SCENERY_PHET/PhetFont','PHET_CORE/inherit','SCENERY/nodes/Node','common/model/NumberAtom','common/view/PeriodicTableNode','game/view/ProblemView','AXON/Property','SCENERY/nodes/Text'],function (require) {\n  'use strict';\n  var AquaRadioButton = require('SUN/AquaRadioButton');\n  var PhetFont = require('SCENERY_PHET/PhetFont');\n  var inherit = require('PHET_CORE/inherit');\n  var Node = require('SCENERY/nodes/Node');\n  var NumberAtom = require('common/model/NumberAtom');\n  var PeriodicTableNode = require('common/view/PeriodicTableNode');\n  var ProblemView = require('game/view/ProblemView');\n  var Property = require('AXON/Property');\n  var Text = require('SCENERY/nodes/Text');\n  var TITLE_FONT = new PhetFont(30);\n  var INSET = 10;\n  function CountsToElementProblemView(countsToElementProblem, layoutBounds) {\n    ProblemView.call(this, countsToElementProblem, layoutBounds);\n    var thisNode = this;\n    var problemTitle = new Text('Find the element:', { font: TITLE_FONT });\n    this.problemPresentationNode.addChild(problemTitle);\n    this.periodicTable = new PeriodicTableNode(this.periodicTableAtom, 100);\n    this.periodicTable.scale(0.85);\n    this.interactiveAnswerNode.addChild(this.periodicTable);\n    var neutralVersusIonPrompt = new Text('Is it:', { font: new PhetFont(24) });\n    var neutralAtomButton = new AquaRadioButton(this.neutralOrIon, 'neutral', new Text('Neutral Atom', { font: new PhetFont(18) }), { radius: 8 });\n    var ionButton = new AquaRadioButton(this.neutralOrIon, 'ion', new Text('Ion', { font: new PhetFont(18) }), { radius: 8 });\n    var neutralAtomVersusIonQuestion = new Node();\n    neutralAtomVersusIonQuestion.addChild(neutralVersusIonPrompt);\n    neutralAtomButton.left = neutralVersusIonPrompt.right + 10;\n    neutralAtomButton.centerY = neutralVersusIonPrompt.centerY;\n    neutralAtomVersusIonQuestion.addChild(neutralAtomButton);\n    ionButton.left = neutralAtomVersusIonQuestion.right + 10;\n    ionButton.centerY = neutralVersusIonPrompt.centerY;\n    neutralAtomVersusIonQuestion.addChild(ionButton);\n    this.interactiveAnswerNode.addChild(neutralAtomVersusIonQuestion);\n    this.periodicTableAtom.protonCountProperty.link(function (protonCount) {\n      neutralAtomVersusIonQuestion.visible = protonCount > 0;\n    });\n    this.neutralOrIon.link(function (neutralOrIon) {\n      thisNode.checkAnswerButton.enabled = neutralOrIon !== 'noSelection';\n      thisNode.checkAnswerButton.pickable = neutralOrIon !== 'noSelection';\n    });\n    this.periodicTable.right = layoutBounds.width - INSET;\n    this.periodicTable.centerY = layoutBounds.height / 2;\n    var maxTitleWidth = this.periodicTable.width * 0.9;\n    if (problemTitle.width > maxTitleWidth) {\n      problemTitle.scale(maxTitleWidth / problemTitle.width);\n    }\n    problemTitle.centerX = this.periodicTable.centerX;\n    problemTitle.bottom = this.periodicTable.top - 30;\n    neutralAtomVersusIonQuestion.centerX = this.periodicTable.centerX;\n    neutralAtomVersusIonQuestion.top = this.periodicTable.bottom + 20;\n    this.setButtonCenter(this.periodicTable.centerX, neutralAtomVersusIonQuestion.bottom + 40);\n  }\n  inherit(ProblemView, CountsToElementProblemView, {\n    periodicTableAtom: new NumberAtom(),\n    neutralOrIon: new Property('noSelection'),\n    checkAnswer: function () {\n      var submittedAtom = new NumberAtom({\n          protonCount: this.periodicTableAtom.protonCount,\n          neutronCount: this.problem.answerAtom.neutronCount,\n          electronCount: this.problem.answerAtom.electronCount\n        });\n      this.problem.checkAnswer(submittedAtom, this.neutralOrIon.value);\n    },\n    clearAnswer: function () {\n      this.periodicTableAtom.protonCount = 0;\n      this.periodicTableAtom.neutronCount = 0;\n      this.periodicTableAtom.electronCount = 0;\n      this.neutralOrIon.reset();\n    },\n    displayCorrectAnswer: function () {\n      this.periodicTableAtom.protonCount = this.problem.answerAtom.protonCount;\n      this.periodicTableAtom.neutronCount = this.problem.answerAtom.neutronCount;\n      this.periodicTableAtom.electronCount = this.problem.answerAtom.electronCount;\n      this.neutralOrIon.value = this.problem.answerAtom.charge === 0 ? 'neutral' : 'ion';\n    }\n  });\n  return CountsToElementProblemView;\n});",
    "\ndefine('game/view/CountsToElementProblemView',['require','SCENERY_PHET/PhetFont','game/view/ParticleCountsNode','PHET_CORE/inherit','SCENERY/nodes/Node','game/view/ToElementProblemView','SCENERY/nodes/Text'],function (require) {\n  'use strict';\n  var PhetFont = require('SCENERY_PHET/PhetFont');\n  var ParticleCountsNode = require('game/view/ParticleCountsNode');\n  var inherit = require('PHET_CORE/inherit');\n  var Node = require('SCENERY/nodes/Node');\n  var ToElementProblemView = require('game/view/ToElementProblemView');\n  var Text = require('SCENERY/nodes/Text');\n  function CountsToElementProblemView(countsToElementProblem, layoutBounds) {\n    ToElementProblemView.call(this, countsToElementProblem, layoutBounds);\n    var particleCountsNode = new ParticleCountsNode(countsToElementProblem.answerAtom);\n    this.problemPresentationNode.addChild(particleCountsNode);\n    particleCountsNode.centerX = layoutBounds.width * 0.25;\n    particleCountsNode.centerY = this.periodicTable.centerY;\n  }\n  inherit(ToElementProblemView, CountsToElementProblemView);\n  return CountsToElementProblemView;\n});",
    "\ndefine('game/model/CountsToElementProblem',['require','game/model/ToElementProblem','game/view/CountsToElementProblemView','PHET_CORE/inherit','common/SharedConstants'],function (require) {\n  'use strict';\n  var ToElementProblem = require('game/model/ToElementProblem');\n  var CountsToElementProblemView = require('game/view/CountsToElementProblemView');\n  var inherit = require('PHET_CORE/inherit');\n  var SharedConstants = require('common/SharedConstants');\n  function CountsToElementProblem(buildAnAtomGameModel, answerAtom) {\n    ToElementProblem.call(this, buildAnAtomGameModel, answerAtom);\n  }\n  inherit(ToElementProblem, CountsToElementProblem, {\n    createView: function (layoutBounds) {\n      return new CountsToElementProblemView(this, layoutBounds);\n    }\n  });\n  return CountsToElementProblem;\n});",
    "\ndefine('game/view/CountsToMassNumberProblemView',['require','SCENERY_PHET/PhetFont','PHET_CORE/inherit','SCENERY_PHET/MultiLineText','SCENERY/nodes/Node','common/model/NumberAtom','game/view/NumberEntryNode','game/view/ParticleCountsNode','game/view/ProblemView','AXON/Property'],function (require) {\n  'use strict';\n  var PhetFont = require('SCENERY_PHET/PhetFont');\n  var inherit = require('PHET_CORE/inherit');\n  var MultiLineText = require('SCENERY_PHET/MultiLineText');\n  var Node = require('SCENERY/nodes/Node');\n  var NumberAtom = require('common/model/NumberAtom');\n  var NumberEntryNode = require('game/view/NumberEntryNode');\n  var ParticleCountsNode = require('game/view/ParticleCountsNode');\n  var ProblemView = require('game/view/ProblemView');\n  var Property = require('AXON/Property');\n  function CountsToMassNumberProblemView(countsToMassNumberProblem, layoutBounds) {\n    this.massNumberAnswer = new Property(0);\n    ProblemView.call(this, countsToMassNumberProblem, layoutBounds);\n    var thisNode = this;\n    var particleCountsNode = new ParticleCountsNode(countsToMassNumberProblem.answerAtom);\n    this.problemPresentationNode.addChild(particleCountsNode);\n    var questionPrompt = new MultiLineText('What is the\\nmass number?', {\n        align: 'left',\n        font: new PhetFont(24)\n      });\n    this.addChild(questionPrompt);\n    var numberEntryNode = new NumberEntryNode(thisNode.massNumberAnswer);\n    thisNode.addChild(numberEntryNode);\n    particleCountsNode.centerX = layoutBounds.width * 0.25;\n    particleCountsNode.centerY = layoutBounds.height * 0.5;\n    questionPrompt.centerX = layoutBounds.width * 0.65;\n    questionPrompt.centerY = layoutBounds.height * 0.5;\n    numberEntryNode.left = questionPrompt.right + 10;\n    numberEntryNode.centerY = questionPrompt.centerY;\n  }\n  inherit(ProblemView, CountsToMassNumberProblemView, {\n    checkAnswer: function () {\n      var userSubmittedAnswer = new NumberAtom({\n          protonCount: this.problem.answerAtom.protonCount,\n          neutronCount: this.massNumberAnswer.value - this.problem.answerAtom.protonCount,\n          electronCount: this.problem.answerAtom.electronCount\n        });\n      this.problem.checkAnswer(userSubmittedAnswer);\n    },\n    clearAnswer: function () {\n      this.massNumberAnswer.reset();\n    },\n    displayCorrectAnswer: function () {\n      this.massNumberAnswer.value = this.problem.answerAtom.massNumber;\n    }\n  });\n  return CountsToMassNumberProblemView;\n});",
    "\ndefine('game/model/CountsToMassNumberProblem',['require','game/model/BAAGameProblem','game/view/CountsToMassNumberProblemView','PHET_CORE/inherit','common/SharedConstants'],function (require) {\n  'use strict';\n  var BAAGameProblem = require('game/model/BAAGameProblem');\n  var CountsToMassNumberProblemView = require('game/view/CountsToMassNumberProblemView');\n  var inherit = require('PHET_CORE/inherit');\n  var SharedConstants = require('common/SharedConstants');\n  function CountsToMassNumberProblem(buildAnAtomGameModel, answerAtom) {\n    BAAGameProblem.call(this, buildAnAtomGameModel, answerAtom);\n  }\n  inherit(BAAGameProblem, CountsToMassNumberProblem, {\n    createView: function (layoutBounds) {\n      return new CountsToMassNumberProblemView(this, layoutBounds);\n    }\n  });\n  return CountsToMassNumberProblem;\n});",
    "\ndefine('game/model/AtomValuePool',['require','common/model/NumberAtom'],function (require) {\n  'use strict';\n  var NumberAtom = require('common/model/NumberAtom');\n  var PROBLEM_POOLS = [\n      [\n        new NumberAtom({\n          protonCount: 1,\n          neutronCount: 0,\n          electronCount: 0\n        }),\n        new NumberAtom({\n          protonCount: 1,\n          neutronCount: 0,\n          electronCount: 1\n        }),\n        new NumberAtom({\n          protonCount: 1,\n          neutronCount: 0,\n          electronCount: 2\n        }),\n        new NumberAtom({\n          protonCount: 1,\n          neutronCount: 1,\n          electronCount: 0\n        }),\n        new NumberAtom({\n          protonCount: 1,\n          neutronCount: 1,\n          electronCount: 1\n        }),\n        new NumberAtom({\n          protonCount: 1,\n          neutronCount: 1,\n          electronCount: 2\n        }),\n        new NumberAtom({\n          protonCount: 2,\n          neutronCount: 1,\n          electronCount: 2\n        }),\n        new NumberAtom({\n          protonCount: 2,\n          neutronCount: 2,\n          electronCount: 2\n        }),\n        new NumberAtom({\n          protonCount: 3,\n          neutronCount: 3,\n          electronCount: 2\n        }),\n        new NumberAtom({\n          protonCount: 3,\n          neutronCount: 3,\n          electronCount: 3\n        }),\n        new NumberAtom({\n          protonCount: 3,\n          neutronCount: 4,\n          electronCount: 2\n        }),\n        new NumberAtom({\n          protonCount: 3,\n          neutronCount: 4,\n          electronCount: 3\n        }),\n        new NumberAtom({\n          protonCount: 4,\n          neutronCount: 5,\n          electronCount: 4\n        }),\n        new NumberAtom({\n          protonCount: 5,\n          neutronCount: 5,\n          electronCount: 5\n        }),\n        new NumberAtom({\n          protonCount: 5,\n          neutronCount: 6,\n          electronCount: 5\n        }),\n        new NumberAtom({\n          protonCount: 6,\n          neutronCount: 6,\n          electronCount: 6\n        }),\n        new NumberAtom({\n          protonCount: 6,\n          neutronCount: 7,\n          electronCount: 6\n        }),\n        new NumberAtom({\n          protonCount: 7,\n          neutronCount: 7,\n          electronCount: 7\n        }),\n        new NumberAtom({\n          protonCount: 7,\n          neutronCount: 7,\n          electronCount: 10\n        }),\n        new NumberAtom({\n          protonCount: 7,\n          neutronCount: 8,\n          electronCount: 7\n        }),\n        new NumberAtom({\n          protonCount: 7,\n          neutronCount: 8,\n          electronCount: 10\n        }),\n        new NumberAtom({\n          protonCount: 8,\n          neutronCount: 8,\n          electronCount: 8\n        }),\n        new NumberAtom({\n          protonCount: 8,\n          neutronCount: 8,\n          electronCount: 10\n        }),\n        new NumberAtom({\n          protonCount: 8,\n          neutronCount: 9,\n          electronCount: 8\n        }),\n        new NumberAtom({\n          protonCount: 8,\n          neutronCount: 9,\n          electronCount: 10\n        }),\n        new NumberAtom({\n          protonCount: 8,\n          neutronCount: 10,\n          electronCount: 8\n        }),\n        new NumberAtom({\n          protonCount: 8,\n          neutronCount: 10,\n          electronCount: 10\n        }),\n        new NumberAtom({\n          protonCount: 9,\n          neutronCount: 10,\n          electronCount: 9\n        }),\n        new NumberAtom({\n          protonCount: 9,\n          neutronCount: 10,\n          electronCount: 10\n        }),\n        new NumberAtom({\n          protonCount: 10,\n          neutronCount: 10,\n          electronCount: 10\n        }),\n        new NumberAtom({\n          protonCount: 10,\n          neutronCount: 11,\n          electronCount: 10\n        }),\n        new NumberAtom({\n          protonCount: 10,\n          neutronCount: 12,\n          electronCount: 10\n        })\n      ],\n      [\n        new NumberAtom({\n          protonCount: 1,\n          neutronCount: 0,\n          electronCount: 0\n        }),\n        new NumberAtom({\n          protonCount: 1,\n          neutronCount: 0,\n          electronCount: 1\n        }),\n        new NumberAtom({\n          protonCount: 1,\n          neutronCount: 0,\n          electronCount: 2\n        }),\n        new NumberAtom({\n          protonCount: 1,\n          neutronCount: 1,\n          electronCount: 0\n        }),\n        new NumberAtom({\n          protonCount: 1,\n          neutronCount: 1,\n          electronCount: 1\n        }),\n        new NumberAtom({\n          protonCount: 1,\n          neutronCount: 1,\n          electronCount: 2\n        }),\n        new NumberAtom({\n          protonCount: 2,\n          neutronCount: 1,\n          electronCount: 2\n        }),\n        new NumberAtom({\n          protonCount: 2,\n          neutronCount: 2,\n          electronCount: 2\n        }),\n        new NumberAtom({\n          protonCount: 3,\n          neutronCount: 3,\n          electronCount: 2\n        }),\n        new NumberAtom({\n          protonCount: 3,\n          neutronCount: 3,\n          electronCount: 3\n        }),\n        new NumberAtom({\n          protonCount: 3,\n          neutronCount: 4,\n          electronCount: 2\n        }),\n        new NumberAtom({\n          protonCount: 3,\n          neutronCount: 4,\n          electronCount: 3\n        }),\n        new NumberAtom({\n          protonCount: 4,\n          neutronCount: 5,\n          electronCount: 4\n        }),\n        new NumberAtom({\n          protonCount: 5,\n          neutronCount: 5,\n          electronCount: 5\n        }),\n        new NumberAtom({\n          protonCount: 5,\n          neutronCount: 6,\n          electronCount: 5\n        }),\n        new NumberAtom({\n          protonCount: 6,\n          neutronCount: 6,\n          electronCount: 6\n        }),\n        new NumberAtom({\n          protonCount: 6,\n          neutronCount: 7,\n          electronCount: 6\n        }),\n        new NumberAtom({\n          protonCount: 7,\n          neutronCount: 7,\n          electronCount: 7\n        }),\n        new NumberAtom({\n          protonCount: 7,\n          neutronCount: 7,\n          electronCount: 10\n        }),\n        new NumberAtom({\n          protonCount: 7,\n          neutronCount: 8,\n          electronCount: 7\n        }),\n        new NumberAtom({\n          protonCount: 7,\n          neutronCount: 8,\n          electronCount: 10\n        }),\n        new NumberAtom({\n          protonCount: 8,\n          neutronCount: 8,\n          electronCount: 8\n        }),\n        new NumberAtom({\n          protonCount: 8,\n          neutronCount: 8,\n          electronCount: 10\n        }),\n        new NumberAtom({\n          protonCount: 8,\n          neutronCount: 9,\n          electronCount: 8\n        }),\n        new NumberAtom({\n          protonCount: 8,\n          neutronCount: 9,\n          electronCount: 10\n        }),\n        new NumberAtom({\n          protonCount: 8,\n          neutronCount: 10,\n          electronCount: 8\n        }),\n        new NumberAtom({\n          protonCount: 8,\n          neutronCount: 10,\n          electronCount: 10\n        }),\n        new NumberAtom({\n          protonCount: 9,\n          neutronCount: 10,\n          electronCount: 9\n        }),\n        new NumberAtom({\n          protonCount: 9,\n          neutronCount: 10,\n          electronCount: 10\n        }),\n        new NumberAtom({\n          protonCount: 10,\n          neutronCount: 10,\n          electronCount: 10\n        }),\n        new NumberAtom({\n          protonCount: 10,\n          neutronCount: 11,\n          electronCount: 10\n        }),\n        new NumberAtom({\n          protonCount: 10,\n          neutronCount: 12,\n          electronCount: 10\n        })\n      ],\n      [\n        new NumberAtom({\n          protonCount: 1,\n          neutronCount: 0,\n          electronCount: 0\n        }),\n        new NumberAtom({\n          protonCount: 1,\n          neutronCount: 0,\n          electronCount: 1\n        }),\n        new NumberAtom({\n          protonCount: 1,\n          neutronCount: 0,\n          electronCount: 2\n        }),\n        new NumberAtom({\n          protonCount: 1,\n          neutronCount: 1,\n          electronCount: 0\n        }),\n        new NumberAtom({\n          protonCount: 1,\n          neutronCount: 1,\n          electronCount: 1\n        }),\n        new NumberAtom({\n          protonCount: 1,\n          neutronCount: 1,\n          electronCount: 2\n        }),\n        new NumberAtom({\n          protonCount: 2,\n          neutronCount: 1,\n          electronCount: 2\n        }),\n        new NumberAtom({\n          protonCount: 2,\n          neutronCount: 2,\n          electronCount: 2\n        }),\n        new NumberAtom({\n          protonCount: 3,\n          neutronCount: 3,\n          electronCount: 2\n        }),\n        new NumberAtom({\n          protonCount: 3,\n          neutronCount: 3,\n          electronCount: 3\n        }),\n        new NumberAtom({\n          protonCount: 3,\n          neutronCount: 4,\n          electronCount: 2\n        }),\n        new NumberAtom({\n          protonCount: 3,\n          neutronCount: 4,\n          electronCount: 3\n        }),\n        new NumberAtom({\n          protonCount: 4,\n          neutronCount: 5,\n          electronCount: 4\n        }),\n        new NumberAtom({\n          protonCount: 5,\n          neutronCount: 5,\n          electronCount: 5\n        }),\n        new NumberAtom({\n          protonCount: 5,\n          neutronCount: 6,\n          electronCount: 5\n        }),\n        new NumberAtom({\n          protonCount: 6,\n          neutronCount: 6,\n          electronCount: 6\n        }),\n        new NumberAtom({\n          protonCount: 6,\n          neutronCount: 7,\n          electronCount: 6\n        }),\n        new NumberAtom({\n          protonCount: 7,\n          neutronCount: 7,\n          electronCount: 7\n        }),\n        new NumberAtom({\n          protonCount: 7,\n          neutronCount: 7,\n          electronCount: 10\n        }),\n        new NumberAtom({\n          protonCount: 7,\n          neutronCount: 8,\n          electronCount: 7\n        }),\n        new NumberAtom({\n          protonCount: 7,\n          neutronCount: 8,\n          electronCount: 10\n        }),\n        new NumberAtom({\n          protonCount: 8,\n          neutronCount: 8,\n          electronCount: 8\n        }),\n        new NumberAtom({\n          protonCount: 8,\n          neutronCount: 8,\n          electronCount: 10\n        }),\n        new NumberAtom({\n          protonCount: 8,\n          neutronCount: 9,\n          electronCount: 8\n        }),\n        new NumberAtom({\n          protonCount: 8,\n          neutronCount: 9,\n          electronCount: 10\n        }),\n        new NumberAtom({\n          protonCount: 8,\n          neutronCount: 10,\n          electronCount: 8\n        }),\n        new NumberAtom({\n          protonCount: 8,\n          neutronCount: 10,\n          electronCount: 10\n        }),\n        new NumberAtom({\n          protonCount: 9,\n          neutronCount: 10,\n          electronCount: 9\n        }),\n        new NumberAtom({\n          protonCount: 9,\n          neutronCount: 10,\n          electronCount: 10\n        }),\n        new NumberAtom({\n          protonCount: 10,\n          neutronCount: 10,\n          electronCount: 10\n        }),\n        new NumberAtom({\n          protonCount: 10,\n          neutronCount: 11,\n          electronCount: 10\n        }),\n        new NumberAtom({\n          protonCount: 10,\n          neutronCount: 12,\n          electronCount: 10\n        }),\n        new NumberAtom({\n          protonCount: 11,\n          neutronCount: 12,\n          electronCount: 10\n        }),\n        new NumberAtom({\n          protonCount: 11,\n          neutronCount: 12,\n          electronCount: 11\n        }),\n        new NumberAtom({\n          protonCount: 12,\n          neutronCount: 12,\n          electronCount: 10\n        }),\n        new NumberAtom({\n          protonCount: 12,\n          neutronCount: 12,\n          electronCount: 12\n        }),\n        new NumberAtom({\n          protonCount: 12,\n          neutronCount: 13,\n          electronCount: 10\n        }),\n        new NumberAtom({\n          protonCount: 12,\n          neutronCount: 13,\n          electronCount: 12\n        }),\n        new NumberAtom({\n          protonCount: 12,\n          neutronCount: 14,\n          electronCount: 10\n        }),\n        new NumberAtom({\n          protonCount: 12,\n          neutronCount: 14,\n          electronCount: 12\n        }),\n        new NumberAtom({\n          protonCount: 13,\n          neutronCount: 14,\n          electronCount: 10\n        }),\n        new NumberAtom({\n          protonCount: 13,\n          neutronCount: 14,\n          electronCount: 13\n        }),\n        new NumberAtom({\n          protonCount: 14,\n          neutronCount: 14,\n          electronCount: 14\n        }),\n        new NumberAtom({\n          protonCount: 14,\n          neutronCount: 15,\n          electronCount: 14\n        }),\n        new NumberAtom({\n          protonCount: 14,\n          neutronCount: 16,\n          electronCount: 14\n        }),\n        new NumberAtom({\n          protonCount: 15,\n          neutronCount: 16,\n          electronCount: 15\n        }),\n        new NumberAtom({\n          protonCount: 16,\n          neutronCount: 16,\n          electronCount: 16\n        }),\n        new NumberAtom({\n          protonCount: 16,\n          neutronCount: 16,\n          electronCount: 18\n        }),\n        new NumberAtom({\n          protonCount: 16,\n          neutronCount: 17,\n          electronCount: 16\n        }),\n        new NumberAtom({\n          protonCount: 16,\n          neutronCount: 17,\n          electronCount: 18\n        }),\n        new NumberAtom({\n          protonCount: 16,\n          neutronCount: 18,\n          electronCount: 16\n        }),\n        new NumberAtom({\n          protonCount: 16,\n          neutronCount: 18,\n          electronCount: 18\n        }),\n        new NumberAtom({\n          protonCount: 16,\n          neutronCount: 19,\n          electronCount: 16\n        }),\n        new NumberAtom({\n          protonCount: 16,\n          neutronCount: 19,\n          electronCount: 18\n        }),\n        new NumberAtom({\n          protonCount: 17,\n          neutronCount: 18,\n          electronCount: 17\n        }),\n        new NumberAtom({\n          protonCount: 17,\n          neutronCount: 18,\n          electronCount: 18\n        }),\n        new NumberAtom({\n          protonCount: 17,\n          neutronCount: 20,\n          electronCount: 17\n        }),\n        new NumberAtom({\n          protonCount: 17,\n          neutronCount: 20,\n          electronCount: 18\n        }),\n        new NumberAtom({\n          protonCount: 18,\n          neutronCount: 20,\n          electronCount: 18\n        }),\n        new NumberAtom({\n          protonCount: 18,\n          neutronCount: 22,\n          electronCount: 18\n        })\n      ],\n      [\n        new NumberAtom({\n          protonCount: 1,\n          neutronCount: 0,\n          electronCount: 0\n        }),\n        new NumberAtom({\n          protonCount: 1,\n          neutronCount: 0,\n          electronCount: 1\n        }),\n        new NumberAtom({\n          protonCount: 1,\n          neutronCount: 0,\n          electronCount: 2\n        }),\n        new NumberAtom({\n          protonCount: 1,\n          neutronCount: 1,\n          electronCount: 0\n        }),\n        new NumberAtom({\n          protonCount: 1,\n          neutronCount: 1,\n          electronCount: 1\n        }),\n        new NumberAtom({\n          protonCount: 1,\n          neutronCount: 1,\n          electronCount: 2\n        }),\n        new NumberAtom({\n          protonCount: 2,\n          neutronCount: 1,\n          electronCount: 2\n        }),\n        new NumberAtom({\n          protonCount: 2,\n          neutronCount: 2,\n          electronCount: 2\n        }),\n        new NumberAtom({\n          protonCount: 3,\n          neutronCount: 3,\n          electronCount: 2\n        }),\n        new NumberAtom({\n          protonCount: 3,\n          neutronCount: 3,\n          electronCount: 3\n        }),\n        new NumberAtom({\n          protonCount: 3,\n          neutronCount: 4,\n          electronCount: 2\n        }),\n        new NumberAtom({\n          protonCount: 3,\n          neutronCount: 4,\n          electronCount: 3\n        }),\n        new NumberAtom({\n          protonCount: 4,\n          neutronCount: 5,\n          electronCount: 4\n        }),\n        new NumberAtom({\n          protonCount: 5,\n          neutronCount: 5,\n          electronCount: 5\n        }),\n        new NumberAtom({\n          protonCount: 5,\n          neutronCount: 6,\n          electronCount: 5\n        }),\n        new NumberAtom({\n          protonCount: 6,\n          neutronCount: 6,\n          electronCount: 6\n        }),\n        new NumberAtom({\n          protonCount: 6,\n          neutronCount: 7,\n          electronCount: 6\n        }),\n        new NumberAtom({\n          protonCount: 7,\n          neutronCount: 7,\n          electronCount: 7\n        }),\n        new NumberAtom({\n          protonCount: 7,\n          neutronCount: 7,\n          electronCount: 10\n        }),\n        new NumberAtom({\n          protonCount: 7,\n          neutronCount: 8,\n          electronCount: 7\n        }),\n        new NumberAtom({\n          protonCount: 7,\n          neutronCount: 8,\n          electronCount: 10\n        }),\n        new NumberAtom({\n          protonCount: 8,\n          neutronCount: 8,\n          electronCount: 8\n        }),\n        new NumberAtom({\n          protonCount: 8,\n          neutronCount: 8,\n          electronCount: 10\n        }),\n        new NumberAtom({\n          protonCount: 8,\n          neutronCount: 9,\n          electronCount: 8\n        }),\n        new NumberAtom({\n          protonCount: 8,\n          neutronCount: 9,\n          electronCount: 10\n        }),\n        new NumberAtom({\n          protonCount: 8,\n          neutronCount: 10,\n          electronCount: 8\n        }),\n        new NumberAtom({\n          protonCount: 8,\n          neutronCount: 10,\n          electronCount: 10\n        }),\n        new NumberAtom({\n          protonCount: 9,\n          neutronCount: 10,\n          electronCount: 9\n        }),\n        new NumberAtom({\n          protonCount: 9,\n          neutronCount: 10,\n          electronCount: 10\n        }),\n        new NumberAtom({\n          protonCount: 10,\n          neutronCount: 10,\n          electronCount: 10\n        }),\n        new NumberAtom({\n          protonCount: 10,\n          neutronCount: 11,\n          electronCount: 10\n        }),\n        new NumberAtom({\n          protonCount: 10,\n          neutronCount: 12,\n          electronCount: 10\n        }),\n        new NumberAtom({\n          protonCount: 11,\n          neutronCount: 12,\n          electronCount: 10\n        }),\n        new NumberAtom({\n          protonCount: 11,\n          neutronCount: 12,\n          electronCount: 11\n        }),\n        new NumberAtom({\n          protonCount: 12,\n          neutronCount: 12,\n          electronCount: 10\n        }),\n        new NumberAtom({\n          protonCount: 12,\n          neutronCount: 12,\n          electronCount: 12\n        }),\n        new NumberAtom({\n          protonCount: 12,\n          neutronCount: 13,\n          electronCount: 10\n        }),\n        new NumberAtom({\n          protonCount: 12,\n          neutronCount: 13,\n          electronCount: 12\n        }),\n        new NumberAtom({\n          protonCount: 12,\n          neutronCount: 14,\n          electronCount: 10\n        }),\n        new NumberAtom({\n          protonCount: 12,\n          neutronCount: 14,\n          electronCount: 12\n        }),\n        new NumberAtom({\n          protonCount: 13,\n          neutronCount: 14,\n          electronCount: 10\n        }),\n        new NumberAtom({\n          protonCount: 13,\n          neutronCount: 14,\n          electronCount: 13\n        }),\n        new NumberAtom({\n          protonCount: 14,\n          neutronCount: 14,\n          electronCount: 14\n        }),\n        new NumberAtom({\n          protonCount: 14,\n          neutronCount: 15,\n          electronCount: 14\n        }),\n        new NumberAtom({\n          protonCount: 14,\n          neutronCount: 16,\n          electronCount: 14\n        }),\n        new NumberAtom({\n          protonCount: 15,\n          neutronCount: 16,\n          electronCount: 15\n        }),\n        new NumberAtom({\n          protonCount: 16,\n          neutronCount: 16,\n          electronCount: 16\n        }),\n        new NumberAtom({\n          protonCount: 16,\n          neutronCount: 16,\n          electronCount: 18\n        }),\n        new NumberAtom({\n          protonCount: 16,\n          neutronCount: 17,\n          electronCount: 16\n        }),\n        new NumberAtom({\n          protonCount: 16,\n          neutronCount: 17,\n          electronCount: 18\n        }),\n        new NumberAtom({\n          protonCount: 16,\n          neutronCount: 18,\n          electronCount: 16\n        }),\n        new NumberAtom({\n          protonCount: 16,\n          neutronCount: 18,\n          electronCount: 18\n        }),\n        new NumberAtom({\n          protonCount: 16,\n          neutronCount: 19,\n          electronCount: 16\n        }),\n        new NumberAtom({\n          protonCount: 16,\n          neutronCount: 19,\n          electronCount: 18\n        }),\n        new NumberAtom({\n          protonCount: 17,\n          neutronCount: 18,\n          electronCount: 17\n        }),\n        new NumberAtom({\n          protonCount: 17,\n          neutronCount: 18,\n          electronCount: 18\n        }),\n        new NumberAtom({\n          protonCount: 17,\n          neutronCount: 20,\n          electronCount: 17\n        }),\n        new NumberAtom({\n          protonCount: 17,\n          neutronCount: 20,\n          electronCount: 18\n        }),\n        new NumberAtom({\n          protonCount: 18,\n          neutronCount: 20,\n          electronCount: 18\n        }),\n        new NumberAtom({\n          protonCount: 18,\n          neutronCount: 22,\n          electronCount: 18\n        })\n      ]\n    ];\n  function AtomValuePool(level) {\n    this.remainingAtomValues = PROBLEM_POOLS[level];\n    this.usedAtomValues = [];\n  }\n  AtomValuePool.prototype.markAtomAsUsed = function (atomValueToRemove) {\n    if (this.remainingAtomValues.indexOf(atomValueToRemove) !== -1) {\n      this.remainingAtomValues = _.without(this.remainingAtomValues, atomValueToRemove);\n      this.usedAtomValues.push(atomValueToRemove);\n    }\n  };\n  AtomValuePool.prototype.getRandomAtomValue = function (minProtonCount, maxProtonCount, requireCharged) {\n    var meetsCriteria = function (numberAtom) {\n      return numberAtom.protonCount >= minProtonCount && numberAtom.protonCount < maxProtonCount && (!requireCharged || numberAtom.charge !== 0);\n    };\n    var allowableAtomValues = [];\n    this.remainingAtomValues.forEach(function (numberAtom) {\n      if (meetsCriteria(numberAtom)) {\n        allowableAtomValues.push(numberAtom);\n      }\n    });\n    if (allowableAtomValues.length === 0) {\n      this.usedAtomValues.forEach(function (numberAtom) {\n        if (meetsCriteria(numberAtom)) {\n          allowableAtomValues.push(numberAtom);\n        }\n      });\n    }\n    var atomValue = null;\n    if (allowableAtomValues.length > 0) {\n      atomValue = allowableAtomValues[Math.floor(Math.random() * allowableAtomValues.length)];\n    } else {\n      throw 'Error: No atoms found that match the specified criteria';\n    }\n    return atomValue;\n  };\n  return AtomValuePool;\n});",
    "\ndefine('game/view/NonInteractiveSchematicAtomNode',['require','common/view/AtomNode','SCENERY/nodes/Node','PHET_CORE/inherit','common/model/ParticleAtom','common/view/ParticleView','common/model/Particle','AXON/Property'],function (require) {\n  'use strict';\n  var AtomNode = require('common/view/AtomNode');\n  var Node = require('SCENERY/nodes/Node');\n  var inherit = require('PHET_CORE/inherit');\n  var ParticleAtom = require('common/model/ParticleAtom');\n  var ParticleView = require('common/view/ParticleView');\n  var Particle = require('common/model/Particle');\n  var Property = require('AXON/Property');\n  var NonInteractiveSchematicAtomNode = function NonInteractiveSchematicAtomNode(numberAtom, mvt) {\n    Node.call(this, { pickable: false });\n    var thisNode = this;\n    var particleAtom = new ParticleAtom();\n    this.addChild(new AtomNode(particleAtom, mvt, {\n      showElementNameProperty: new Property(false),\n      showNeutralOrIonProperty: new Property(false),\n      showStableOrUnstableProperty: new Property(false)\n    }));\n    var particleLayer = new Node();\n    this.addChild(particleLayer);\n    var createAndAddParticles = function (particleType, number) {\n      _.times(number, function () {\n        var particle = new Particle(particleType);\n        particleAtom.addParticle(particle);\n        particleLayer.addChild(new ParticleView(particle, mvt));\n      });\n    };\n    createAndAddParticles('proton', numberAtom.protonCount);\n    createAndAddParticles('neutron', numberAtom.neutronCount);\n    createAndAddParticles('electron', numberAtom.electronCount);\n    particleAtom.moveAllParticlesToDestination();\n    var particleViewsInNucleus = _.filter(particleLayer.children, function (particleView) {\n        return particleView.particle.destination.distance(particleAtom.position) < particleAtom.innerElectronShellRadius;\n      });\n    if (particleViewsInNucleus.length > 3) {\n      particleViewsInNucleus = _.sortBy(particleViewsInNucleus, function (particleView) {\n        return -particleView.particle.destination.distance(particleAtom.position);\n      });\n      particleViewsInNucleus.forEach(function (particleView) {\n        particleLayer.removeChild(particleView);\n        particleLayer.addChild(particleView);\n      });\n    }\n  };\n  inherit(Node, NonInteractiveSchematicAtomNode);\n  return NonInteractiveSchematicAtomNode;\n});",
    "\ndefine('game/view/SchematicToChargeProblemView',['require','SCENERY_PHET/PhetFont','PHET_CORE/inherit','PHETCOMMON/view/ModelViewTransform2','SCENERY_PHET/MultiLineText','SCENERY/nodes/Node','game/view/NonInteractiveSchematicAtomNode','common/model/NumberAtom','game/view/NumberEntryNode','game/view/ProblemView','AXON/Property','common/SharedConstants'],function (require) {\n  'use strict';\n  var PhetFont = require('SCENERY_PHET/PhetFont');\n  var inherit = require('PHET_CORE/inherit');\n  var ModelViewTransform2 = require('PHETCOMMON/view/ModelViewTransform2');\n  var MultiLineText = require('SCENERY_PHET/MultiLineText');\n  var Node = require('SCENERY/nodes/Node');\n  var NonInteractiveSchematicAtomNode = require('game/view/NonInteractiveSchematicAtomNode');\n  var NumberAtom = require('common/model/NumberAtom');\n  var NumberEntryNode = require('game/view/NumberEntryNode');\n  var ProblemView = require('game/view/ProblemView');\n  var Property = require('AXON/Property');\n  var SharedConstants = require('common/SharedConstants');\n  function SchematicToChargeProblemView(schematicToChargeProblem, layoutBounds) {\n    this.chargeAnswer = new Property(0);\n    ProblemView.call(this, schematicToChargeProblem, layoutBounds);\n    var thisNode = this;\n    var mvt = ModelViewTransform2.createSinglePointScaleInvertedYMapping({\n        x: 0,\n        y: 0\n      }, {\n        x: layoutBounds.width * 0.275,\n        y: layoutBounds.height * 0.45\n      }, 0.8);\n    this.addChild(new NonInteractiveSchematicAtomNode(schematicToChargeProblem.answerAtom, mvt));\n    var questionPrompt = new MultiLineText('What is the\\ntotal charge?', {\n        align: 'left',\n        font: new PhetFont(24)\n      });\n    this.addChild(questionPrompt);\n    var numberEntryNode = new NumberEntryNode(thisNode.chargeAnswer, {\n        prependPlusSign: true,\n        getTextColor: SharedConstants.CHARGE_TEXT_COLOR\n      });\n    thisNode.addChild(numberEntryNode);\n    questionPrompt.centerX = layoutBounds.width * 0.65;\n    questionPrompt.centerY = layoutBounds.height * 0.5;\n    numberEntryNode.left = questionPrompt.right + 10;\n    numberEntryNode.centerY = questionPrompt.centerY;\n  }\n  inherit(ProblemView, SchematicToChargeProblemView, {\n    checkAnswer: function () {\n      var userSubmittedAnswer = new NumberAtom({\n          protonCount: this.problem.answerAtom.protonCount,\n          neutronCount: this.problem.answerAtom.neutronCount,\n          electronCount: this.problem.answerAtom.protonCount - this.chargeAnswer.value\n        });\n      this.problem.checkAnswer(userSubmittedAnswer);\n    },\n    clearAnswer: function () {\n      this.chargeAnswer.reset();\n    },\n    displayCorrectAnswer: function () {\n      this.chargeAnswer.value = this.problem.answerAtom.charge;\n    }\n  });\n  return SchematicToChargeProblemView;\n});",
    "\ndefine('game/model/SchematicToChargeProblem',['require','game/model/BAAGameProblem','game/view/SchematicToChargeProblemView','PHET_CORE/inherit','common/SharedConstants'],function (require) {\n  'use strict';\n  var BAAGameProblem = require('game/model/BAAGameProblem');\n  var SchematicToChargeProblemView = require('game/view/SchematicToChargeProblemView');\n  var inherit = require('PHET_CORE/inherit');\n  var SharedConstants = require('common/SharedConstants');\n  function SchematicToChargeProblem(buildAnAtomGameModel, answerAtom) {\n    BAAGameProblem.call(this, buildAnAtomGameModel, answerAtom);\n  }\n  inherit(BAAGameProblem, SchematicToChargeProblem, {\n    createView: function (layoutBounds) {\n      return new SchematicToChargeProblemView(this, layoutBounds);\n    }\n  });\n  return SchematicToChargeProblem;\n});",
    "\ndefine('game/view/SchematicToElementProblemView',['require','common/view/AtomNode','PHET_CORE/inherit','PHETCOMMON/view/ModelViewTransform2','SCENERY/nodes/Node','game/view/NonInteractiveSchematicAtomNode','game/view/ToElementProblemView'],function (require) {\n  'use strict';\n  var AtomNode = require('common/view/AtomNode');\n  var inherit = require('PHET_CORE/inherit');\n  var ModelViewTransform2 = require('PHETCOMMON/view/ModelViewTransform2');\n  var Node = require('SCENERY/nodes/Node');\n  var NonInteractiveSchematicAtomNode = require('game/view/NonInteractiveSchematicAtomNode');\n  var ToElementProblemView = require('game/view/ToElementProblemView');\n  function SchematicToElementProblemView(schematicToElementProblem, layoutBounds) {\n    ToElementProblemView.call(this, schematicToElementProblem, layoutBounds);\n    var mvt = ModelViewTransform2.createSinglePointScaleInvertedYMapping({\n        x: 0,\n        y: 0\n      }, {\n        x: layoutBounds.width * 0.275,\n        y: layoutBounds.height * 0.45\n      }, 0.8);\n    this.addChild(new NonInteractiveSchematicAtomNode(schematicToElementProblem.answerAtom, mvt));\n  }\n  inherit(ToElementProblemView, SchematicToElementProblemView);\n  return SchematicToElementProblemView;\n});",
    "\ndefine('game/model/SchematicToElementProblem',['require','game/model/ToElementProblem','game/view/SchematicToElementProblemView','PHET_CORE/inherit','common/SharedConstants'],function (require) {\n  'use strict';\n  var ToElementProblem = require('game/model/ToElementProblem');\n  var SchematicToElementProblemView = require('game/view/SchematicToElementProblemView');\n  var inherit = require('PHET_CORE/inherit');\n  var SharedConstants = require('common/SharedConstants');\n  function SchematicToElementProblem(buildAnAtomGameModel, answerAtom) {\n    ToElementProblem.call(this, buildAnAtomGameModel, answerAtom);\n  }\n  inherit(ToElementProblem, SchematicToElementProblem, {\n    createView: function (layoutBounds) {\n      return new SchematicToElementProblemView(this, layoutBounds);\n    }\n  });\n  return SchematicToElementProblem;\n});",
    "\ndefine('game/view/SchematicToMassNumberProblemView',['require','SCENERY_PHET/PhetFont','PHET_CORE/inherit','PHETCOMMON/view/ModelViewTransform2','SCENERY_PHET/MultiLineText','SCENERY/nodes/Node','game/view/NonInteractiveSchematicAtomNode','common/model/NumberAtom','game/view/NumberEntryNode','game/view/ProblemView','AXON/Property'],function (require) {\n  'use strict';\n  var PhetFont = require('SCENERY_PHET/PhetFont');\n  var inherit = require('PHET_CORE/inherit');\n  var ModelViewTransform2 = require('PHETCOMMON/view/ModelViewTransform2');\n  var MultiLineText = require('SCENERY_PHET/MultiLineText');\n  var Node = require('SCENERY/nodes/Node');\n  var NonInteractiveSchematicAtomNode = require('game/view/NonInteractiveSchematicAtomNode');\n  var NumberAtom = require('common/model/NumberAtom');\n  var NumberEntryNode = require('game/view/NumberEntryNode');\n  var ProblemView = require('game/view/ProblemView');\n  var Property = require('AXON/Property');\n  function SchematicToMassNumberProblemView(schematicToMassNumberProblem, layoutBounds) {\n    this.massNumberAnswer = new Property(0);\n    ProblemView.call(this, schematicToMassNumberProblem, layoutBounds);\n    var thisNode = this;\n    var mvt = ModelViewTransform2.createSinglePointScaleInvertedYMapping({\n        x: 0,\n        y: 0\n      }, {\n        x: layoutBounds.width * 0.275,\n        y: layoutBounds.height * 0.45\n      }, 0.8);\n    this.addChild(new NonInteractiveSchematicAtomNode(schematicToMassNumberProblem.answerAtom, mvt));\n    var questionPrompt = new MultiLineText('What is the\\nmass number?', {\n        align: 'left',\n        font: new PhetFont(24)\n      });\n    this.addChild(questionPrompt);\n    var numberEntryNode = new NumberEntryNode(thisNode.massNumberAnswer, false);\n    thisNode.addChild(numberEntryNode);\n    questionPrompt.centerX = layoutBounds.width * 0.65;\n    questionPrompt.centerY = layoutBounds.height * 0.5;\n    numberEntryNode.left = questionPrompt.right + 10;\n    numberEntryNode.centerY = questionPrompt.centerY;\n  }\n  inherit(ProblemView, SchematicToMassNumberProblemView, {\n    checkAnswer: function () {\n      var userSubmittedAnswer = new NumberAtom({\n          protonCount: this.problem.answerAtom.protonCount,\n          neutronCount: this.massNumberAnswer.value - this.problem.answerAtom.protonCount,\n          electronCount: this.problem.answerAtom.electronCount\n        });\n      this.problem.checkAnswer(userSubmittedAnswer);\n    },\n    clearAnswer: function () {\n      this.massNumberAnswer.reset();\n    },\n    displayCorrectAnswer: function () {\n      this.massNumberAnswer.value = this.problem.answerAtom.massNumber;\n    }\n  });\n  return SchematicToMassNumberProblemView;\n});",
    "\ndefine('game/model/SchematicToMassNumberProblem',['require','game/model/BAAGameProblem','game/view/SchematicToMassNumberProblemView','PHET_CORE/inherit','common/SharedConstants'],function (require) {\n  'use strict';\n  var BAAGameProblem = require('game/model/BAAGameProblem');\n  var SchematicToMassNumberProblemView = require('game/view/SchematicToMassNumberProblemView');\n  var inherit = require('PHET_CORE/inherit');\n  var SharedConstants = require('common/SharedConstants');\n  function SchematicToMassNumberProblem(buildAnAtomGameModel, answerAtom) {\n    BAAGameProblem.call(this, buildAnAtomGameModel, answerAtom);\n  }\n  inherit(BAAGameProblem, SchematicToMassNumberProblem, {\n    createView: function (layoutBounds) {\n      return new SchematicToMassNumberProblemView(this, layoutBounds);\n    }\n  });\n  return SchematicToMassNumberProblem;\n});",
    "\ndefine('game/view/SchematicToSymbolProblemView',['require','PHET_CORE/inherit','PHETCOMMON/view/ModelViewTransform2','SCENERY/nodes/Node','common/model/NumberAtom','game/view/InteractiveSymbolNode','game/view/NonInteractiveSchematicAtomNode','game/view/ProblemView'],function (require) {\n  'use strict';\n  var inherit = require('PHET_CORE/inherit');\n  var ModelViewTransform2 = require('PHETCOMMON/view/ModelViewTransform2');\n  var Node = require('SCENERY/nodes/Node');\n  var NumberAtom = require('common/model/NumberAtom');\n  var InteractiveSymbolNode = require('game/view/InteractiveSymbolNode');\n  var NonInteractiveSchematicAtomNode = require('game/view/NonInteractiveSchematicAtomNode');\n  var ProblemView = require('game/view/ProblemView');\n  function SchematicToSymbolProblemView(toSymbolProblem, layoutBounds) {\n    this.interactiveSymbol = new InteractiveSymbolNode(toSymbolProblem.answerAtom, {\n      interactiveProtonCount: toSymbolProblem.configurableProtonCount,\n      interactiveMassNumber: toSymbolProblem.configurableMassNumber,\n      interactiveCharge: toSymbolProblem.configurableCharge\n    });\n    ProblemView.call(this, toSymbolProblem, layoutBounds);\n    var thisNode = this;\n    this.interactiveSymbol.scale(0.75);\n    this.interactiveAnswerNode.addChild(this.interactiveSymbol);\n    var mvt = ModelViewTransform2.createSinglePointScaleInvertedYMapping({\n        x: 0,\n        y: 0\n      }, {\n        x: layoutBounds.width * 0.275,\n        y: layoutBounds.height * 0.45\n      }, 0.8);\n    var schematicAtomNode = new NonInteractiveSchematicAtomNode(toSymbolProblem.answerAtom, mvt);\n    this.addChild(schematicAtomNode);\n    schematicAtomNode.centerX = layoutBounds.width * 0.25;\n    schematicAtomNode.centerY = layoutBounds.height * 0.4;\n    this.interactiveSymbol.centerX = layoutBounds.width * 0.75;\n    this.interactiveSymbol.centerY = layoutBounds.height * 0.45;\n  }\n  inherit(ProblemView, SchematicToSymbolProblemView, {\n    checkAnswer: function () {\n      var userSubmittedAtom = new NumberAtom({\n          protonCount: this.interactiveSymbol.protonCount.value,\n          neutronCount: this.interactiveSymbol.massNumber.value - this.interactiveSymbol.protonCount.value,\n          electronCount: this.interactiveSymbol.protonCount.value - this.interactiveSymbol.charge.value\n        });\n      this.problem.checkAnswer(userSubmittedAtom);\n    },\n    clearAnswer: function () {\n      this.interactiveSymbol.reset();\n    },\n    displayCorrectAnswer: function () {\n      this.interactiveSymbol.protonCount.value = this.problem.answerAtom.protonCount;\n      this.interactiveSymbol.massNumber.value = this.problem.answerAtom.massNumber;\n      this.interactiveSymbol.charge.value = this.problem.answerAtom.charge;\n    }\n  });\n  return SchematicToSymbolProblemView;\n});",
    "\ndefine('game/model/SchematicToSymbolProblem',['require','game/model/BAAGameProblem','game/view/SchematicToSymbolProblemView','PHET_CORE/inherit','common/SharedConstants'],function (require) {\n  'use strict';\n  var BAAGameProblem = require('game/model/BAAGameProblem');\n  var SchematicToSymbolProblemView = require('game/view/SchematicToSymbolProblemView');\n  var inherit = require('PHET_CORE/inherit');\n  var SharedConstants = require('common/SharedConstants');\n  function SchematicToSymbolProblem(buildAnAtomGameModel, answerAtom, configurableProtonCount, configurableMassNumber, configurableCharge) {\n    BAAGameProblem.call(this, buildAnAtomGameModel, answerAtom);\n    this.configurableProtonCount = configurableProtonCount;\n    this.configurableMassNumber = configurableMassNumber;\n    this.configurableCharge = configurableCharge;\n  }\n  inherit(BAAGameProblem, SchematicToSymbolProblem, {\n    createView: function (layoutBounds) {\n      return new SchematicToSymbolProblemView(this, layoutBounds);\n    }\n  });\n  return SchematicToSymbolProblem;\n});",
    "\ndefine('game/view/InteractiveParticleCountsNode',['require','SCENERY_PHET/PhetFont','SCENERY/nodes/Node','common/model/NumberAtom','game/view/NumberEntryNode','SCENERY/nodes/Text','PHET_CORE/inherit'],function (require) {\n  'use strict';\n  var PhetFont = require('SCENERY_PHET/PhetFont');\n  var Node = require('SCENERY/nodes/Node');\n  var NumberAtom = require('common/model/NumberAtom');\n  var NumberEntryNode = require('game/view/NumberEntryNode');\n  var Text = require('SCENERY/nodes/Text');\n  var inherit = require('PHET_CORE/inherit');\n  function InteractiveParticleCountsNode(options) {\n    Node.call(this, options);\n    options = _.extend({ font: new PhetFont(24) }, options);\n    this.numberAtom = new NumberAtom();\n    var protonCountPrompt = new Text('Protons:', options.font);\n    this.addChild(protonCountPrompt);\n    var protonCountEntry = new NumberEntryNode(this.numberAtom.protonCountProperty);\n    this.addChild(protonCountEntry);\n    var neutronCountPrompt = new Text('Neutrons:', options.font);\n    this.addChild(neutronCountPrompt);\n    var neutronCountEntry = new NumberEntryNode(this.numberAtom.neutronCountProperty);\n    this.addChild(neutronCountEntry);\n    var electronCountPrompt = new Text('Electrons:', options.font);\n    this.addChild(electronCountPrompt);\n    var electronCountEntry = new NumberEntryNode(this.numberAtom.electronCountProperty);\n    this.addChild(electronCountEntry);\n    var maxParticleLabelWidth = Math.max(Math.max(protonCountPrompt.width, neutronCountPrompt.width), electronCountPrompt.width);\n    var interLineSpacing = protonCountPrompt.height * 1.3;\n    protonCountPrompt.left = 0;\n    protonCountPrompt.top = 0;\n    protonCountEntry.centerY = protonCountPrompt.centerY;\n    protonCountEntry.left = maxParticleLabelWidth + protonCountPrompt.height;\n    neutronCountPrompt.left = 0;\n    neutronCountPrompt.top = protonCountPrompt.bottom + interLineSpacing;\n    neutronCountEntry.centerY = neutronCountPrompt.centerY;\n    neutronCountEntry.left = protonCountEntry.left;\n    electronCountPrompt.left = 0;\n    electronCountPrompt.top = neutronCountPrompt.bottom + interLineSpacing;\n    electronCountEntry.centerY = electronCountPrompt.centerY;\n    electronCountEntry.left = protonCountEntry.left;\n  }\n  inherit(Node, InteractiveParticleCountsNode);\n  return InteractiveParticleCountsNode;\n});",
    "\ndefine('game/view/SymbolToCountsProblemView',['require','PHET_CORE/inherit','SCENERY/nodes/Node','common/model/NumberAtom','game/view/InteractiveSymbolNode','game/view/InteractiveParticleCountsNode','game/view/ProblemView'],function (require) {\n  'use strict';\n  var inherit = require('PHET_CORE/inherit');\n  var Node = require('SCENERY/nodes/Node');\n  var NumberAtom = require('common/model/NumberAtom');\n  var InteractiveSymbolNode = require('game/view/InteractiveSymbolNode');\n  var InteractiveParticleCountsNode = require('game/view/InteractiveParticleCountsNode');\n  var ProblemView = require('game/view/ProblemView');\n  function SymbolToCountsProblemView(symbolToCountsProblem, layoutBounds) {\n    this.interactiveSchematicAtom = new InteractiveParticleCountsNode();\n    ProblemView.call(this, symbolToCountsProblem, layoutBounds);\n    this.interactiveAnswerNode.addChild(this.interactiveSchematicAtom);\n    var symbol = new InteractiveSymbolNode(symbolToCountsProblem.answerAtom);\n    symbol.scale(0.75);\n    this.problemPresentationNode.addChild(symbol);\n    symbol.centerX = layoutBounds.width * 0.25;\n    symbol.centerY = layoutBounds.height * 0.5;\n    this.interactiveSchematicAtom.centerX = layoutBounds.width * 0.75;\n    this.interactiveSchematicAtom.centerY = layoutBounds.height * 0.45;\n  }\n  inherit(ProblemView, SymbolToCountsProblemView, {\n    checkAnswer: function () {\n      this.problem.checkAnswer(this.interactiveSchematicAtom.numberAtom);\n    },\n    clearAnswer: function () {\n      this.interactiveSchematicAtom.numberAtom.reset();\n    },\n    displayCorrectAnswer: function () {\n      this.interactiveSchematicAtom.numberAtom.protonCount = this.problem.answerAtom.protonCount;\n      this.interactiveSchematicAtom.numberAtom.neutronCount = this.problem.answerAtom.neutronCount;\n      this.interactiveSchematicAtom.numberAtom.electronCount = this.problem.answerAtom.electronCount;\n    }\n  });\n  return SymbolToCountsProblemView;\n});",
    "\ndefine('game/model/SymbolToCountsProblem',['require','game/model/BAAGameProblem','game/view/SymbolToCountsProblemView','PHET_CORE/inherit','common/SharedConstants'],function (require) {\n  'use strict';\n  var BAAGameProblem = require('game/model/BAAGameProblem');\n  var SymbolToCountsProblemView = require('game/view/SymbolToCountsProblemView');\n  var inherit = require('PHET_CORE/inherit');\n  var SharedConstants = require('common/SharedConstants');\n  function SymbolToCountsProblem(buildAnAtomGameModel, answerAtom) {\n    BAAGameProblem.call(this, buildAnAtomGameModel, answerAtom);\n  }\n  inherit(BAAGameProblem, SymbolToCountsProblem, {\n    createView: function (layoutBounds) {\n      return new SymbolToCountsProblemView(this, layoutBounds);\n    }\n  });\n  return SymbolToCountsProblem;\n});",
    "\ndefine('common/view/InteractiveSchematicAtom',['require','common/view/AtomNode','buildanatom/view/BucketDragHandler','SCENERY_PHET/bucket/BucketFront','SCENERY_PHET/bucket/BucketHole','PHET_CORE/inherit','SCENERY/nodes/Node','common/view/ParticleView'],function (require) {\n  'use strict';\n  var AtomNode = require('common/view/AtomNode');\n  var BucketDragHandler = require('buildanatom/view/BucketDragHandler');\n  var BucketFront = require('SCENERY_PHET/bucket/BucketFront');\n  var BucketHole = require('SCENERY_PHET/bucket/BucketHole');\n  var inherit = require('PHET_CORE/inherit');\n  var Node = require('SCENERY/nodes/Node');\n  var ParticleView = require('common/view/ParticleView');\n  var NUM_NUCLEON_LAYERS = 5;\n  function InteractiveSchematicAtom(model, mvt) {\n    Node.call(this);\n    var thisNode = this;\n    var atomNode = new AtomNode(model.particleAtom, mvt, {\n        showElementNameProperty: model.showElementNameProperty,\n        showNeutralOrIonProperty: model.showNeutralOrIonProperty,\n        showStableOrUnstableProperty: model.showStableOrUnstableProperty,\n        electronShellDepictionProperty: model.electronShellDepictionProperty\n      });\n    this.addChild(atomNode);\n    _.each(model.buckets, function (bucket) {\n      thisNode.addChild(new BucketHole(bucket, mvt));\n    });\n    var nucleonLayers = [];\n    _.times(NUM_NUCLEON_LAYERS, function () {\n      var nucleonLayer = new Node();\n      nucleonLayers.push(nucleonLayer);\n      thisNode.addChild(nucleonLayer);\n    });\n    nucleonLayers.reverse();\n    var electronLayer = new Node({ layerSplit: true });\n    this.addChild(electronLayer);\n    model.nucleons.forEach(function (nucleon) {\n      nucleonLayers[nucleon.zLayer].addChild(new ParticleView(nucleon, mvt));\n      nucleon.zLayerProperty.link(function (zLayer) {\n        null;\n        var onCorrectLayer = false;\n        nucleonLayers[zLayer].children.forEach(function (particleView) {\n          if (particleView.particle === nucleon) {\n            onCorrectLayer = true;\n          }\n        });\n        if (!onCorrectLayer) {\n          var particleView = null;\n          for (var layerIndex = 0; layerIndex < nucleonLayers.length && particleView === null; layerIndex++) {\n            for (var childIndex = 0; childIndex < nucleonLayers[layerIndex].children.length; childIndex++) {\n              if (nucleonLayers[layerIndex].children[childIndex].particle === nucleon) {\n                particleView = nucleonLayers[layerIndex].children[childIndex];\n                nucleonLayers[layerIndex].removeChildAt(childIndex);\n                break;\n              }\n            }\n          }\n          null;\n          nucleonLayers[zLayer].addChild(particleView);\n        }\n      });\n    });\n    model.electrons.forEach(function (electron) {\n      electronLayer.addChild(new ParticleView(electron, mvt));\n    });\n    var updateElectronVisibility = function () {\n      electronLayer.getChildren().forEach(function (electronNode) {\n        electronNode.visible = model.electronShellDepiction === 'orbits' || !model.particleAtom.electrons.contains(electronNode.particle);\n      });\n    };\n    model.particleAtom.electrons.lengthProperty.link(updateElectronVisibility);\n    model.electronShellDepictionProperty.link(updateElectronVisibility);\n    _.each(model.buckets, function (bucket) {\n      var bucketFront = new BucketFront(bucket, mvt);\n      thisNode.addChild(bucketFront);\n      bucketFront.addInputListener(new BucketDragHandler(bucket, bucketFront, mvt));\n    });\n  }\n  return inherit(Node, InteractiveSchematicAtom);\n});",
    "\ndefine('game/view/SymbolToSchematicProblemView',['require','PHET_CORE/inherit','common/view/InteractiveSchematicAtom','game/view/InteractiveSymbolNode','PHETCOMMON/view/ModelViewTransform2','SCENERY/nodes/Node','common/model/NumberAtom','game/view/ProblemView'],function (require) {\n  'use strict';\n  var inherit = require('PHET_CORE/inherit');\n  var InteractiveSchematicAtom = require('common/view/InteractiveSchematicAtom');\n  var InteractiveSymbolNode = require('game/view/InteractiveSymbolNode');\n  var ModelViewTransform2 = require('PHETCOMMON/view/ModelViewTransform2');\n  var Node = require('SCENERY/nodes/Node');\n  var NumberAtom = require('common/model/NumberAtom');\n  var ProblemView = require('game/view/ProblemView');\n  function SymbolToSchematicProblemView(problem, layoutBounds) {\n    var mvt = ModelViewTransform2.createSinglePointScaleInvertedYMapping({\n        x: 0,\n        y: 0\n      }, {\n        x: layoutBounds.width * 0.275,\n        y: layoutBounds.height * 0.45\n      }, 0.75);\n    this.interactiveSchematicAtom = new InteractiveSchematicAtom(problem.buildAnAtomModel, mvt);\n    ProblemView.call(this, problem, layoutBounds);\n    this.interactiveAnswerNode.addChild(this.interactiveSchematicAtom);\n    var symbol = new InteractiveSymbolNode(problem.answerAtom);\n    symbol.scale(0.75);\n    this.problemPresentationNode.addChild(symbol);\n    symbol.centerX = layoutBounds.width * 0.25;\n    symbol.centerY = layoutBounds.height * 0.45;\n    this.interactiveSchematicAtom.centerX = layoutBounds.width * 0.75;\n    this.interactiveSchematicAtom.centerY = layoutBounds.height * 0.4;\n  }\n  inherit(ProblemView, SymbolToSchematicProblemView, {\n    checkAnswer: function () {\n      this.problem.checkAnswer(this.problem.buildAnAtomModel.numberAtom);\n    },\n    clearAnswer: function () {\n    },\n    displayCorrectAnswer: function () {\n      this.problem.buildAnAtomModel.setAtomConfiguration(this.problem.answerAtom);\n    }\n  });\n  return SymbolToSchematicProblemView;\n});",
    "\ndefine('game/model/SymbolToSchematicProblem',['require','game/model/BAAGameProblem','common/model/BuildAnAtomModel','game/view/SymbolToSchematicProblemView','PHET_CORE/inherit','common/SharedConstants'],function (require) {\n  'use strict';\n  var BAAGameProblem = require('game/model/BAAGameProblem');\n  var BuildAnAtomModel = require('common/model/BuildAnAtomModel');\n  var SymbolToSchematicProblemView = require('game/view/SymbolToSchematicProblemView');\n  var inherit = require('PHET_CORE/inherit');\n  var SharedConstants = require('common/SharedConstants');\n  function SymbolToSchematicProblem(buildAnAtomGameModel, answerAtom) {\n    BAAGameProblem.call(this, buildAnAtomGameModel, answerAtom);\n    this.buildAnAtomModel = new BuildAnAtomModel();\n    this.buildAnAtomModel.showElementName = false;\n    this.buildAnAtomModel.showNeutralOrIon = false;\n    this.buildAnAtomModel.showStableOrUnstable = false;\n  }\n  inherit(BAAGameProblem, SymbolToSchematicProblem, {\n    createView: function (layoutBounds) {\n      return new SymbolToSchematicProblemView(this, layoutBounds);\n    },\n    step: function (dt) {\n      this.buildAnAtomModel.step(dt);\n    }\n  });\n  return SymbolToSchematicProblem;\n});",
    "\ndefine('game/model/ProblemSetFactory',['require','game/model/AtomValuePool','game/model/CountsToChargeProblem','game/model/CountsToSymbolProblem','game/model/CountsToElementProblem','game/model/CountsToMassNumberProblem','game/model/SchematicToChargeProblem','game/model/SchematicToElementProblem','game/model/SchematicToMassNumberProblem','game/model/SchematicToSymbolProblem','common/SharedConstants','game/model/SymbolToCountsProblem','game/model/SymbolToSchematicProblem'],function (require) {\n  'use strict';\n  var AtomValuePool = require('game/model/AtomValuePool');\n  var CountsToChargeProblem = require('game/model/CountsToChargeProblem');\n  var CountsToSymbolProblem = require('game/model/CountsToSymbolProblem');\n  var CountsToElementProblem = require('game/model/CountsToElementProblem');\n  var CountsToMassNumberProblem = require('game/model/CountsToMassNumberProblem');\n  var SchematicToChargeProblem = require('game/model/SchematicToChargeProblem');\n  var SchematicToElementProblem = require('game/model/SchematicToElementProblem');\n  var SchematicToMassNumberProblem = require('game/model/SchematicToMassNumberProblem');\n  var SchematicToSymbolProblem = require('game/model/SchematicToSymbolProblem');\n  var SharedConstants = require('common/SharedConstants');\n  var SymbolToCountsProblem = require('game/model/SymbolToCountsProblem');\n  var SymbolToSchematicProblem = require('game/model/SymbolToSchematicProblem');\n  var MAX_PROTON_NUMBER_FOR_SCHEMATIC_PROBS = 3;\n  var ALLOWED_PROBLEM_TYPES_BY_LEVEL = [\n      [\n        'schematic-to-element',\n        'counts-to-element'\n      ],\n      [\n        'counts-to-charge',\n        'counts-to-mass',\n        'schematic-to-charge',\n        'schematic-to-mass'\n      ],\n      [\n        'schematic-to-symbol-charge',\n        'schematic-to-symbol-mass-number',\n        'schematic-to-symbol-proton-count',\n        'counts-to-symbol-charge',\n        'counts-to-symbol-mass'\n      ],\n      [\n        'schematic-to-symbol-all',\n        'symbol-to-schematic',\n        'symbol-to-counts',\n        'counts-to-symbol-all'\n      ]\n    ];\n  var ProblemSetFactory = {};\n  ProblemSetFactory.generate = function (level, numProblems, model) {\n    this.problems = [];\n    this._previousProblemType = null;\n    this._availableProblemTypes = [];\n    var atomValueList = new AtomValuePool(level);\n    for (var i = 0; i < numProblems; i++) {\n      var problem = this._generateProblem(level, atomValueList, model);\n      if (problem !== null) {\n        this.problems.push(problem);\n      }\n    }\n    return this.problems;\n  };\n  ProblemSetFactory._generateProblem = function (level, availableAtomValues, model) {\n    if (this._availableProblemTypes.length === 0) {\n      this._availableProblemTypes = ALLOWED_PROBLEM_TYPES_BY_LEVEL[level].slice();\n    }\n    var index = Math.floor(Math.random() * this._availableProblemTypes.length);\n    if (this._previousProblemType !== null && this._availableProblemTypes.get(index) === this._previousProblemType) {\n      index = (index + 1) % this._availableProblemTypes.length;\n    }\n    var problemType = this._availableProblemTypes[index];\n    this.previousProblemType = problemType;\n    this._availableProblemTypes = _.without(this._availableProblemTypes, problemType);\n    var minProtonCount = 0;\n    var maxProtonCount = Number.POSITIVE_INFINITY;\n    var requireCharged = false;\n    if (this._isSchematicProbType(problemType)) {\n      maxProtonCount = MAX_PROTON_NUMBER_FOR_SCHEMATIC_PROBS;\n    } else {\n      minProtonCount = MAX_PROTON_NUMBER_FOR_SCHEMATIC_PROBS + 1;\n    }\n    if (this._isChargeProbType(problemType)) {\n      requireCharged = Math.random() > 0.5;\n    }\n    var atomValue = availableAtomValues.getRandomAtomValue(minProtonCount, maxProtonCount, requireCharged);\n    availableAtomValues.markAtomAsUsed(atomValue);\n    return this._createProblem(model, problemType, atomValue);\n  };\n  ProblemSetFactory._createProblem = function (model, problemType, atomValue) {\n    var problem = null;\n    switch (problemType) {\n    case 'counts-to-element':\n      problem = new CountsToElementProblem(model, atomValue);\n      break;\n    case 'counts-to-charge':\n      problem = new CountsToChargeProblem(model, atomValue);\n      break;\n    case 'counts-to-mass':\n      problem = new CountsToMassNumberProblem(model, atomValue);\n      break;\n    case 'counts-to-symbol-all':\n      problem = new CountsToSymbolProblem(model, atomValue, true, true, true);\n      break;\n    case 'counts-to-symbol-charge':\n      problem = new CountsToSymbolProblem(model, atomValue, false, false, true);\n      break;\n    case 'counts-to-symbol-mass':\n      problem = new CountsToSymbolProblem(model, atomValue, false, true, false);\n      break;\n    case 'counts-to-symbol-proton-count':\n      problem = new CountsToSymbolProblem(model, atomValue, true, false, false);\n      break;\n    case 'schematic-to-element':\n      problem = new SchematicToElementProblem(model, atomValue);\n      break;\n    case 'schematic-to-charge':\n      problem = new SchematicToChargeProblem(model, atomValue);\n      break;\n    case 'schematic-to-mass':\n      problem = new SchematicToMassNumberProblem(model, atomValue);\n      break;\n    case 'schematic-to-symbol-all':\n      problem = new SchematicToSymbolProblem(model, atomValue, true, true, true);\n      break;\n    case 'schematic-to-symbol-charge':\n      problem = new SchematicToSymbolProblem(model, atomValue, false, false, true);\n      break;\n    case 'schematic-to-symbol-mass-number':\n      problem = new SchematicToSymbolProblem(model, atomValue, false, true, false);\n      break;\n    case 'schematic-to-symbol-proton-count':\n      problem = new SchematicToSymbolProblem(model, atomValue, true, false, false);\n      break;\n    case 'symbol-to-counts':\n      problem = new SymbolToCountsProblem(model, atomValue);\n      break;\n    case 'symbol-to-schematic':\n      problem = new SymbolToSchematicProblem(model, atomValue);\n      break;\n    default:\n      throw new Error('Error: Request to create unknown problem type, type = ' + problemType);\n    }\n    return problem;\n  };\n  ProblemSetFactory._isSchematicProbType = function (problemType) {\n    return problemType === 'schematic-to-element' || problemType === 'schematic-to-charge' || problemType === 'schematic-to-mass' || problemType === 'schematic-to-symbol-all' || problemType === 'schematic-to-symbol-proton-count' || problemType === 'schematic-to-symbol-charge' || problemType === 'schematic-to-symbol-mass-number' || problemType === 'symbol-to-schematic';\n  };\n  ProblemSetFactory._isChargeProbType = function (problemType) {\n    return problemType === 'schematic-to-charge' || problemType === 'counts-to-charge' || problemType === 'counts-to-symbol-charge' || problemType === 'schematic-to-symbol-charge';\n  };\n  return ProblemSetFactory;\n});",
    "\ndefine('game/model/BAAGameModel',['require','AXON/Property','AXON/PropertySet','PHET_CORE/inherit','PHET_CORE/callSuper','game/model/CountsToChargeProblem','game/model/CountsToSymbolProblem','game/model/CountsToElementProblem','game/model/CountsToMassNumberProblem','game/model/ProblemSetFactory','game/model/SchematicToChargeProblem','game/model/SchematicToElementProblem','game/model/SchematicToMassNumberProblem','game/model/SchematicToSymbolProblem','common/SharedConstants','game/model/SymbolToCountsProblem','game/model/SymbolToSchematicProblem'],function (require) {\n  'use strict';\n  var Property = require('AXON/Property');\n  var PropertySet = require('AXON/PropertySet');\n  var inherit = require('PHET_CORE/inherit');\n  var callSuper = require('PHET_CORE/callSuper');\n  var CountsToChargeProblem = require('game/model/CountsToChargeProblem');\n  var CountsToSymbolProblem = require('game/model/CountsToSymbolProblem');\n  var CountsToElementProblem = require('game/model/CountsToElementProblem');\n  var CountsToMassNumberProblem = require('game/model/CountsToMassNumberProblem');\n  var ProblemSetFactory = require('game/model/ProblemSetFactory');\n  var SchematicToChargeProblem = require('game/model/SchematicToChargeProblem');\n  var SchematicToElementProblem = require('game/model/SchematicToElementProblem');\n  var SchematicToMassNumberProblem = require('game/model/SchematicToMassNumberProblem');\n  var SchematicToSymbolProblem = require('game/model/SchematicToSymbolProblem');\n  var SharedConstants = require('common/SharedConstants');\n  var SymbolToCountsProblem = require('game/model/SymbolToCountsProblem');\n  var SymbolToSchematicProblem = require('game/model/SymbolToSchematicProblem');\n  var PROBLEMS_PER_SUB_GAME = 5;\n  var POSSIBLE_POINTS_PER_PROBLEM = 2;\n  function BAAGameModel() {\n    PropertySet.call(this, {\n      state: 'selectSubGame',\n      soundEnabled: 'false',\n      timerEnabled: 'true',\n      level: 0,\n      problemSet: [],\n      problemIndex: 0,\n      score: 0,\n      elapsedTime: 0,\n      bestTimes: []\n    });\n    var thisGameModel = this;\n    this.scoreProperties = [\n      new Property(0),\n      new Property(0),\n      new Property(0),\n      new Property(0)\n    ];\n    _.each(SharedConstants.SUB_GAME_TYPES, function (subGameType) {\n      thisGameModel.bestTimes[subGameType] = Number.POSITIVE_INFINITY;\n    });\n  }\n  inherit(PropertySet, BAAGameModel, {\n    step: function (dt) {\n      this.elapsedTime += dt;\n      if (this.state && typeof this.state.step !== 'undefined') {\n        this.state.step(dt);\n      }\n    },\n    startSubGame: function (subGameType) {\n      console.log('startGame called, sub game subGameType = ' + subGameType);\n      this.level = SharedConstants.SUB_GAME_TO_LEVEL(subGameType);\n      this.problemIndex = 0;\n      this.problemSet = ProblemSetFactory.generate(this.level, PROBLEMS_PER_SUB_GAME, this);\n      this.elapsedTime = 0;\n      this.scoreProperties[this.level].reset();\n      if (this.problemSet.length > 0) {\n        this.state = this.problemSet[0];\n      } else {\n        this.state = 'subGameOver';\n      }\n    },\n    stopGame: function () {\n      console.log('stopGame called, not implemented.');\n    },\n    newGame: function (level) {\n      this.state = 'selectSubGame';\n    },\n    processGuess: function (numberAtom) {\n      console.log('processGuess called, not implemented.');\n    },\n    next: function () {\n      if (this.problemSet.length > this.problemIndex + 1) {\n        this.score += this.problemSet[this.problemIndex].score;\n        this.problemIndex++;\n        this.state = this.problemSet[this.problemIndex];\n      } else {\n        var totalPointsThisRound = 0;\n        this.problemSet.forEach(function (problem) {\n          totalPointsThisRound += problem.score;\n        });\n        this.scoreProperties[this.level].value = totalPointsThisRound;\n        this.state = 'subGameOver';\n      }\n    },\n    reset: function () {\n      callSuper(PropertySet, 'reset', this);\n      this.scoreProperties.forEach(function (progressProperty) {\n        progressProperty.reset();\n      });\n    },\n    MAX_POINTS_PER_GAME_LEVEL: PROBLEMS_PER_SUB_GAME * POSSIBLE_POINTS_PER_PROBLEM\n  });\n  return BAAGameModel;\n});",
    "\ndefine('game/view/GameScoreboardNode',['require','SCENERY/util/Color','SCENERY_PHET/PhetFont','SCENERY/nodes/Image','imageLoader','SCENERY/nodes/Node','SCENERY/nodes/Text','PHET_CORE/inherit','SCENERY/nodes/Rectangle','SUN/TextButton','common/Utils'],function (require) {\n  'use strict';\n  var Color = require('SCENERY/util/Color');\n  var PhetFont = require('SCENERY_PHET/PhetFont');\n  var Image = require('SCENERY/nodes/Image');\n  var imageLoader = require('imageLoader');\n  var Node = require('SCENERY/nodes/Node');\n  var Text = require('SCENERY/nodes/Text');\n  var inherit = require('PHET_CORE/inherit');\n  var Rectangle = require('SCENERY/nodes/Rectangle');\n  var TextButton = require('SUN/TextButton');\n  var Utils = require('common/Utils');\n  var FONT = new PhetFont(20);\n  var X_MARGIN = 20;\n  var Y_MARGIN = 5;\n  function GameScoreboardNode(gameModel, options) {\n    Node.call(this);\n    var thisNode = this;\n    options = _.extend({\n      backgroundFillColor: 'rgb( 180, 205, 255 )',\n      backgroundStroke: 'black',\n      backgroundLineWidth: 1,\n      width: 700\n    }, options);\n    var levelNode = new Text('', { font: FONT });\n    thisNode.addChild(levelNode);\n    gameModel.levelProperty.link(function (level) {\n      levelNode.text = 'Level: ' + level;\n    });\n    var scoreNode = new Text('', { font: FONT });\n    thisNode.addChild(scoreNode);\n    gameModel.scoreProperty.link(function (score) {\n      scoreNode.text = 'Score: ' + score;\n    });\n    var timerIcon = new Image(imageLoader.getImage('blue-stopwatch.png'));\n    thisNode.addChild(timerIcon);\n    var timerValue = new Text('0', { font: FONT });\n    thisNode.addChild(timerValue);\n    gameModel.elapsedTimeProperty.link(function (elapsedTime) {\n      timerValue.text = Utils.formatTime(elapsedTime);\n      if (gameModel.bestTimes[gameModel.level]) {\n        timerValue.text += ' (Your best: ' + Utils.formatTime(gameModel.bestTimes[gameModel.level]) + ')';\n      }\n    });\n    gameModel.timerEnabledProperty.link(function (timerEnabled) {\n      timerIcon.visible = timerEnabled;\n      timerValue.visible = timerEnabled;\n    });\n    var newGameButton = new TextButton('New Game', function () {\n        gameModel.newGame();\n      }, {\n        font: new PhetFont(20),\n        rectangleFillUp: new Color(235, 235, 235)\n      });\n    thisNode.addChild(newGameButton);\n    var maxChildHeight = 0;\n    thisNode.children.forEach(function (childNode) {\n      maxChildHeight = childNode.height > maxChildHeight ? childNode.height : maxChildHeight;\n    });\n    var backgroundHeight = maxChildHeight + 2 * Y_MARGIN;\n    levelNode.left = X_MARGIN;\n    levelNode.centerY = backgroundHeight / 2;\n    scoreNode.centerX = options.width * 0.28;\n    scoreNode.centerY = backgroundHeight / 2;\n    timerIcon.right = options.width / 2;\n    timerIcon.centerY = backgroundHeight / 2;\n    timerValue.left = timerIcon.right + 5;\n    timerValue.centerY = backgroundHeight / 2;\n    newGameButton.right = options.width - X_MARGIN;\n    newGameButton.centerY = backgroundHeight / 2;\n    var background = new Rectangle(0, 0, options.width, backgroundHeight, 0, 0, {\n        fill: options.backgroundFillColor,\n        stroke: options.backgroundStroke,\n        lineWidth: options.backgroundLineWidth\n      });\n    thisNode.addChild(background);\n    background.moveToBack();\n  }\n  inherit(Node, GameScoreboardNode);\n  return GameScoreboardNode;\n});",
    "\ndefine('game/view/HalfStar',['require','PHET_CORE/inherit','SCENERY/nodes/Path','KITE/Shape','DOT/Vector2'],function (require) {\n  'use strict';\n  var inherit = require('PHET_CORE/inherit');\n  var Path = require('SCENERY/nodes/Path');\n  var Shape = require('KITE/Shape');\n  var Vector2 = require('DOT/Vector2');\n  var Star = function Star(diameter, options) {\n    var starShape = new Shape();\n    var angle = -Math.PI / 2;\n    for (var i = 0; i < 6; i++) {\n      var vector = Vector2.createPolar(i % 2 === 0 ? diameter / 2 : diameter / 4, angle);\n      starShape.lineTo(vector.x, vector.y);\n      angle -= 2 * Math.PI / 10;\n    }\n    starShape.close();\n    Path.call(this, starShape, options);\n  };\n  inherit(Path, Star);\n  return Star;\n});",
    "\ndefine('game/view/Star',['require','PHET_CORE/inherit','SCENERY/nodes/Path','KITE/Shape','DOT/Vector2'],function (require) {\n  'use strict';\n  var inherit = require('PHET_CORE/inherit');\n  var Path = require('SCENERY/nodes/Path');\n  var Shape = require('KITE/Shape');\n  var Vector2 = require('DOT/Vector2');\n  var Star = function Star(diameter, options) {\n    var starShape = new Shape();\n    var angle = -Math.PI / 2;\n    for (var i = 0; i < 10; i++) {\n      var vector = Vector2.createPolar(i % 2 === 0 ? diameter / 2 : diameter / 4, angle);\n      starShape.lineTo(vector.x, vector.y);\n      angle += 2 * Math.PI / 10;\n    }\n    starShape.close();\n    Path.call(this, starShape, options);\n  };\n  inherit(Path, Star);\n  return Star;\n});",
    "\ndefine('game/view/GameProgressIndicator',['require','SCENERY/util/Color','game/view/HalfStar','PHET_CORE/inherit','SCENERY/nodes/Node','SCENERY/nodes/Rectangle','game/view/Star'],function (require) {\n  'use strict';\n  var Color = require('SCENERY/util/Color');\n  var HalfStar = require('game/view/HalfStar');\n  var inherit = require('PHET_CORE/inherit');\n  var Node = require('SCENERY/nodes/Node');\n  var Rectangle = require('SCENERY/nodes/Rectangle');\n  var Star = require('game/view/Star');\n  var BACKGROUND_COLOR = 'white';\n  var FILLED_STAR_COLOR = 'yellow';\n  var FILLED_STAR_STROKE = 'black';\n  var UNFILLED_STAR_COLOR = 'rgb( 220, 220, 220 )';\n  var UNFILLED_STAR_STROKE = 'rgb( 190, 190, 190 )';\n  function GameProgressIndicator(width, height, rounding, numStars, scoreProperty, maxPossibleScore) {\n    Node.call(this);\n    var boundingRectangle = new Rectangle(0, 0, width, height, rounding, rounding, {\n        fill: BACKGROUND_COLOR,\n        stroke: 'black',\n        lineWidth: 1\n      });\n    this.addChild(boundingRectangle);\n    var starDiameter = height * 0.8;\n    var distanceBetweenStars = (width - starDiameter * numStars) / (numStars + 1);\n    var starLeft = distanceBetweenStars;\n    var unfilledStars = [];\n    var filledStars = [];\n    var filledHalfStars = [];\n    for (var i = 0; i < numStars; i++) {\n      unfilledStars.push(new Star(starDiameter, {\n        fill: UNFILLED_STAR_COLOR,\n        stroke: UNFILLED_STAR_STROKE,\n        lineWidth: 1,\n        left: starLeft,\n        centerY: height / 2\n      }));\n      boundingRectangle.addChild(unfilledStars[i]);\n      filledStars.push(new Star(starDiameter, {\n        fill: FILLED_STAR_COLOR,\n        stroke: FILLED_STAR_STROKE,\n        lineWidth: 1,\n        left: starLeft,\n        centerY: height / 2\n      }));\n      boundingRectangle.addChild(filledStars[i]);\n      filledHalfStars.push(new HalfStar(starDiameter, {\n        fill: FILLED_STAR_COLOR,\n        stroke: FILLED_STAR_STROKE,\n        lineWidth: 1,\n        left: starLeft,\n        centerY: height / 2\n      }));\n      boundingRectangle.addChild(filledHalfStars[i]);\n      starLeft += distanceBetweenStars + starDiameter;\n    }\n    scoreProperty.link(function (score) {\n      var proportion = score / maxPossibleScore;\n      var numFilledStars = Math.floor(proportion * numStars);\n      for (var i = 0; i < numStars; i++) {\n        filledStars[i].visible = i < numFilledStars;\n      }\n      filledHalfStars.forEach(function (halfStar) {\n        halfStar.visible = false;\n      });\n      if (proportion * numStars - numFilledStars > 0.49) {\n        filledHalfStars[numFilledStars].visible = true;\n      }\n    });\n  }\n  inherit(Node, GameProgressIndicator);\n  return GameProgressIndicator;\n});",
    "\ndefine('game/view/GameStartButton',['require','PHET_CORE/inherit','game/view/GameProgressIndicator','SCENERY/util/LinearGradient','SCENERY/nodes/Node','SCENERY_PHET/PhetFont','SCENERY/nodes/Rectangle','SCENERY/nodes/Text'],function (require) {\n  'use strict';\n  var inherit = require('PHET_CORE/inherit');\n  var GameProgressIndicator = require('game/view/GameProgressIndicator');\n  var LinearGradient = require('SCENERY/util/LinearGradient');\n  var Node = require('SCENERY/nodes/Node');\n  var PhetFont = require('SCENERY_PHET/PhetFont');\n  var Rectangle = require('SCENERY/nodes/Rectangle');\n  var Text = require('SCENERY/nodes/Text');\n  var WIDTH = 150;\n  var HEIGHT = 150;\n  var BACKGROUND_COLOR = 'rgb( 242, 255, 204 )';\n  var HIGHLIGHTED_BACKGROUND_COLOR = 'rgb( 250, 255, 230 )';\n  var DROP_SHADOW_OFFSET = WIDTH * 0.02;\n  var CORNER_ROUNDING = 10;\n  var GameStartButton = function GameStartButton(icon, onFireFunction, scoreProperty, maxPossibleScore) {\n    Node.call(this);\n    var thisNode = this;\n    this.addChild(new Rectangle(0, 0, WIDTH, HEIGHT, CORNER_ROUNDING, CORNER_ROUNDING, {\n      stroke: 'black',\n      lineWidth: 1,\n      fill: 'black',\n      top: DROP_SHADOW_OFFSET,\n      left: DROP_SHADOW_OFFSET\n    }));\n    var buttonOutline = new Rectangle(0, 0, WIDTH, HEIGHT, CORNER_ROUNDING, CORNER_ROUNDING, {\n        stroke: 'black',\n        lineWidth: 1,\n        fill: BACKGROUND_COLOR,\n        cursor: 'pointer'\n      });\n    thisNode.addChild(buttonOutline);\n    var iconScaleFactor = Math.min(HEIGHT * 0.65 / icon.height, WIDTH * 0.85 / icon.width);\n    icon.scale(iconScaleFactor);\n    icon.centerX = WIDTH / 2;\n    icon.centerY = HEIGHT * 0.4;\n    buttonOutline.addChild(icon);\n    buttonOutline.addChild(new GameProgressIndicator(WIDTH, HEIGHT * 0.2, CORNER_ROUNDING, 5, scoreProperty, maxPossibleScore).mutate({ bottom: HEIGHT }));\n    thisNode._armed = false;\n    buttonOutline.addInputListener({\n      down: function () {\n        buttonOutline.fill = HIGHLIGHTED_BACKGROUND_COLOR;\n        buttonOutline.top = DROP_SHADOW_OFFSET;\n        buttonOutline.left = DROP_SHADOW_OFFSET;\n        thisNode._armed = true;\n      },\n      over: function () {\n        buttonOutline.fill = HIGHLIGHTED_BACKGROUND_COLOR;\n      },\n      out: function () {\n        buttonOutline.fill = BACKGROUND_COLOR;\n      },\n      up: function () {\n        buttonOutline.fill = BACKGROUND_COLOR;\n        buttonOutline.top = 0;\n        buttonOutline.left = 0;\n        if (thisNode._armed) {\n          onFireFunction();\n        }\n      }\n    });\n  };\n  inherit(Node, GameStartButton);\n  return GameStartButton;\n});",
    "\ndefine('SUN/ToggleNode',['require','SCENERY/nodes/Node','SCENERY/nodes/Path','KITE/Shape','PHET_CORE/inherit'],function (require) {\n  'use strict';\n  var Node = require('SCENERY/nodes/Node');\n  var Path = require('SCENERY/nodes/Path');\n  var Shape = require('KITE/Shape');\n  var inherit = require('PHET_CORE/inherit');\n  function ToggleNode(trueNode, falseNode, booleanProperty) {\n    var thisNode = this;\n    Node.call(thisNode);\n    var background = new Path(Shape.bounds(trueNode.bounds.union(falseNode.bounds)));\n    booleanProperty.link(function (value) {\n      thisNode.children = [\n        background,\n        value ? trueNode : falseNode\n      ];\n    });\n  }\n  inherit(Node, ToggleNode);\n  return ToggleNode;\n});",
    "\ndefine('SUN/ToggleButton',['require','SCENERY/nodes/Node','SCENERY/nodes/DOM','PHET_CORE/inherit','SCENERY/nodes/Rectangle','SUN/ToggleNode'],function (require) {\n  'use strict';\n  var Node = require('SCENERY/nodes/Node');\n  var DOM = require('SCENERY/nodes/DOM');\n  var inherit = require('PHET_CORE/inherit');\n  var Rectangle = require('SCENERY/nodes/Rectangle');\n  var ToggleNode = require('SUN/ToggleNode');\n  function ToggleButton(trueNode, falseNode, booleanProperty, options) {\n    var toggleButton = this;\n    options = _.extend({\n      addRectangle: false,\n      padX: 10,\n      padY: 10,\n      cursor: 'pointer',\n      label: '',\n      radioButton: false\n    }, options);\n    Node.call(this, options);\n    var content = new ToggleNode(trueNode, falseNode, booleanProperty);\n    if (options.addRectangle) {\n      this.path = new Rectangle(0, 0, content.width + options.padX, content.height + options.padY, 10, 10, {\n        stroke: 'black',\n        lineWidth: 1,\n        fill: '#e3e980'\n      });\n      this.addChild(this.path);\n      content.centerX = this.path.width / 2;\n      content.centerY = this.path.height / 2;\n    }\n    this.addChild(content);\n    if (options.radioButton) {\n      this.addInputListener({\n        up: function () {\n          booleanProperty.value = true;\n        }\n      });\n    } else {\n      this.addInputListener({\n        up: function () {\n          booleanProperty.value = !booleanProperty.value;\n        }\n      });\n    }\n    this.addPeer('<input type=\"checkbox\" aria-label=\"' + _.escape(options.label) + '\">', {\n      click: function () {\n        booleanProperty.value = !booleanProperty.value;\n      },\n      label: options.label\n    });\n    booleanProperty.link(function (value) {\n      _.each(toggleButton.instances, function (instance) {\n        _.each(instance.peers, function (peer) {\n          peer.element.setAttribute('checked', value);\n        });\n      });\n    });\n  }\n  inherit(Node, ToggleButton);\n  return ToggleButton;\n});",
    "\ndefine('SCENERY_PHET/SoundToggleButton',['require','SUN/FontAwesomeNode','PHET_CORE/inherit','SUN/ToggleButton','SUN/ToggleNode'],function (require) {\n  'use strict';\n  var FontAwesomeNode = require('SUN/FontAwesomeNode');\n  var inherit = require('PHET_CORE/inherit');\n  var ToggleButton = require('SUN/ToggleButton');\n  var ToggleNode = require('SUN/ToggleNode');\n  function SoundToggleButton(property, options) {\n    ToggleButton.call(this, new FontAwesomeNode('volume_up'), new FontAwesomeNode('volume_off'), property, _.extend({\n      addRectangle: true,\n      label: 'Sound'\n    }, options));\n  }\n  inherit(ToggleButton, SoundToggleButton);\n  return SoundToggleButton;\n});",
    "\ndefine('game/view/TimerToggleButton',['require','SUN/FontAwesomeNode','SCENERY/nodes/Image','imageLoader','PHET_CORE/inherit','SCENERY/nodes/Node','SCENERY/nodes/Path','AXON/Property','KITE/Shape','SCENERY_PHET/SoundToggleButton','SUN/ToggleButton'],function (require) {\n  'use strict';\n  var FontAwesomeNode = require('SUN/FontAwesomeNode');\n  var Image = require('SCENERY/nodes/Image');\n  var imageLoader = require('imageLoader');\n  var inherit = require('PHET_CORE/inherit');\n  var Node = require('SCENERY/nodes/Node');\n  var Path = require('SCENERY/nodes/Path');\n  var Property = require('AXON/Property');\n  var Shape = require('KITE/Shape');\n  var SoundToggleButton = require('SCENERY_PHET/SoundToggleButton');\n  var ToggleButton = require('SUN/ToggleButton');\n  var X_STROKE_WIDTH = 4;\n  function TimerToggleButton(property, options) {\n    var tempSoundToggleButton = new FontAwesomeNode('volume_up');\n    var timerOnNode = new Image(imageLoader.getImage('blue-stopwatch.png'));\n    var timerNodeScale = Math.min(tempSoundToggleButton.width / timerOnNode.width, tempSoundToggleButton.height / timerOnNode.height);\n    timerOnNode.scale(timerNodeScale);\n    var timerOffNode = new Node();\n    timerOffNode.addChild(timerOnNode);\n    var xNode = new Shape();\n    xNode.moveTo(0, 0);\n    xNode.lineTo(tempSoundToggleButton.width - X_STROKE_WIDTH / 2, tempSoundToggleButton.height);\n    xNode.moveTo(0, tempSoundToggleButton.height);\n    xNode.lineTo(tempSoundToggleButton.width - X_STROKE_WIDTH / 2, 0);\n    timerOffNode.addChild(new Path(xNode, {\n      stroke: 'black',\n      lineWidth: X_STROKE_WIDTH,\n      centerX: timerOffNode.width / 2,\n      centerY: timerOffNode.height / 2\n    }));\n    ToggleButton.call(this, timerOnNode, timerOffNode, property, _.extend({\n      addRectangle: true,\n      label: 'Timer'\n    }, options));\n  }\n  inherit(ToggleButton, TimerToggleButton);\n  return TimerToggleButton;\n});",
    "\ndefine('game/view/StartSubGameNode',['require','SUN/CheckBox','game/view/GameStartButton','SCENERY/nodes/Image','imageLoader','PHET_CORE/inherit','SCENERY/util/LinearGradient','SCENERY/nodes/Node','SCENERY_PHET/PhetFont','SCENERY/nodes/Rectangle','common/view/ResetAllButton','common/SharedConstants','SCENERY_PHET/SoundToggleButton','SCENERY/nodes/Text','game/view/TimerToggleButton'],function (require) {\n  'use strict';\n  var CheckBox = require('SUN/CheckBox');\n  var GameStartButton = require('game/view/GameStartButton');\n  var Image = require('SCENERY/nodes/Image');\n  var imageLoader = require('imageLoader');\n  var inherit = require('PHET_CORE/inherit');\n  var LinearGradient = require('SCENERY/util/LinearGradient');\n  var Node = require('SCENERY/nodes/Node');\n  var PhetFont = require('SCENERY_PHET/PhetFont');\n  var Rectangle = require('SCENERY/nodes/Rectangle');\n  var ResetAllButton = require('common/view/ResetAllButton');\n  var SharedConstants = require('common/SharedConstants');\n  var SoundToggleButton = require('SCENERY_PHET/SoundToggleButton');\n  var Text = require('SCENERY/nodes/Text');\n  var TimerToggleButton = require('game/view/TimerToggleButton');\n  var CONTROL_INSET = 20;\n  var StartSubGameNode = function (gameModel, layoutBounds) {\n    Node.call(this);\n    var title = new Text('Choose Your Challenge', { font: new PhetFont(30) });\n    this.addChild(title);\n    var periodicTableGameButton = new GameStartButton(new Image(imageLoader.getImage('periodic_table_icon.png')), function () {\n        gameModel.startSubGame('periodic-table-game');\n      }, gameModel.scoreProperties[SharedConstants.SUB_GAME_TO_LEVEL('periodic-table-game')], gameModel.MAX_POINTS_PER_GAME_LEVEL);\n    this.addChild(periodicTableGameButton);\n    var massAndChangeGameButton = new GameStartButton(new Image(imageLoader.getImage('mass_charge_icon.png')), function () {\n        gameModel.startSubGame('mass-and-charge-game');\n      }, gameModel.scoreProperties[SharedConstants.SUB_GAME_TO_LEVEL('mass-and-charge-game')], gameModel.MAX_POINTS_PER_GAME_LEVEL);\n    this.addChild(massAndChangeGameButton);\n    var symbolGameButton = new GameStartButton(new Image(imageLoader.getImage('symbol_question_icon.png')), function () {\n        gameModel.startSubGame('symbol-game');\n      }, gameModel.scoreProperties[SharedConstants.SUB_GAME_TO_LEVEL('symbol-game')], gameModel.MAX_POINTS_PER_GAME_LEVEL);\n    this.addChild(symbolGameButton);\n    var advancedSymbolGameButton = new GameStartButton(new Image(imageLoader.getImage('question_mark_icon.png')), function () {\n        gameModel.startSubGame('advanced-symbol-game');\n      }, gameModel.scoreProperties[SharedConstants.SUB_GAME_TO_LEVEL('advanced-symbol-game')], gameModel.MAX_POINTS_PER_GAME_LEVEL);\n    this.addChild(advancedSymbolGameButton);\n    var timerToggleButton = new TimerToggleButton(gameModel.timerEnabledProperty);\n    this.addChild(timerToggleButton);\n    var soundToggleButton = new SoundToggleButton(gameModel.soundEnabledProperty);\n    this.addChild(soundToggleButton);\n    var resetButton = new ResetAllButton(function () {\n        gameModel.reset();\n      });\n    resetButton.scale(0.8);\n    this.addChild(resetButton);\n    title.centerX = layoutBounds.width / 2;\n    title.top = 20;\n    var buttonWidth = periodicTableGameButton.width;\n    var interButtonXSpace = buttonWidth * 0.2;\n    var buttonCenterY = layoutBounds.height * 0.4;\n    periodicTableGameButton.right = layoutBounds.centerX - 1.5 * interButtonXSpace - buttonWidth;\n    periodicTableGameButton.centerY = buttonCenterY;\n    massAndChangeGameButton.left = periodicTableGameButton.right + interButtonXSpace;\n    massAndChangeGameButton.centerY = buttonCenterY;\n    symbolGameButton.left = massAndChangeGameButton.right + interButtonXSpace;\n    symbolGameButton.centerY = buttonCenterY;\n    advancedSymbolGameButton.left = symbolGameButton.right + interButtonXSpace;\n    advancedSymbolGameButton.centerY = buttonCenterY;\n    resetButton.right = layoutBounds.width - CONTROL_INSET;\n    resetButton.bottom = layoutBounds.height - CONTROL_INSET;\n    soundToggleButton.left = CONTROL_INSET;\n    soundToggleButton.bottom = layoutBounds.height - CONTROL_INSET;\n    timerToggleButton.left = CONTROL_INSET;\n    timerToggleButton.bottom = soundToggleButton.top - 10;\n  };\n  inherit(Node, StartSubGameNode);\n  return StartSubGameNode;\n});",
    "\ndefine('SCENERY/nodes/Line',['require','PHET_CORE/inherit','SCENERY/scenery','SCENERY/nodes/Path','KITE/Shape','DOT/Vector2'],function (require) {\n  'use strict';\n  var inherit = require('PHET_CORE/inherit');\n  var scenery = require('SCENERY/scenery');\n  var Path = require('SCENERY/nodes/Path');\n  var Shape = require('KITE/Shape');\n  var Vector2 = require('DOT/Vector2');\n  scenery.Line = function Line(x1, y1, x2, y2, options) {\n    if (typeof x1 === 'object') {\n      if (x1 instanceof Vector2) {\n        this._x1 = x1.x;\n        this._y1 = x1.y;\n        this._x2 = y1.x;\n        this._y2 = y1.y;\n        options = x2 || {};\n      } else {\n        this._x1 = 0;\n        this._y1 = 0;\n        this._x2 = 0;\n        this._y2 = 0;\n        options = x1 || {};\n      }\n    } else {\n      this._x1 = x1;\n      this._y1 = y1;\n      this._x2 = x2;\n      this._y2 = y2;\n      options = options || {};\n    }\n    Path.call(this, this.createLineShape(), options);\n  };\n  var Line = scenery.Line;\n  inherit(Path, Line, {\n    setLine: function (x1, y1, x2, y2) {\n      sceneryAssert && sceneryAssert(x1 !== undefined && y1 !== undefined && x2 !== undefined && y2 !== undefined, 'parameters need to be defined');\n      this._x1 = x1;\n      this._y1 = y1;\n      this._x2 = x2;\n      this._y2 = y2;\n      this.invalidateLine();\n    },\n    setPoint1: function (x1, y1) {\n      if (typeof x1 === 'number') {\n        this.setLine(x1, y1, this._x2, this._y2);\n      } else {\n        this.setLine(x1.x, x1.y, this._x2, this._y2);\n      }\n    },\n    set p1(point) {\n      this.setPoint1(point);\n    },\n    get p1() {\n      return new Vector2(this._x1, this._y1);\n    },\n    setPoint2: function (x2, y2) {\n      if (typeof x2 === 'number') {\n        this.setLine(this._x1, this._y1, x2, y2);\n      } else {\n        this.setLine(this._x1, this._y1, x2.x, x2.y);\n      }\n    },\n    set p2(point) {\n      this.setPoint2(point);\n    },\n    get p2() {\n      return new Vector2(this._x2, this._y2);\n    },\n    createLineShape: function () {\n      sceneryAssert && sceneryAssert(isFinite(this._x1), 'A rectangle needs to have a finite x1 (' + this._x1 + ')');\n      sceneryAssert && sceneryAssert(isFinite(this._y1), 'A rectangle needs to have a finite y1 (' + this._y1 + ')');\n      sceneryAssert && sceneryAssert(isFinite(this._x2), 'A rectangle needs to have a finite x2 (' + this._x2 + ')');\n      sceneryAssert && sceneryAssert(isFinite(this._y2), 'A rectangle needs to have a finite y2 (' + this._y2 + ')');\n      return Shape.lineSegment(this._x1, this._y1, this._x2, this._y2);\n    },\n    invalidateLine: function () {\n      this.setShape(this.createLineShape());\n    },\n    containsPointSelf: function (point) {\n      return false;\n    },\n    createSVGFragment: function (svg, defs, group) {\n      return document.createElementNS('http://www.w3.org/2000/svg', 'line');\n    },\n    updateSVGFragment: function (rect) {\n      rect.setAttribute('x1', this._x1);\n      rect.setAttribute('y1', this._y1);\n      rect.setAttribute('x2', this._x2);\n      rect.setAttribute('y2', this._y2);\n      rect.setAttribute('style', this.getSVGFillStyle() + this.getSVGStrokeStyle());\n    },\n    getBasicConstructor: function (propLines) {\n      return 'new scenery.Line( ' + this._x1 + ', ' + this._y1 + ', ' + this._x1 + ', ' + this._y1 + ', {' + propLines + '} )';\n    }\n  });\n  function addLineProp(capitalizedShort) {\n    var lowerShort = capitalizedShort.toLowerCase();\n    var getName = 'get' + capitalizedShort;\n    var setName = 'set' + capitalizedShort;\n    var privateName = '_' + lowerShort;\n    Line.prototype[getName] = function () {\n      return this[privateName];\n    };\n    Line.prototype[setName] = function (value) {\n      this[privateName] = value;\n      this.invalidateLine();\n      return this;\n    };\n    Object.defineProperty(Line.prototype, lowerShort, {\n      set: Line.prototype[setName],\n      get: Line.prototype[getName]\n    });\n  }\n  addLineProp('X1');\n  addLineProp('Y1');\n  addLineProp('X2');\n  addLineProp('Y2');\n  Line.prototype._mutatorKeys = [\n    'p1',\n    'p2',\n    'x1',\n    'y1',\n    'x2',\n    'y2'\n  ].concat(Path.prototype._mutatorKeys);\n  return Line;\n});",
    "\ndefine('game/view/LevelCompletedNode',['require','SCENERY/util/Color','DOT/Dimension2','game/view/GameStartButton','PHET_CORE/inherit','SCENERY/nodes/Line','SCENERY/nodes/Node','SCENERY_PHET/PhetFont','SCENERY/nodes/Rectangle','SUN/TextButton','SCENERY/nodes/Text','common/Utils'],function (require) {\n  'use strict';\n  var Color = require('SCENERY/util/Color');\n  var Dimension2 = require('DOT/Dimension2');\n  var GameStartButton = require('game/view/GameStartButton');\n  var inherit = require('PHET_CORE/inherit');\n  var Line = require('SCENERY/nodes/Line');\n  var Node = require('SCENERY/nodes/Node');\n  var PhetFont = require('SCENERY_PHET/PhetFont');\n  var Rectangle = require('SCENERY/nodes/Rectangle');\n  var TextButton = require('SUN/TextButton');\n  var Text = require('SCENERY/nodes/Text');\n  var Utils = require('common/Utils');\n  var BACKGROUND_COLOR = new Color(180, 205, 255);\n  var DIVIDER_LINE_OPTIONS = {\n      stroke: 'black',\n      lineWidth: 2\n    };\n  var INFO_TEXT_FONT = new PhetFont(20);\n  var LevelCompletedNode = function (gameModel, layoutBounds) {\n    Node.call(this);\n    var size = new Dimension2(layoutBounds.width * 0.33, layoutBounds.height * 0.6);\n    var rounding = size.width * 0.1;\n    var background = new Rectangle(0, 0, size.width, size.height, rounding, rounding, {\n        fill: BACKGROUND_COLOR,\n        stroke: 'black',\n        lineWidth: 2\n      });\n    this.addChild(background);\n    var title = new Text('Level Completed', {\n        font: new PhetFont({\n          size: 28,\n          weight: 'bold'\n        })\n      });\n    title.scale(Math.min(1, size.width * 0.9 / title.width));\n    background.addChild(title);\n    var dividerLineWidth = size.width * 0.8;\n    var upperDividerLine = new Line(0, 0, dividerLineWidth, 0, DIVIDER_LINE_OPTIONS);\n    background.addChild(upperDividerLine);\n    var lowerDividerLine = new Line(0, 0, dividerLineWidth, 0, DIVIDER_LINE_OPTIONS);\n    background.addChild(lowerDividerLine);\n    var level = new Text('Level: ' + (gameModel.level + 1), { font: INFO_TEXT_FONT });\n    background.addChild(level);\n    var scoreText = gameModel.scoreProperties[gameModel.level].value + ' of ' + gameModel.MAX_POINTS_PER_GAME_LEVEL;\n    if (gameModel.scoreProperties[gameModel.level].value === gameModel.MAX_POINTS_PER_GAME_LEVEL) {\n      scoreText += '(Perfect!)';\n    }\n    var score = new Text('Score: ' + gameModel.scoreProperties[gameModel.level].value + ' of ' + gameModel.MAX_POINTS_PER_GAME_LEVEL, { font: INFO_TEXT_FONT });\n    background.addChild(score);\n    var time = new Text('Time: ' + Utils.formatTime(gameModel.elapsedTime), { font: INFO_TEXT_FONT });\n    background.addChild(time);\n    var doneButton = new TextButton('OK', function () {\n        gameModel.state = 'selectSubGame';\n      }, {\n        font: new PhetFont(24),\n        rectangleFillUp: new Color(243, 243, 243)\n      });\n    background.addChild(doneButton);\n    var inset = size.width * 0.05;\n    title.centerX = background.width / 2;\n    title.top = inset;\n    upperDividerLine.centerX = size.width / 2;\n    upperDividerLine.top = title.bottom + inset;\n    doneButton.centerX = size.width / 2;\n    doneButton.bottom = size.height - inset;\n    lowerDividerLine.centerX = size.width / 2;\n    lowerDividerLine.bottom = doneButton.top - inset;\n    level.left = upperDividerLine.left;\n    score.left = upperDividerLine.left;\n    time.left = upperDividerLine.left;\n    if (gameModel.timerEnabled) {\n      level.centerY = size.height * 0.33;\n      score.centerY = size.height * 0.5;\n      time.centerY = size.height * 0.67;\n    } else {\n      time.visible = false;\n      level.centerY = size.height * 0.4;\n      score.centerY = size.height * 0.6;\n    }\n  };\n  inherit(Node, LevelCompletedNode);\n  return LevelCompletedNode;\n});",
    "\ndefine('game/view/BAAGameView',['require','SCENERY_PHET/PhetFont','PHET_CORE/inherit','SCENERY/nodes/Node','JOIST/ScreenView','SCENERY/nodes/Text','game/view/GameScoreboardNode','game/view/StartSubGameNode','game/view/LevelCompletedNode'],function (require) {\n  'use strict';\n  var PhetFont = require('SCENERY_PHET/PhetFont');\n  var inherit = require('PHET_CORE/inherit');\n  var Node = require('SCENERY/nodes/Node');\n  var ScreenView = require('JOIST/ScreenView');\n  var Text = require('SCENERY/nodes/Text');\n  var GameScoreboardNode = require('game/view/GameScoreboardNode');\n  var StartSubGameNode = require('game/view/StartSubGameNode');\n  var LevelCompletedNode = require('game/view/LevelCompletedNode');\n  function BAAGameView(gameModel) {\n    ScreenView.call(this);\n    var thisScene = this;\n    var startSubGameNode = new StartSubGameNode(gameModel, this.layoutBounds);\n    var scoreboard = new GameScoreboardNode(gameModel).mutate({\n        centerX: this.layoutBounds.centerX,\n        bottom: this.layoutBounds.maxY - 10\n      });\n    gameModel.stateProperty.link(function (state) {\n      if (state === 'selectSubGame') {\n        thisScene.removeAllChildren();\n        thisScene.addChild(startSubGameNode);\n      } else if (state === 'subGameOver') {\n        thisScene.removeAllChildren();\n        thisScene.addChild(new LevelCompletedNode(gameModel, thisScene.layoutBounds).mutate({\n          centerX: thisScene.layoutBounds.width / 2,\n          centerY: thisScene.layoutBounds.height / 2\n        }));\n      } else if (typeof state.createView === 'function') {\n        thisScene.removeAllChildren();\n        thisScene.addChild(state.createView(thisScene.layoutBounds));\n        thisScene.addChild(new Text('Problem ' + (gameModel.problemIndex + 1) + ' of ' + gameModel.problemSet.length, {\n          font: new PhetFont(16),\n          top: 30,\n          left: 10\n        }));\n        thisScene.addChild(scoreboard);\n      }\n    });\n  }\n  inherit(ScreenView, BAAGameView);\n  return BAAGameView;\n});",
    "\ndefine('symbol/view/SymbolNode',['require','common/AtomIdentifier','SCENERY_PHET/PhetFont','common/view/ChargeMeter','SCENERY/nodes/Image','imageLoader','PHET_CORE/inherit','SCENERY/nodes/Node','SCENERY/nodes/Rectangle','SCENERY/nodes/Text','DOT/Vector2'],function (require) {\n  'use strict';\n  var AtomIdentifier = require('common/AtomIdentifier');\n  var PhetFont = require('SCENERY_PHET/PhetFont');\n  var ChargeMeter = require('common/view/ChargeMeter');\n  var Image = require('SCENERY/nodes/Image');\n  var imageLoader = require('imageLoader');\n  var inherit = require('PHET_CORE/inherit');\n  var Node = require('SCENERY/nodes/Node');\n  var Rectangle = require('SCENERY/nodes/Rectangle');\n  var Text = require('SCENERY/nodes/Text');\n  var Vector2 = require('DOT/Vector2');\n  var SYMBOL_BOX_WIDTH = 275;\n  var SYMBOL_BOX_HEIGHT = 300;\n  var NUMBER_FONT = new PhetFont(56);\n  var NUMBER_INSET = 20;\n  var SymbolNode = function SymbolNode(numberAtom) {\n    Node.call(this, { pickable: false });\n    var thisSymbolNode = this;\n    var boundingBox = new Rectangle(0, 0, SYMBOL_BOX_WIDTH, SYMBOL_BOX_HEIGHT, 0, 0, {\n        stroke: 'black',\n        lineWidth: 2,\n        fill: 'white'\n      });\n    this.addChild(boundingBox);\n    var symbolText = new Text('', {\n        font: new PhetFont(150),\n        fill: 'black',\n        center: new Vector2(SYMBOL_BOX_WIDTH / 2, SYMBOL_BOX_HEIGHT / 2)\n      });\n    numberAtom.protonCountProperty.link(function (protonCount) {\n      var symbol = AtomIdentifier.getSymbol(protonCount);\n      symbolText.text = protonCount > 0 ? symbol : '';\n      symbolText.center = new Vector2(SYMBOL_BOX_WIDTH / 2, SYMBOL_BOX_HEIGHT / 2);\n    });\n    boundingBox.addChild(symbolText);\n    var protonCountDisplay = new Text('0', {\n        font: NUMBER_FONT,\n        fill: 'red'\n      });\n    numberAtom.protonCountProperty.link(function (protonCount) {\n      protonCountDisplay.text = protonCount;\n      protonCountDisplay.left = NUMBER_INSET;\n      protonCountDisplay.bottom = SYMBOL_BOX_HEIGHT - NUMBER_INSET;\n    });\n    boundingBox.addChild(protonCountDisplay);\n    var massNumberDisplay = new Text('0', {\n        font: NUMBER_FONT,\n        fill: 'black'\n      });\n    boundingBox.addChild(massNumberDisplay);\n    numberAtom.massNumberProperty.link(function (massNumber) {\n      massNumberDisplay.text = massNumber;\n      massNumberDisplay.left = NUMBER_INSET;\n      massNumberDisplay.top = NUMBER_INSET;\n    });\n    var chargeDisplay = new Text('0', {\n        font: NUMBER_FONT,\n        fill: 'black'\n      });\n    boundingBox.addChild(chargeDisplay);\n    numberAtom.chargeProperty.link(function (charge) {\n      var sign = '';\n      var textColor;\n      if (charge > 0) {\n        sign = '+';\n        textColor = 'red';\n      } else if (charge < 0) {\n        textColor = 'blue';\n      } else {\n        textColor = 'black';\n      }\n      chargeDisplay.text = sign + charge;\n      chargeDisplay.right = SYMBOL_BOX_WIDTH - NUMBER_INSET;\n      chargeDisplay.top = NUMBER_INSET;\n    });\n    var scaleImage = new Image(imageLoader.getImage('scale.png'));\n    scaleImage.scale(0.32);\n    this.addChild(scaleImage);\n    var chargeMeter = new ChargeMeter(numberAtom, { showNumericalReadout: false });\n    chargeMeter.scale(1.5);\n    this.addChild(chargeMeter);\n    scaleImage.left = 0;\n    scaleImage.centerY = massNumberDisplay.centerY;\n    boundingBox.top = 0;\n    boundingBox.left = scaleImage.right + 10;\n    chargeMeter.left = boundingBox.right + 10;\n    chargeMeter.centerY = chargeDisplay.centerY;\n  };\n  inherit(Node, SymbolNode);\n  return SymbolNode;\n});",
    "\ndefine('symbol/view/SymbolView',['require','SUN/AccordionBox','common/view/AtomView','SCENERY_PHET/PhetFont','PHET_CORE/inherit','SCENERY/nodes/Node','common/SharedConstants','symbol/view/SymbolNode'],function (require) {\n  'use strict';\n  var AccordionBox = require('SUN/AccordionBox');\n  var AtomView = require('common/view/AtomView');\n  var PhetFont = require('SCENERY_PHET/PhetFont');\n  var inherit = require('PHET_CORE/inherit');\n  var Node = require('SCENERY/nodes/Node');\n  var SharedConstants = require('common/SharedConstants');\n  var SymbolNode = require('symbol/view/SymbolNode');\n  function SymbolView(model) {\n    AtomView.call(this, model);\n    var thisView = this;\n    var symbolNode = new SymbolNode(model.numberAtom);\n    symbolNode.scale(0.43);\n    var symbolBox = new AccordionBox(symbolNode, {\n        title: 'Symbol',\n        fill: SharedConstants.DISPLAY_PANEL_BACKGROUND_COLOR,\n        minWidth: this.periodicTableBox.width,\n        contentPosition: 'center',\n        titlePosition: 'left',\n        buttonPosition: 'right',\n        font: new PhetFont(20)\n      });\n    this.addChild(symbolBox);\n    this.resetFunctions.push(function () {\n      symbolBox.open.reset();\n    });\n    symbolBox.top = this.periodicTableBox.top + this.periodicTableBox.openHeight + 10;\n    symbolBox.left = this.periodicTableBox.left;\n  }\n  inherit(AtomView, SymbolView);\n  return SymbolView;\n});",
    "\ndefine('SCENERY_PHET/HomeButton',['require','SUN/FontAwesomeNode','PHET_CORE/inherit','SCENERY/nodes/Node','KITE/Shape'],function (require) {\n  'use strict';\n  var FontAwesomeNode = require('SUN/FontAwesomeNode');\n  var inherit = require('PHET_CORE/inherit');\n  var Node = require('SCENERY/nodes/Node');\n  var Shape = require('KITE/Shape');\n  function HomeButton(options) {\n    options = _.extend({ cursor: 'pointer' }, options);\n    Node.call(this, options);\n    var icon = new FontAwesomeNode('home', {\n        fill: '#fff',\n        scale: 0.75\n      });\n    this.mouseArea = this.touchArea = Shape.rectangle(icon.bounds.minX, icon.bounds.minY, icon.bounds.width, icon.bounds.height);\n    this.addChild(icon);\n  }\n  inherit(Node, HomeButton);\n  return HomeButton;\n});",
    "\ndefine('SCENERY/nodes/HTMLText',['require','PHET_CORE/inherit','SCENERY/scenery','SCENERY/nodes/Text'],function (require) {\n  'use strict';\n  var inherit = require('PHET_CORE/inherit');\n  var scenery = require('SCENERY/scenery');\n  var Text = require('SCENERY/nodes/Text');\n  scenery.HTMLText = function HTMLText(text, options) {\n    this._isHTML = true;\n    Text.call(this, text, options);\n  };\n  var HTMLText = scenery.HTMLText;\n  inherit(Text, HTMLText, {});\n  return HTMLText;\n});",
    "\ndefine('JOIST/AboutDialog',['require','SCENERY/nodes/Node','SCENERY/nodes/VBox','SCENERY/nodes/Rectangle','SCENERY/nodes/Text','PHET_CORE/inherit','SCENERY_PHET/MultiLineText','JOIST/ScreenView','SUN/Panel','SCENERY/nodes/HTMLText','SCENERY_PHET/PhetFont'],function (require) {\n  'use strict';\n  var Node = require('SCENERY/nodes/Node');\n  var VBox = require('SCENERY/nodes/VBox');\n  var Rectangle = require('SCENERY/nodes/Rectangle');\n  var Text = require('SCENERY/nodes/Text');\n  var inherit = require('PHET_CORE/inherit');\n  var MultiLineText = require('SCENERY_PHET/MultiLineText');\n  var ScreenView = require('JOIST/ScreenView');\n  var Panel = require('SUN/Panel');\n  var HTMLText = require('SCENERY/nodes/HTMLText');\n  var PhetFont = require('SCENERY_PHET/PhetFont');\n  var SOFTWARE_AGREEMENT_URL = 'http://phet.colorado.edu/about/software-agreement_v7.htm';\n  function AboutDialog(sim) {\n    var aboutDialog = this;\n    ScreenView.call(this, { renderer: 'svg' });\n    var softwareAgreementLink = new HTMLText('<a href=\"#\" onclick=\"return false;\">Software Agreement</a>', {\n        font: new PhetFont(14),\n        renderer: 'dom',\n        interactive: true\n      });\n    softwareAgreementLink.addInputListener({\n      up: function (evt) {\n        evt.handle();\n      },\n      upImmediate: function (evt) {\n        var aboutDialogWindow = window.open(SOFTWARE_AGREEMENT_URL, '_blank');\n        aboutDialogWindow.focus();\n      }\n    });\n    var debugLink = 'http://phet.colorado.edu/files/troubleshooting/' + '?sim=' + encodeURIComponent(sim.name) + '&version=' + encodeURIComponent(sim.version) + '&url=' + encodeURIComponent(window.location.href);\n    var debuggingInfoLink = new HTMLText('<a href=\"' + debugLink + '\" onclick=\"return false;\">Debugging Information (for bug reports)</a>', {\n        font: new PhetFont(12),\n        renderer: 'dom',\n        interactive: true\n      });\n    debuggingInfoLink.addInputListener({\n      up: function (evt) {\n        evt.handle();\n      },\n      upImmediate: function (evt) {\n        var debugWindow = window.open(debugLink, '_blank');\n        debugWindow.focus();\n      }\n    });\n    var content = new VBox({\n        align: 'left',\n        spacing: 5,\n        children: [\n          new Text('PhET Interactive Simulations', { font: new PhetFont(16) }),\n          new Text('Copyright \\xa9 2004-2013 University of Colorado Boulder', { font: new PhetFont(12) }),\n          new Text(' ', { font: new PhetFont(28) }),\n          new Text(sim.name, { font: new PhetFont(28) }),\n          new Text('version ' + sim.version, { font: new PhetFont(20) }),\n          new Text(' '),\n          new MultiLineText(sim.credits, {\n            align: 'left',\n            font: new PhetFont(12)\n          }),\n          new Text(' '),\n          new MultiLineText(sim.thanks, {\n            align: 'left',\n            font: new PhetFont(12)\n          }),\n          new Text(' '),\n          softwareAgreementLink,\n          new Text(' '),\n          debuggingInfoLink\n        ]\n      });\n    this.addChild(new Panel(content, {\n      centerX: this.layoutBounds.centerX,\n      centerY: this.layoutBounds.centerY,\n      xMargin: 20,\n      yMargin: 20\n    }));\n    function resize() {\n      aboutDialog.layout($(window).width(), $(window).height());\n    }\n    $(window).resize(resize);\n    resize();\n  }\n  inherit(ScreenView, AboutDialog);\n  return AboutDialog;\n});",
    "\ndefine('SCENERY/nodes/Plane',['require','PHET_CORE/inherit','SCENERY/scenery','SCENERY/nodes/Rectangle','KITE/Shape'],function (require) {\n  'use strict';\n  var inherit = require('PHET_CORE/inherit');\n  var scenery = require('SCENERY/scenery');\n  var Rectangle = require('SCENERY/nodes/Rectangle');\n  var Shape = require('KITE/Shape');\n  scenery.Plane = function Plane(options) {\n    Rectangle.call(this, -2000, -2000, 6000, 6000, options);\n  };\n  var Plane = scenery.Plane;\n  return inherit(Rectangle, Plane);\n});",
    "\ndefine('JOIST/PhetMenu',['require','SCENERY/nodes/Node','KITE/Shape','SCENERY/nodes/Path','SCENERY/nodes/Text','PHET_CORE/inherit','JOIST/AboutDialog','SCENERY/nodes/Rectangle','SCENERY/input/ButtonListener','SCENERY/nodes/Plane','AXON/log','SCENERY_PHET/PhetFont'],function (require) {\n  'use strict';\n  var Node = require('SCENERY/nodes/Node');\n  var Shape = require('KITE/Shape');\n  var Path = require('SCENERY/nodes/Path');\n  var Text = require('SCENERY/nodes/Text');\n  var inherit = require('PHET_CORE/inherit');\n  var AboutDialog = require('JOIST/AboutDialog');\n  var Rectangle = require('SCENERY/nodes/Rectangle');\n  var ButtonListener = require('SCENERY/input/ButtonListener');\n  var Plane = require('SCENERY/nodes/Plane');\n  var log = require('AXON/log');\n  var PhetFont = require('SCENERY_PHET/PhetFont');\n  var FONT_SIZE = 18;\n  var HIGHLIGHT_COLOR = '#a6d2f4';\n  var createMenuItem = function (text, width, height, callback, immediateCallback) {\n    var X_MARGIN = 5;\n    var Y_MARGIN = 3;\n    var CORNER_RADIUS = 5;\n    var textNode = new Text(text, { font: new PhetFont(FONT_SIZE) });\n    var highlight = new Rectangle(0, 0, width + X_MARGIN + X_MARGIN, height + Y_MARGIN + Y_MARGIN, CORNER_RADIUS, CORNER_RADIUS);\n    var menuItem = new Node({ cursor: 'pointer' });\n    menuItem.addChild(highlight);\n    menuItem.addChild(textNode);\n    textNode.left = highlight.left + X_MARGIN;\n    textNode.centerY = highlight.centerY;\n    menuItem.addInputListener({\n      enter: function () {\n        highlight.fill = HIGHLIGHT_COLOR;\n      },\n      exit: function () {\n        highlight.fill = null;\n      },\n      upImmediate: function () {\n        immediateCallback && immediateCallback();\n      }\n    });\n    menuItem.addInputListener(new ButtonListener({ fire: callback }));\n    return menuItem;\n  };\n  var createBubble = function (width, height) {\n    var rectangle = new Rectangle(0, 0, width, height, 8, 8, {\n        fill: 'white',\n        lineWidth: 1,\n        stroke: 'black'\n      });\n    var tail = new Shape();\n    tail.moveTo(width - 20, height - 2);\n    tail.lineToRelative(0, 20);\n    tail.lineToRelative(-20, -20);\n    tail.close();\n    var tailOutline = new Shape();\n    tailOutline.moveTo(width - 20, height);\n    tailOutline.lineToRelative(0, 20 - 2);\n    tailOutline.lineToRelative(-18, -18);\n    var bubble = new Node();\n    bubble.addChild(rectangle);\n    bubble.addChild(new Path(tail, { fill: 'white' }));\n    bubble.addChild(new Path(tailOutline, {\n      stroke: 'black',\n      lineWidth: 1\n    }));\n    return bubble;\n  };\n  function PhetMenu(sim, options) {\n    options = _.extend({ renderer: 'svg' }, options);\n    var thisMenu = this;\n    Node.call(thisMenu);\n    var itemDescriptors = [\n        {\n          text: 'PhET website',\n          present: true,\n          callback: function () {\n          },\n          immediateCallback: function () {\n            var phetWindow = window.open('http://phet.colorado.edu', '_blank');\n            phetWindow.focus();\n          }\n        },\n        {\n          text: 'Output Log',\n          present: log.enabled ? true : false,\n          callback: function () {\n            console.log(JSON.stringify(log.entries));\n          }\n        },\n        {\n          text: 'Output Input Events Log',\n          present: !!sim.options.recordInputEventLog,\n          callback: function () {\n            console.log(sim.getRecordedInputEventLogString());\n          }\n        },\n        {\n          text: 'Submit Input Events Log',\n          present: !!sim.options.recordInputEventLog,\n          callback: function () {\n            sim.submitEventLog();\n          }\n        },\n        {\n          text: 'Mail Input Events Log',\n          present: !!sim.options.recordInputEventLog,\n          callback: function () {\n          },\n          immediateCallback: function () {\n            sim.mailEventLog();\n          }\n        },\n        {\n          text: 'About...',\n          present: true,\n          callback: function () {\n            var aboutDialog = new AboutDialog(sim);\n            var plane = new Plane({\n                fill: 'black',\n                opacity: 0.3\n              });\n            sim.addChild(plane);\n            sim.addChild(aboutDialog);\n            var aboutDialogListener = {\n                up: function () {\n                  aboutDialog.removeInputListener(aboutDialogListener);\n                  plane.addInputListener(aboutDialogListener);\n                  aboutDialog.detach();\n                  plane.detach();\n                }\n              };\n            aboutDialog.addInputListener(aboutDialogListener);\n            plane.addInputListener(aboutDialogListener);\n          }\n        }\n      ];\n    var keepItemDescriptors = _.filter(itemDescriptors, function (itemDescriptor) {\n        return itemDescriptor.present;\n      });\n    var textNodes = _.map(keepItemDescriptors, function (item) {\n        return new Text(item.text, { font: new PhetFont(FONT_SIZE) });\n      });\n    var maxTextWidth = _.max(textNodes, function (node) {\n        return node.width;\n      }).width;\n    var maxTextHeight = _.max(textNodes, function (node) {\n        return node.height;\n      }).height;\n    var items = _.map(keepItemDescriptors, function (itemDescriptor) {\n        return createMenuItem(itemDescriptor.text, maxTextWidth, maxTextHeight, itemDescriptor.callback, itemDescriptor.immediateCallback);\n      });\n    var itemWidth = _.max(items, function (item) {\n        return item.width;\n      }).width;\n    var itemHeight = _.max(items, function (item) {\n        return item.height;\n      }).height;\n    var X_MARGIN = 5;\n    var Y_MARGIN = 5;\n    var bubbleWidth = itemWidth + X_MARGIN + X_MARGIN;\n    var bubbleHeight = itemHeight * items.length + Y_MARGIN + Y_MARGIN;\n    thisMenu.addChild(createBubble(bubbleWidth, bubbleHeight));\n    var y = Y_MARGIN;\n    _.each(items, function (item) {\n      item.top = y;\n      item.left = X_MARGIN;\n      thisMenu.addChild(item);\n      if (item === items[items.length - 2]) {\n        thisMenu.addChild(new Path(Shape.lineSegment(8, y + itemHeight, bubbleWidth - 8, y + itemHeight), {\n          stroke: 'gray',\n          lineWidth: 1\n        }));\n      }\n      y += itemHeight;\n    });\n    thisMenu.mutate(options);\n  }\n  inherit(Node, PhetMenu);\n  return PhetMenu;\n});",
    "\ndefine('PHET_CORE/platform',['require'],function (require) {\n  'use strict';\n  function isIE(version) {\n    var r = new RegExp('msie' + (!isNaN(version) ? '\\\\s' + version : ''), 'i');\n    return r.test(navigator.userAgent);\n  }\n  return {\n    get firefox() {\n      return navigator.userAgent.toLowerCase().indexOf('firefox') > -1;\n    },\n    get mobileSafari() {\n      return navigator.userAgent.match(/(iPod|iPhone|iPad)/) && navigator.userAgent.match(/AppleWebKit/);\n    },\n    get ie9() {\n      return isIE(9);\n    },\n    get ie10() {\n      return isIE(10);\n    },\n    get ie() {\n      return navigator.userAgent.indexOf('MSIE') !== -1;\n    },\n    get android() {\n      return navigator.userAgent.indexOf('Android') > 0;\n    }\n  };\n});",
    "\ndefine('JOIST/joistImageLoader',[],function () {\n  'use strict';\n  return {\n    imageNames: [\n      'phet-logo-loading.svg',\n      'phet-logo-short.svg',\n      'phet-logo-short.png'\n    ]\n  };\n});",
    "\ndefine('JOIST/PhetButton',['require','SCENERY/nodes/Node','SCENERY/nodes/Path','SCENERY/nodes/Text','SCENERY/nodes/Image','SUN/FontAwesomeNode','SCENERY/nodes/Rectangle','SCENERY/nodes/Plane','PHET_CORE/inherit','PHET_CORE/platform','JOIST/PhetMenu','SCENERY/util/Font','KITE/Shape','SCENERY/util/LinearGradient','SCENERY/input/ButtonListener','DOT/Vector2','JOIST/joistImageLoader'],function (require) {\n  'use strict';\n  var Node = require('SCENERY/nodes/Node');\n  var Path = require('SCENERY/nodes/Path');\n  var Text = require('SCENERY/nodes/Text');\n  var Image = require('SCENERY/nodes/Image');\n  var FontAwesomeNode = require('SUN/FontAwesomeNode');\n  var Rectangle = require('SCENERY/nodes/Rectangle');\n  var Plane = require('SCENERY/nodes/Plane');\n  var inherit = require('PHET_CORE/inherit');\n  var platform = require('PHET_CORE/platform');\n  var PhetMenu = require('JOIST/PhetMenu');\n  var Font = require('SCENERY/util/Font');\n  var Shape = require('KITE/Shape');\n  var LinearGradient = require('SCENERY/util/LinearGradient');\n  var ButtonListener = require('SCENERY/input/ButtonListener');\n  var Vector2 = require('DOT/Vector2');\n  var joistImageLoader = require('JOIST/joistImageLoader');\n  var createHighlight = function (width, height) {\n    var leftBar = new Path(Shape.lineSegment(0, 0, 0, height), {\n        lineWidth: 1,\n        stroke: new LinearGradient(0, 0, 0, height).addColorStop(0, 'black').addColorStop(0.5, 'white').addColorStop(1, 'black')\n      });\n    var rightBar = new Path(Shape.lineSegment(width, 0, width, height), {\n        lineWidth: 1,\n        stroke: new LinearGradient(0, 0, 0, height).addColorStop(0, 'black').addColorStop(0.5, 'white').addColorStop(1, 'black')\n      });\n    return new Node({\n      children: [\n        leftBar,\n        rightBar\n      ],\n      visible: false\n    });\n  };\n  var createHighlightListener = function (node) {\n    return {\n      over: function (event) {\n        if (event.pointer.isMouse) {\n          node.visible = true;\n        }\n      },\n      out: function (event) {\n        if (event.pointer.isMouse) {\n          node.visible = false;\n        }\n      }\n    };\n  };\n  function PhetButton(sim, options) {\n    var phetButton = this;\n    Node.call(this, {\n      renderer: 'svg',\n      cursor: 'pointer'\n    });\n    options = _.extend({\n      phetLogo: 'phet-logo-short.svg',\n      phetLogoScale: 0.28,\n      optionsButtonVerticalMargin: 1.5\n    }, options);\n    var phetLabel = new Image(joistImageLoader.getImage(options.phetLogo), { scale: options.phetLogoScale });\n    if (platform.firefox) {\n      phetLabel.renderer = 'canvas';\n    }\n    var optionsButton = new FontAwesomeNode('reorder', {\n        fill: '#fff',\n        scale: 0.6,\n        left: phetLabel.width + 10,\n        bottom: phetLabel.bottom - options.optionsButtonVerticalMargin\n      });\n    this.addChild(phetLabel);\n    this.addChild(optionsButton);\n    var optionsHighlight = createHighlight(this.width + 6, this.height - 2);\n    optionsHighlight.bottom = this.bottom + 3;\n    optionsHighlight.x = -3;\n    this.addChild(optionsHighlight);\n    var phetButtonPressed = function () {\n      var phetMenu = new PhetMenu(sim);\n      phetMenu.right = phetButton.globalToParentPoint(new Vector2(phetButton.globalBounds.maxX, 0)).x;\n      phetMenu.bottom = phetButton.centerY;\n      var rectangle = new Plane({\n          fill: 'black',\n          opacity: 0.3\n        });\n      var detach = function () {\n        rectangle.detach();\n        phetMenu.detach();\n        phetMenu.removeInputListener(popupMenuListener);\n        rectangle.removeInputListener(rectangleListener);\n      };\n      var popupMenuListener = new ButtonListener({ fire: detach });\n      var rectangleListener = { down: detach };\n      phetMenu.addInputListener(popupMenuListener);\n      rectangle.addInputListener(rectangleListener);\n      phetButton.parents[0].addChild(rectangle);\n      phetButton.parents[0].addChild(phetMenu);\n    };\n    this.addPeer('<input type=\"button\" aria-label=\"PhET Menu\">', {\n      click: phetButtonPressed,\n      tabIndex: 101\n    });\n    this.addInputListener(new ButtonListener({ fire: phetButtonPressed }));\n    this.addInputListener(createHighlightListener(optionsHighlight));\n    this.mouseArea = this.touchArea = Shape.bounds(this.bounds);\n    this.mutate(options);\n  }\n  return inherit(Node, PhetButton);\n});",
    "\ndefine('JOIST/Highlight',['require','SCENERY/nodes/Node','SCENERY/nodes/Path','KITE/Shape','SCENERY/util/LinearGradient'],function (require) {\n  'use strict';\n  var Node = require('SCENERY/nodes/Node');\n  var Path = require('SCENERY/nodes/Path');\n  var Shape = require('KITE/Shape');\n  var LinearGradient = require('SCENERY/util/LinearGradient');\n  var createHighlight = function (width, height) {\n    var leftBar = new Path(Shape.lineSegment(0, 0, 0, height), {\n        lineWidth: 1,\n        stroke: new LinearGradient(0, 0, 0, height).addColorStop(0, 'black').addColorStop(0.5, 'white').addColorStop(1, 'black')\n      });\n    var rightBar = new Path(Shape.lineSegment(width, 0, width, height), {\n        lineWidth: 1,\n        stroke: new LinearGradient(0, 0, 0, height).addColorStop(0, 'black').addColorStop(0.5, 'white').addColorStop(1, 'black')\n      });\n    return new Node({\n      children: [\n        leftBar,\n        rightBar\n      ],\n      visible: false\n    });\n  };\n  var createHighlightListener = function (node) {\n    return {\n      over: function (event) {\n        if (event.pointer.isMouse) {\n          node.visible = true;\n        }\n      },\n      out: function (event) {\n        if (event.pointer.isMouse) {\n          node.visible = false;\n        }\n      }\n    };\n  };\n  return {\n    createHighlight: createHighlight,\n    createHighlightListener: createHighlightListener\n  };\n});",
    "\ndefine('JOIST/NavigationBar',['require','SCENERY/nodes/Node','SCENERY/nodes/Path','SCENERY/nodes/HBox','SCENERY/nodes/VBox','SCENERY/nodes/Text','SUN/FontAwesomeNode','SUN/Panel','SCENERY_PHET/HomeButton','SCENERY/nodes/Rectangle','PHET_CORE/inherit','JOIST/PhetMenu','SCENERY_PHET/PhetFont','KITE/Shape','SCENERY/util/LinearGradient','JOIST/PhetButton','SCENERY/input/ButtonListener','JOIST/Highlight'],function (require) {\n  'use strict';\n  var Node = require('SCENERY/nodes/Node');\n  var Path = require('SCENERY/nodes/Path');\n  var HBox = require('SCENERY/nodes/HBox');\n  var VBox = require('SCENERY/nodes/VBox');\n  var Text = require('SCENERY/nodes/Text');\n  var FontAwesomeNode = require('SUN/FontAwesomeNode');\n  var Panel = require('SUN/Panel');\n  var HomeButton = require('SCENERY_PHET/HomeButton');\n  var Rectangle = require('SCENERY/nodes/Rectangle');\n  var inherit = require('PHET_CORE/inherit');\n  var PhetMenu = require('JOIST/PhetMenu');\n  var PhetFont = require('SCENERY_PHET/PhetFont');\n  var Shape = require('KITE/Shape');\n  var LinearGradient = require('SCENERY/util/LinearGradient');\n  var PhetButton = require('JOIST/PhetButton');\n  var ButtonListener = require('SCENERY/input/ButtonListener');\n  var Highlight = require('JOIST/Highlight');\n  function NavigationBar(sim, screens, model) {\n    this.screens = screens;\n    this.navBarHeight = 40;\n    this.navBarScale = 1;\n    this.navBarWidth = 768;\n    Node.call(this, { renderer: 'svg' });\n    this.background = new Rectangle(0, 0, 0, 0, { fill: 'black' });\n    this.addChild(this.background);\n    this.hbox = new PhetButton(sim);\n    this.addChild(this.hbox);\n    this.titleLabel = new Text(sim.name, {\n      font: new PhetFont(18),\n      fill: 'white'\n    });\n    var index = 0;\n    var selectedFont = new PhetFont({\n        size: 10,\n        weight: 'bold'\n      });\n    var normalFont = new PhetFont({ size: 10 });\n    this.addChild(this.titleLabel);\n    if (screens.length > 1) {\n      var iconAndTextArray = _.map(screens, function (screen) {\n          var icon = new Node({\n              children: [screen.icon],\n              scale: 25 / screen.icon.height\n            });\n          var text = new Text(screen.name, {\n              fill: 'white',\n              visible: true\n            });\n          var textPanel = new Panel(text, {\n              fill: null,\n              stroke: null,\n              lineWidth: 1,\n              xMargin: 4,\n              yMargin: 0,\n              cornerRadius: 0,\n              resize: false\n            });\n          var iconAndText = new VBox({\n              children: [\n                icon,\n                textPanel\n              ]\n            });\n          iconAndText.icon = icon;\n          iconAndText.text = text;\n          iconAndText.textPanel = textPanel;\n          iconAndText.index = index++;\n          iconAndText.screen = screen;\n          model.screenIndexProperty.link(function (screenIndex) {\n            var selected = iconAndText.index === screenIndex;\n            iconAndText.text.fill = selected ? 'yellow' : 'white';\n            iconAndText.text.font = selected ? selectedFont : normalFont;\n            iconAndText.opacity = selected ? 1 : 0.5;\n          });\n          return iconAndText;\n        });\n      var maxWidth = _.max(iconAndTextArray, function (iconAndText) {\n          return iconAndText.width;\n        }).width;\n      var maxHeight = _.max(iconAndTextArray, function (iconAndText) {\n          return iconAndText.height;\n        }).height;\n      this.buttonArray = iconAndTextArray.map(function (iconAndText) {\n        var rectangle = new Rectangle(0, 0, maxWidth, maxHeight);\n        var highlight = Highlight.createHighlight(maxWidth, maxHeight);\n        iconAndText.centerX = maxWidth / 2;\n        iconAndText.top = 0;\n        var button = new Node({\n            children: [\n              rectangle,\n              highlight,\n              iconAndText\n            ]\n          });\n        model.screenIndexProperty.link(function (screenIndex) {\n          button.cursor = screenIndex === iconAndText.index ? 'default' : 'pointer';\n        });\n        var pressListener = function () {\n          model.screenIndex = iconAndText.index;\n          model.showHomeScreen = false;\n        };\n        button.addInputListener(new ButtonListener({ fire: pressListener }));\n        button.addInputListener({\n          over: function (event) {\n            if (event.pointer.isMouse) {\n              highlight.visible = true;\n            }\n          },\n          out: function (event) {\n            if (event.pointer.isMouse) {\n              highlight.visible = false;\n            }\n          }\n        });\n        button.addPeer('<input type=\"button\" aria-label=\"Switch to the ' + iconAndText.screen.name + ' screen\">', {\n          click: pressListener,\n          tabIndex: 99\n        });\n        return button;\n      });\n      var maxIconWidth = _.max(iconAndTextArray, function (i) {\n          return i.icon.width;\n        }).icon.width;\n      var maxTextWidth = _.max(iconAndTextArray, function (i) {\n          return i.text.width;\n        }).text.width;\n      this.buttonHBox = new HBox({\n        spacing: maxTextWidth <= maxIconWidth + 2 ? 20 : 0,\n        children: this.buttonArray\n      });\n      this.addChild(this.buttonHBox);\n      this.homeIcon = new HomeButton();\n      var homeHighlight = Highlight.createHighlight(this.homeIcon.width + 10, this.homeIcon.height + 5);\n      homeHighlight.bottom = this.homeIcon.bottom + 3;\n      homeHighlight.x = -5;\n      this.homeIcon.addChild(homeHighlight);\n      model.showHomeScreenProperty.link(function (showHomeScreen) {\n        if (showHomeScreen) {\n          homeHighlight.visible = false;\n        }\n      });\n      this.homeIcon.addInputListener({\n        down: function () {\n          model.showHomeScreen = true;\n        }\n      });\n      this.homeIcon.addInputListener(Highlight.createHighlightListener(homeHighlight));\n      this.homeIcon.addPeer('<input type=\"button\" aria-label=\"Home Screen\">', {\n        click: function () {\n          model.showHomeScreen = true;\n        },\n        tabIndex: 100\n      });\n      this.addChild(this.homeIcon);\n    }\n  }\n  return inherit(Node, NavigationBar, {\n    relayout: function () {\n      var navigationBar = this;\n      navigationBar.background.rectHeight = this.navBarHeight;\n      navigationBar.background.rectWidth = this.navBarWidth;\n      var screenIndex = navigationBar.screenIndex;\n      if (this.buttonHBox) {\n        this.buttonHBox.setScaleMagnitude(navigationBar.navBarScale);\n      }\n      this.titleLabel.setScaleMagnitude(this.navBarScale);\n      this.titleLabel.centerY = this.navBarHeight / 2;\n      this.titleLabel.left = 10;\n      if (this.screens.length !== 1) {\n        this.buttonHBox.centerX = this.navBarWidth / 2;\n        this.buttonHBox.top = 2;\n        navigationBar.homeIcon.setScaleMagnitude(this.navBarScale);\n        navigationBar.homeIcon.top = 2;\n        navigationBar.homeIcon.left = navigationBar.buttonHBox.right + 15;\n      }\n      this.hbox.setScaleMagnitude(this.navBarScale);\n      this.hbox.right = this.navBarWidth - 5;\n      this.hbox.centerY = this.navBarHeight / 2;\n    },\n    layout: function (scale, width, height, windowHeight) {\n      this.navBarScale = scale;\n      this.navBarWidth = width;\n      this.navBarHeight = height;\n      this.relayout();\n    }\n  });\n});",
    "\ndefine('JOIST/Frame',['require','PHET_CORE/inherit','SCENERY/nodes/Node','SCENERY/nodes/Rectangle','SCENERY/util/LinearGradient'],function (require) {\n  'use strict';\n  var inherit = require('PHET_CORE/inherit');\n  var Node = require('SCENERY/nodes/Node');\n  var Rectangle = require('SCENERY/nodes/Rectangle');\n  var LinearGradient = require('SCENERY/util/LinearGradient');\n  function Frame(content, options) {\n    var thisNode = this;\n    options = _.extend({\n      xMargin1: 6,\n      yMargin1: 6,\n      cornerRadius: 0\n    }, options);\n    Node.call(thisNode);\n    var width1 = content.width + 2 * options.xMargin1;\n    var height1 = content.height + 2 * options.yMargin1;\n    this.gradient = new LinearGradient(0, 0, width1, 0).addColorStop(0, '#fbff41').addColorStop(118 / 800, '#fef98b').addColorStop(372 / 800, '#feff40').addColorStop(616 / 800, '#fffccd').addColorStop(1, '#fbff41');\n    this.rectangle = new Rectangle(0, 0, width1, height1, options.cornerRadius, options.cornerRadius, {\n      stroke: this.gradient,\n      lineWidth: 3,\n      x: content.x - options.xMargin1,\n      y: content.y - options.yMargin1\n    });\n    this.addChild(this.rectangle);\n    this.mutate(options);\n    this.width1 = width1;\n    this.height1 = height1;\n  }\n  inherit(Node, Frame, {\n    setHighlighted: function (highlighted) {\n      this.rectangle.lineWidth = highlighted ? 4.5 : 3;\n      if (highlighted) {\n        this.rectangle.setRect(-1.5 / 2, -1.5 / 2, this.width1 + 1.5, this.height1 + 1.5);\n      } else {\n        this.rectangle.setRect(0, 0, this.width1, this.height1);\n      }\n    }\n  });\n  return Frame;\n});",
    "\ndefine('JOIST/FullScreenButton',['require','SCENERY/nodes/Node','SCENERY/nodes/Path','KITE/Shape','SCENERY/util/LinearGradient','SUN/FontAwesomeNode','PHET_CORE/inherit','SCENERY/input/ButtonListener','SCENERY/input/Input'],function (require) {\n  'use strict';\n  var Node = require('SCENERY/nodes/Node');\n  var Path = require('SCENERY/nodes/Path');\n  var Shape = require('KITE/Shape');\n  var LinearGradient = require('SCENERY/util/LinearGradient');\n  var FontAwesomeNode = require('SUN/FontAwesomeNode');\n  var inherit = require('PHET_CORE/inherit');\n  var ButtonListener = require('SCENERY/input/ButtonListener');\n  var Input = require('SCENERY/input/Input');\n  function requestFullScreen(element) {\n    var requestMethod = element.requestFullScreen || element.webkitRequestFullScreen || element.mozRequestFullScreen || element.msRequestFullScreen;\n    if (requestMethod) {\n      requestMethod.call(element);\n    } else if (typeof window.ActiveXObject !== 'undefined') {\n      var wscript = new ActiveXObject('WScript.Shell');\n      if (wscript !== null) {\n        wscript.SendKeys('{F11}');\n      }\n    }\n  }\n  var fullScreener = function () {\n    requestFullScreen(document.body);\n  };\n  function FullScreenButton(options) {\n    Node.call(this, { cursor: 'pointer' });\n    this.addChild(new FontAwesomeNode('fullscreen', {\n      fill: '#fff',\n      scale: 0.8\n    }));\n    this.mutate(_.extend({ cursor: 'pointer' }, options));\n    this.addInputListener({\n      down: function () {\n        $('body').one('mouseup', fullScreener);\n      }\n    });\n    this.mouseArea = this.bounds;\n    this.touchArea = this.bounds;\n  }\n  return inherit(Node, FullScreenButton);\n});",
    "\ndefine('JOIST/HomeScreen',['require','JOIST/PhetButton','SCENERY/nodes/Node','SCENERY/nodes/HBox','SCENERY/nodes/VBox','SCENERY/nodes/Text','KITE/Shape','PHET_CORE/inherit','PHET_CORE/platform','JOIST/ScreenView','JOIST/Frame','SCENERY/nodes/Rectangle','AXON/Property','SCENERY/input/ButtonListener','JOIST/FullScreenButton','SCENERY_PHET/PhetFont'],function (require) {\n  'use strict';\n  var PhetButton = require('JOIST/PhetButton');\n  var Node = require('SCENERY/nodes/Node');\n  var HBox = require('SCENERY/nodes/HBox');\n  var VBox = require('SCENERY/nodes/VBox');\n  var Text = require('SCENERY/nodes/Text');\n  var Shape = require('KITE/Shape');\n  var inherit = require('PHET_CORE/inherit');\n  var platform = require('PHET_CORE/platform');\n  var ScreenView = require('JOIST/ScreenView');\n  var Frame = require('JOIST/Frame');\n  var Rectangle = require('SCENERY/nodes/Rectangle');\n  var Property = require('AXON/Property');\n  var ButtonListener = require('SCENERY/input/ButtonListener');\n  var FullScreenButton = require('JOIST/FullScreenButton');\n  var PhetFont = require('SCENERY_PHET/PhetFont');\n  var HEIGHT = 70;\n  function HomeScreen(sim) {\n    var homeScreen = this;\n    ScreenView.call(this, { renderer: 'svg' });\n    this.backgroundColor = 'black';\n    var title = new Text(sim.name, {\n        font: new PhetFont({\n          size: 52,\n          family: 'Century Gothic, Futura'\n        }),\n        fill: 'white',\n        y: 110,\n        centerX: this.layoutBounds.width / 2\n      });\n    this.addChild(title);\n    var highlightedIndex = new Property(-1);\n    var screenChildren = _.map(sim.screens, function (screen) {\n        var index = sim.screens.indexOf(screen);\n        var largeIcon = new Node({\n            children: [screen.icon],\n            scale: HEIGHT / screen.icon.height * 2\n          });\n        var frame = new Frame(largeIcon);\n        highlightedIndex.link(function (highlightedIndex) {\n          frame.setHighlighted(highlightedIndex === index);\n        });\n        var largeIconWithFrame = new Node({\n            children: [\n              frame,\n              largeIcon\n            ]\n          });\n        var large = new VBox({\n            cursor: 'pointer',\n            children: [\n              largeIconWithFrame,\n              new Text(screen.name, {\n                font: new PhetFont(42),\n                fill: 'yellow'\n              })\n            ]\n          });\n        large.addInputListener({\n          down: function () {\n            sim.simModel.showHomeScreen = false;\n            highlightedIndex.value = -1;\n          }\n        });\n        var small = new VBox({\n            spacing: 3,\n            cursor: 'pointer',\n            children: [\n              new Node({\n                opacity: 0.5,\n                children: [screen.icon],\n                scale: sim.screens.length === 4 ? HEIGHT / screen.icon.height : sim.screens.length === 3 ? 1.25 * HEIGHT / screen.icon.height : sim.screens.length === 2 ? 1.75 * HEIGHT / screen.icon.height : HEIGHT / screen.icon.height\n              }),\n              new Text(screen.name, {\n                font: new PhetFont(18),\n                fill: 'gray'\n              })\n            ]\n          });\n        small.mouseArea = small.touchArea = Shape.bounds(small.bounds);\n        small.addInputListener({\n          down: function () {\n            sim.simModel.screenIndex = index;\n          },\n          over: function (event) {\n            if (!event.pointer.isMouse) {\n              sim.simModel.screenIndex = index;\n            }\n          }\n        });\n        var highlightListener = {\n            over: function (event) {\n              if (event.pointer.isMouse) {\n                highlightedIndex.value = index;\n                small.children[0].opacity = 1;\n                small.children[1].fill = 'white';\n              }\n            },\n            out: function (event) {\n              if (event.pointer.isMouse) {\n                highlightedIndex.value = -1;\n                small.children[0].opacity = 0.5;\n                small.children[1].fill = 'gray';\n              }\n            }\n          };\n        small.addInputListener(highlightListener);\n        large.addInputListener(highlightListener);\n        large.mouseArea = large.touchArea = Shape.bounds(large.bounds);\n        return {\n          screen: screen,\n          small: small,\n          large: large,\n          index: index\n        };\n      });\n    var center = new Node({ y: 170 });\n    homeScreen.addChild(center);\n    sim.simModel.screenIndexProperty.link(function (screenIndex) {\n      var spacing = sim.screens.length === 2 ? 60 : sim.screens.length === 3 ? 60 : 33;\n      var icons = _.map(screenChildren, function (screenChild) {\n          return screenChild.index === screenIndex ? screenChild.large : screenChild.small;\n        });\n      center.children = [new HBox({\n          spacing: spacing,\n          children: icons,\n          align: 'top'\n        })];\n      center.centerX = homeScreen.layoutBounds.width / 2;\n    });\n    var showFullScreenButton = !platform.android && !platform.mobileSafari && !platform.ie;\n    if (showFullScreenButton && false) {\n      var fullScreenButton = new FullScreenButton();\n      var phetButton = new PhetButton(sim);\n      this.addChild(new HBox({\n        spacing: 10,\n        children: [\n          fullScreenButton,\n          phetButton\n        ],\n        right: this.layoutBounds.maxX - 5,\n        bottom: this.layoutBounds.maxY - 5\n      }));\n    } else {\n      this.addChild(new PhetButton(sim, {\n        phetLogo: 'phet-logo-short.svg',\n        phetLogoScale: 0.4,\n        optionsButtonVerticalMargin: 6\n      }).mutate({\n        right: this.layoutBounds.maxX - 5,\n        bottom: this.layoutBounds.maxY - 5\n      }));\n    }\n  }\n  return inherit(ScreenView, HomeScreen);\n});",
    "\ndefine('version',['require'],function (require) {\n  'use strict';\n  return function () {\n    return '1.1.0-dev.1';\n  };\n});",
    "\ndefine('JOIST/share/Pointer',['require'],function (require) {\n  'use strict';\n  function Pointer() {\n  }\n  return Pointer;\n});",
    "\ndefine('JOIST/share/Pointers',['require','JOIST/share/Pointer'],function (require) {\n  'use strict';\n  var Pointer = require('JOIST/share/Pointer');\n  return [];\n});",
    "\ndefine('JOIST/share/LogPointers',['require','JOIST/share/Pointer','JOIST/share/Pointers'],function (require) {\n  'use strict';\n  var Pointer = require('JOIST/share/Pointer');\n  var Pointers = require('JOIST/share/Pointers');\n  function LogPointers() {\n    this.pointers = new Pointers();\n  }\n  LogPointers.prototype = {\n    startLogging: function () {\n      var logPointers = this;\n      window.addEventListener('mousemove', function (e) {\n        var location = {\n            x: e.clientX,\n            y: e.clientY\n          };\n        if (logPointers.pointers.length === 0) {\n          logPointers.pointers.add(new Pointer(location));\n        } else {\n          logPointers.pointers.at(0).set(location);\n        }\n      }, false);\n      window.addEventListener('touchmove', function (e) {\n        var touches = e.touches;\n        for (var i = 0; i < touches.length; i++) {\n          var touch = touches[i];\n          var location = {\n              x: touch.pageX,\n              y: touch.pageY\n            };\n          if (i >= logPointers.pointers.length) {\n            logPointers.pointers.add(new Pointer(location));\n          } else {\n            logPointers.pointers.at(i).set(location);\n          }\n        }\n        while (logPointers.pointers.length > touches.length) {\n          logPointers.pointers.pop();\n        }\n      }, false);\n    },\n    showPointers: function () {\n      var logPointers = this;\n      this.pointers.on('add', function (model, collection, options) {\n        var $img = $('<img id=\"cursor\">');\n        $img.attr('src', 'http://dc440.4shared.com/img/mFJBl0A0/s7/mouse-cursor-icon.png');\n        $img.css({\n          zIndex: 9999,\n          position: 'absolute',\n          width: 12,\n          height: 20,\n          'pointer-events': 'none'\n        });\n        $img.appendTo('body');\n        model.on('change:x change:y', function () {\n          $img.css({\n            left: model.x,\n            top: model.y\n          });\n        });\n        logPointers.pointers.on('remove', function (m, c, o) {\n          if (m === model) {\n            $img.detach();\n          }\n        });\n      });\n    }\n  };\n  return LogPointers;\n});",
    "\ndefine('JOIST/Sim',['require','SCENERY/util/Util','JOIST/NavigationBar','JOIST/HomeScreen','SCENERY/Scene','SCENERY/nodes/Node','SCENERY/nodes/Text','DOT/Vector2','DOT/Bounds2','version','AXON/PropertySet','SCENERY_PHET/PhetFont','AXON/log','JOIST/share/LogPointers'],function (require) {\n  'use strict';\n  var Util = require('SCENERY/util/Util');\n  var NavigationBar = require('JOIST/NavigationBar');\n  var HomeScreen = require('JOIST/HomeScreen');\n  var Scene = require('SCENERY/Scene');\n  var Node = require('SCENERY/nodes/Node');\n  var Text = require('SCENERY/nodes/Text');\n  var Vector2 = require('DOT/Vector2');\n  var Bounds2 = require('DOT/Bounds2');\n  var version = require('version');\n  var PropertySet = require('AXON/PropertySet');\n  var PhetFont = require('SCENERY_PHET/PhetFont');\n  var log = require('AXON/log');\n  var LogPointers = require('JOIST/share/LogPointers');\n  function Sim(name, screens, options) {\n    options = _.extend({\n      showHomeScreen: true,\n      screenIndex: 0,\n      standalone: false,\n      credits: '',\n      thanks: ''\n    }, options);\n    this.options = options;\n    var sim = this;\n    window.sim = sim;\n    sim.name = name;\n    sim.version = version();\n    sim.credits = options.credits;\n    sim.thanks = options.thanks;\n    sim.frameCounter = 0;\n    sim.inputEventLog = [];\n    sim.inputEventBounds = Bounds2.NOTHING;\n    sim.fuzzMouseAverage = 10;\n    sim.fuzzMouseIsDown = false;\n    sim.fuzzMousePosition = new Vector2();\n    sim.fuzzMouseLastMoved = false;\n    $('title').html(name + ' ' + sim.version);\n    function stringToBoolean(string) {\n      return string === 'true' ? true : false;\n    }\n    if (window.phetcommon && window.phetcommon.getQueryParameter && window.phetcommon.getQueryParameter('showHomeScreen')) {\n      options.showHomeScreen = stringToBoolean(window.phetcommon.getQueryParameter('showHomeScreen'));\n    }\n    if (window.phetcommon && window.phetcommon.getQueryParameter && window.phetcommon.getQueryParameter('screenIndex')) {\n      options.screenIndex = parseInt(window.phetcommon.getQueryParameter('screenIndex'), 10);\n    }\n    if (window.phetcommon && window.phetcommon.getQueryParameter && window.phetcommon.getQueryParameter('recordInputEventLog')) {\n      options.recordInputEventLog = true;\n      options.inputEventLogName = window.phetcommon.getQueryParameter('recordInputEventLog');\n    }\n    if (window.phetcommon && window.phetcommon.getQueryParameter && window.phetcommon.getQueryParameter('playbackInputEventLog')) {\n      options.playbackInputEventLog = true;\n      options.inputEventLogName = window.phetcommon.getQueryParameter('playbackInputEventLog');\n    }\n    if (window.phetcommon && window.phetcommon.getQueryParameter && window.phetcommon.getQueryParameter('fuzzMouse')) {\n      options.fuzzMouse = true;\n      if (window.phetcommon.getQueryParameter('fuzzMouse') !== 'undefined') {\n        sim.fuzzMouseAverage = parseFloat(window.phetcommon.getQueryParameter('fuzzMouse'));\n      }\n    }\n    if (window.phetcommon && window.phetcommon.getQueryParameter && window.phetcommon.getQueryParameter('fuzzTouches')) {\n      options.fuzzTouches = true;\n    }\n    if (window.phetcommon && window.phetcommon.getQueryParameter && window.phetcommon.getQueryParameter('standalone')) {\n      options.standalone = true;\n      screens = [screens[options.screenIndex]];\n      options.screenIndex = 0;\n    }\n    var showHomeScreen = _.isUndefined(options.showHomeScreen) ? true : options.showHomeScreen;\n    if (screens.length === 1) {\n      showHomeScreen = false;\n    }\n    sim.screens = screens;\n    sim.simModel = new PropertySet({\n      showHomeScreen: showHomeScreen,\n      screenIndex: options.screenIndex || 0\n    });\n    var $body = $('body');\n    $body.css('padding', '0').css('margin', '0').css('overflow', 'hidden');\n    var $simDiv = $('<div>').attr('id', 'sim').css('position', 'absolute').css('left', 0).css('top', 0);\n    $body.append($simDiv);\n    sim.scene = new Scene($simDiv, {\n      allowDevicePixelRatioScaling: false,\n      accessible: true\n    });\n    sim.scene.sim = sim;\n    sim.scene.initializeWindowEvents({ batchDOMEvents: true });\n    if (options.recordInputEventLog) {\n      sim.scene.input.logEvents = true;\n    }\n    window.simScene = sim.scene;\n    sim.navigationBar = new NavigationBar(sim, screens, sim.simModel);\n    if (screens.length > 1) {\n      sim.homeScreen = new HomeScreen(sim);\n    }\n    var simNode = new Node();\n    var viewContainer = new Node({ layerSplit: true });\n    var updateBackground = function () {\n      if (sim.simModel.showHomeScreen) {\n        $simDiv.css('background', 'black');\n      } else {\n        var backgroundColor = screens[sim.simModel.screenIndex].backgroundColor || 'white';\n        var cssColor = typeof backgroundColor === 'string' ? backgroundColor : backgroundColor.toCSS();\n        $simDiv.css('background', cssColor);\n      }\n    };\n    sim.simModel.showHomeScreenProperty.link(function (showHomeScreen) {\n      simNode.children = showHomeScreen ? [] : [viewContainer];\n      if (showHomeScreen) {\n        sim.scene.children = [sim.homeScreen];\n      } else {\n        sim.scene.children = [\n          simNode,\n          sim.navigationBar\n        ];\n      }\n      updateBackground();\n    });\n    _.each(screens, function (m) {\n      m.model = m.createModel();\n      m.view = m.createView(m.model);\n    });\n    sim.simModel.screenIndexProperty.link(function (screenIndex) {\n      viewContainer.children = [screens[screenIndex].view];\n      updateBackground();\n    });\n    updateBackground();\n    $(window).resize(function () {\n      sim.resizeToWindow();\n    });\n    sim.resizeToWindow();\n  }\n  Sim.prototype.resizeToWindow = function () {\n    this.resize(window.innerWidth, window.innerHeight);\n  };\n  Sim.prototype.resize = function (width, height) {\n    var sim = this;\n    var scale = Math.min(width / 768, height / 504);\n    var navBarHeight = scale * 40;\n    sim.navigationBar.layout(scale, width, navBarHeight, height);\n    sim.navigationBar.y = height - navBarHeight;\n    sim.scene.resize(width, height);\n    _.each(sim.screens, function (m) {\n      m.view.layout(width, height - sim.navigationBar.height);\n    });\n    if (sim.homeScreen) {\n      sim.homeScreen.layout(width, height);\n    }\n    sim.scene.input.eventLog.push('scene.sim.resize(' + width + ',' + height + ');');\n  };\n  Sim.prototype.start = function () {\n    var sim = this;\n    if (this.options.playbackInputEventLog) {\n      var request = new XMLHttpRequest();\n      request.open('GET', this.getEventLogLocation(), true);\n      request.onload = function (e) {\n        sim.startInputEventPlayback(eval(request.responseText));\n      };\n      request.send();\n      return;\n    }\n    var lastTime = -1;\n    Util.polyfillRequestAnimationFrame();\n    (function animationLoop() {\n      var dt;\n      sim.frameCounter++;\n      window.requestAnimationFrame(animationLoop);\n      phetAllocation && phetAllocation('loop');\n      if (sim.options.fuzzMouse) {\n        sim.fuzzMouseEvents();\n      } else if (sim.options.fuzzTouches) {\n      } else {\n        sim.scene.fireBatchedEvents();\n      }\n      if (!sim.simModel.showHomeScreen) {\n        var time = Date.now();\n        var elapsedTimeMilliseconds = lastTime === -1 ? 1000 / 60 : time - lastTime;\n        lastTime = time;\n        dt = elapsedTimeMilliseconds / 1000;\n        sim.screens[sim.simModel.screenIndex].model.step(dt);\n      }\n      if (window.TWEEN) {\n        window.TWEEN.update();\n      }\n      if (sim.options.recordInputEventLog) {\n        var entry = {\n            dt: dt,\n            events: sim.scene.input.eventLog,\n            id: sim.frameCounter,\n            time: Date.now()\n          };\n        if (!sim.inputEventBounds.equals(sim.scene.sceneBounds)) {\n          sim.inputEventBounds = sim.scene.sceneBounds.copy();\n          entry.width = sim.scene.sceneBounds.width;\n          entry.height = sim.scene.sceneBounds.height;\n        }\n        sim.inputEventLog.push(entry);\n        sim.scene.input.eventLog = [];\n      }\n      sim.scene.updateScene();\n    }());\n  };\n  Sim.prototype.startPlayback = function (logArray) {\n    var sim = this;\n    var logIndex = 0;\n    var playbackTime = logArray[0].time;\n    Util.polyfillRequestAnimationFrame();\n    var totalTime = 0;\n    (function animationLoop() {\n      if (logIndex >= logArray.length) {\n        console.log(totalTime);\n        sim.scene.addChild(new Text('Elapsed time (ms): ' + totalTime, {\n          x: 100,\n          y: 100,\n          font: new PhetFont(32)\n        }));\n        sim.scene.updateScene();\n        return;\n      }\n      window.requestAnimationFrame(animationLoop);\n      var start = Date.now();\n      logIndex = log.stepUntil(logArray, playbackTime, logIndex);\n      playbackTime += 17;\n      sim.scene.updateScene();\n      var stop = Date.now();\n      var elapsed = stop - start;\n      totalTime += elapsed;\n    }());\n  };\n  Sim.prototype.startInputEventPlayback = function (data) {\n    var sim = this;\n    var index = 0;\n    Util.polyfillRequestAnimationFrame();\n    if (data.length && data[0].width) {\n      sim.resize(data[0].width, data[0].height);\n    }\n    var startTime = Date.now();\n    (function animationLoop() {\n      var frame = data[index++];\n      if (frame === undefined) {\n        var endTime = Date.now();\n        var elapsedTime = endTime - startTime;\n        var fps = data.length / (elapsedTime / 1000);\n        document.body.innerHTML = '<div style=\"text-align: center; font-size: 16px;\">' + '<h1>Performance results:</h1>' + '<p>Approximate frames per second: <strong>' + fps.toFixed(1) + '</strong></p>' + '<p>Average time per frame (ms/frame): <strong>' + (elapsedTime / index).toFixed(1) + '</strong></p>' + '<p>Elapsed time: <strong>' + elapsedTime + 'ms</strong></p>' + '<p>Number of frames: <strong>' + index + '</strong></p>' + '</div>';\n        document.body.style.backgroundColor = '#fff';\n        return;\n      }\n      window.requestAnimationFrame(animationLoop);\n      if (frame.fireEvents) {\n        frame.fireEvents(sim.scene, function (x, y) {\n          return new Vector2(x, y);\n        });\n      }\n      if (!sim.simModel.showHomeScreen) {\n        sim.screens[sim.simModel.screenIndex].model.step(frame.dt);\n      }\n      if (window.TWEEN) {\n        window.TWEEN.update();\n      }\n      sim.scene.updateScene();\n    }());\n  };\n  Sim.prototype.addChild = function (node) {\n    this.scene.addChild(node);\n  };\n  Sim.prototype.getRecordedInputEventLogString = function () {\n    return '[\\n' + _.map(this.inputEventLog, function (item) {\n      var fireEvents = 'fireEvents:function(scene,dot){' + _.map(item.events, function (str) {\n          return 'scene.input.' + str;\n        }).join('') + '}';\n      return '{dt:' + item.dt + (item.events.length ? ',' + fireEvents : '') + (item.width ? ',width:' + item.width : '') + (item.height ? ',height:' + item.height : '') + ',id:' + item.id + ',time:' + item.time + '}';\n    }).join(',\\n') + '\\n]';\n  };\n  Sim.prototype.getEventLogName = function () {\n    var name = this.options.inputEventLogName;\n    if (name === 'browser') {\n      name = window.navigator.userAgent;\n    }\n    return (this.name + '_' + name).replace(/[^a-zA-Z0-9]/g, '_');\n  };\n  Sim.prototype.getEventLogLocation = function () {\n    var host = window.location.host.split(':')[0];\n    return '//' + host + ':8083/' + this.getEventLogName();\n  };\n  Sim.prototype.submitEventLog = function () {\n    if (!this.options.recordInputEventLog) {\n      return;\n    }\n    var data = this.getRecordedInputEventLogString();\n    var xmlhttp = new XMLHttpRequest();\n    xmlhttp.open('POST', this.getEventLogLocation(), true);\n    xmlhttp.setRequestHeader('Content-type', 'text/javascript');\n    xmlhttp.send(data);\n  };\n  Sim.prototype.mailEventLog = function () {\n    if (!this.options.recordInputEventLog) {\n      return;\n    }\n    var data = this.getRecordedInputEventLogString();\n    window.open('mailto:phethelp@colorado.edu?subject=' + encodeURIComponent(this.name + ' input event log at ' + Date.now()) + '&body=' + encodeURIComponent(data));\n  };\n  Sim.prototype.fuzzMouseEvents = function () {\n    var sim = this;\n    var chance;\n    while ((chance = Math.random()) < 1 - 1 / sim.fuzzMouseAverage) {\n      var domEvent;\n      if (chance < (sim.fuzzMouseLastMoved ? 0.02 : 0.4)) {\n        domEvent = document.createEvent('MouseEvent');\n        domEvent.initMouseEvent(sim.fuzzMouseIsDown ? 'mouseup' : 'mousedown', true, true, window, 1, sim.fuzzMousePosition.x, sim.fuzzMousePosition.y, sim.fuzzMousePosition.x, sim.fuzzMousePosition.y, false, false, false, false, 0, null);\n        sim.scene.input.validatePointers();\n        if (sim.fuzzMouseIsDown) {\n          sim.scene.input.mouseUp(sim.fuzzMousePosition, domEvent);\n          sim.fuzzMouseIsDown = false;\n        } else {\n          sim.scene.input.mouseDown(sim.fuzzMousePosition, domEvent);\n          sim.fuzzMouseIsDown = true;\n        }\n      } else {\n        sim.fuzzMousePosition = new Vector2(Math.floor(Math.random() * sim.scene.sceneBounds.width), Math.floor(Math.random() * sim.scene.sceneBounds.height));\n        domEvent = document.createEvent('MouseEvent');\n        domEvent.initMouseEvent('mousemove', true, true, window, 0, sim.fuzzMousePosition.x, sim.fuzzMousePosition.y, sim.fuzzMousePosition.x, sim.fuzzMousePosition.y, false, false, false, false, 0, null);\n        sim.scene.input.validatePointers();\n        sim.scene.input.mouseMove(sim.fuzzMousePosition, domEvent);\n      }\n    }\n  };\n  return Sim;\n});",
    "\ndefine('JOIST/SimLauncher',['require','JOIST/joistImageLoader'],function (require) {\n  'use strict';\n  var joistImageLoader = require('JOIST/joistImageLoader');\n  var loadedResourceCount = 0;\n  return {\n    launch: function (simImageLoader, callback) {\n      var pxLoader;\n      var elementsToRemove = [];\n      var delayCompletionEvent = false;\n      function doneLoadingImages() {\n        loadedResourceCount++;\n        if (loadedResourceCount === 1) {\n          $('#splash').remove();\n          callback();\n        }\n      }\n      function load(imageLoader, path) {\n        var loadedImages = {};\n        imageLoader.getImage = function (name) {\n          return loadedImages[name];\n        };\n        imageLoader.imageNames.forEach(function (image) {\n          var filename = path + '/' + image;\n          loadedImages[image] = document.getElementById(filename);\n          if (loadedImages[image]) {\n            if (loadedImages[image].width === 0 || loadedImages[image].height === 0) {\n              delayCompletionEvent = true;\n            }\n            elementsToRemove.push(loadedImages[image]);\n          } else {\n            window.console && console.log && console.log('WARNING: could not find image: ' + filename + ', using PxLoader');\n            if (!pxLoader) {\n              pxLoader = new PxLoader();\n            }\n            loadedImages[image] = pxLoader.addImage(filename);\n          }\n        });\n      }\n      load(simImageLoader, 'images');\n      load(joistImageLoader, '../joist/images');\n      if (pxLoader) {\n        pxLoader.addCompletionListener(doneLoadingImages);\n        pxLoader.start();\n      } else {\n        if (!delayCompletionEvent) {\n          doneLoadingImages();\n        }\n      }\n      $(window).load(function () {\n        if (delayCompletionEvent && !pxLoader) {\n          doneLoadingImages();\n        }\n        _.each(elementsToRemove, function (element) {\n          element.parentNode.removeChild(element);\n        });\n      });\n    }\n  };\n});",
    "\nrequire([\n  'common/model/BuildAnAtomModel',\n  'buildanatom/view/BuildAnAtomView',\n  'SCENERY_PHET/PhetFont',\n  'game/model/BAAGameModel',\n  'game/view/BAAGameView',\n  'symbol/view/SymbolView',\n  'SCENERY/nodes/Circle',\n  'SCENERY/nodes/Image',\n  'SCENERY/nodes/Rectangle',\n  'SCENERY/nodes/Text',\n  'JOIST/Sim',\n  'JOIST/SimLauncher',\n  'imageLoader'\n], function (BuildAnAtomModel, BuildAnAtomView, PhetFont, BAAGameModel, BAAGameView, SymbolView, Circle, Image, Rectangle, Text, Sim, SimLauncher, imageLoader) {\n  'use strict';\n  var simOptions = {\n      credits: 'PhET Development Team -\\n' + 'Lead Design: Kelly Lancaster\\n' + 'Software Development: John Blanco, Sam Reid\\n' + 'Design Team: Jack Barbera, Suzanne Brahmia, Julia Chamberlain, Yuen-ying Carpenter, Patricia Loeblein, Emily B. Moore, Robert Parson, Ariel Paul, Kathy Perkins, Sharon Siman-Tov\\n' + 'Interviews: Emily B. Moore, Kelly Lancaster, Ariel Paul',\n      thanks: 'Thanks -\\n' + 'Conversion of this simulation to HTML5 was funded by the Royal Society of Chemistry.'\n    };\n  SimLauncher.launch(imageLoader, function () {\n    new Sim('Build an Atom', [\n      {\n        name: 'Atom',\n        icon: new Image(imageLoader.getImage('baa_atom_icon.png')),\n        backgroundColor: 'white',\n        createModel: function () {\n          return new BuildAnAtomModel();\n        },\n        createView: function (model) {\n          return new BuildAnAtomView(model);\n        }\n      },\n      {\n        name: 'Symbol',\n        icon: new Image(imageLoader.getImage('baa_element_icon.png')),\n        backgroundColor: 'rgb( 242, 255, 204 )',\n        createModel: function () {\n          return new BuildAnAtomModel();\n        },\n        createView: function (model) {\n          return new SymbolView(model);\n        }\n      },\n      {\n        name: 'Game',\n        icon: new Image(imageLoader.getImage('game_icon.png')),\n        backgroundColor: 'rgb( 255, 254, 223 )',\n        createModel: function () {\n          return new BAAGameModel();\n        },\n        createView: function (model) {\n          return new BAAGameView(model);\n        }\n      }\n    ], simOptions).start();\n  });\n});\ndefine(\"build-an-atom-main\", function(){});\n",
    "\nrequire.config({\n  deps: ['build-an-atom-main'],\n  paths: {\n    i18n: '../../sherpa/i18n-2.0.4',\n    ASSERT: '../../assert/js',\n    AXON: '../../axon/js',\n    DOT: '../../dot/js',\n    JOIST: '../../joist/js',\n    KITE: '../../kite/js',\n    PHETCOMMON: '../../phetcommon/js',\n    PHET_CORE: '../../phet-core/js',\n    SCENERY: '../../scenery/js',\n    SCENERY_PHET: '../../scenery-phet/js',\n    SUN: '../../sun/js'\n  },\n  urlArgs: new Date().getTime()\n});\ndefine(\"build-an-atom-config\", function(){});\n"
  ]
}