{"version":3,"file":"bundle.js","sources":["/Users/mauricio/Documents/web/maurizzzio.me/T3/node_modules/browserify/node_modules/browser-pack/_prelude.js","/Users/mauricio/Documents/web/maurizzzio.me/T3/src/index.js","/Users/mauricio/Documents/web/maurizzzio.me/T3/src/lib/OrbitControls.js","/Users/mauricio/Documents/web/maurizzzio.me/T3/src/model/Coordinates.js","/Users/mauricio/Documents/web/maurizzzio.me/T3/src/controller/Application.js","/Users/mauricio/Documents/web/maurizzzio.me/T3/src/themes/dark.js","/Users/mauricio/Documents/web/maurizzzio.me/T3/src/themes/light.js","/Users/mauricio/Documents/web/maurizzzio.me/T3/src/controller/Keyboard.js","/Users/mauricio/Documents/web/maurizzzio.me/T3/src/controller/LoopManager.js","/Users/mauricio/Documents/web/maurizzzio.me/T3/src/lib/THREEx/index.js","/Users/mauricio/Documents/web/maurizzzio.me/T3/src/lib/THREEx/FullScreen.js","/Users/mauricio/Documents/web/maurizzzio.me/T3/src/lib/THREEx/WindowResize.js","/Users/mauricio/Documents/web/maurizzzio.me/T3/node_modules/extend/index.js","/Users/mauricio/Documents/web/maurizzzio.me/T3/node_modules/stats-js/build/stats.min.js","/Users/mauricio/Documents/web/maurizzzio.me/T3/node_modules/dat-gui/index.js","/Users/mauricio/Documents/web/maurizzzio.me/T3/node_modules/dat-gui/vendor/dat.color.js","/Users/mauricio/Documents/web/maurizzzio.me/T3/node_modules/dat-gui/vendor/dat.gui.js"],"names":["require","Application","t3","model","Coordinates","themes","dark","light","controller","Keyboard","LoopManager","run","module","exports","THREE","window","OrbitControls","object","domElement","getAutoRotationAngle","Math","PI","scope","autoRotateSpeed","getZoomScale","pow","zoomSpeed","onMouseDown","event","enabled","preventDefault","button","noRotate","state","STATE","ROTATE","rotateStart","set","clientX","clientY","noZoom","DOLLY","dollyStart","noPan","PAN","panStart","document","addEventListener","onMouseMove","onMouseUp","dispatchEvent","startEvent","element","body","rotateEnd","rotateDelta","subVectors","rotateLeft","x","clientWidth","rotateSpeed","rotateUp","y","clientHeight","copy","dollyEnd","dollyDelta","dollyIn","dollyOut","panEnd","panDelta","pan","update","removeEventListener","endEvent","NONE","onMouseWheel","stopPropagation","delta","undefined","wheelDelta","detail","onKeyDown","noKeys","keyCode","keys","UP","keyPanSpeed","BOTTOM","LEFT","RIGHT","touchstart","touches","length","TOUCH_ROTATE","pageX","pageY","TOUCH_DOLLY","dx","dy","distance","sqrt","TOUCH_PAN","touchmove","touchend","this","target","Vector3","center","minDistance","maxDistance","Infinity","autoRotate","minPolarAngle","maxPolarAngle","EPS","Vector2","panOffset","offset","phiDelta","thetaDelta","scale","lastPosition","lastQuaternion","Quaternion","target0","clone","position0","position","quat","setFromUnitVectors","up","quatInverse","inverse","changeEvent","type","angle","panLeft","te","matrix","elements","multiplyScalar","add","panUp","deltaX","deltaY","fov","sub","targetDistance","tan","top","right","left","bottom","console","warn","dollyScale","applyQuaternion","theta","atan2","z","phi","max","min","radius","sin","cos","lookAt","distanceToSquared","dot","quaternion","reset","prototype","Object","create","EventDispatcher","config","theme","mesh","Object3D","axes","name","drawAllAxes","axisLength","axisRadius","axisTess","visible","ground","drawGround","size","color","groundColor","gridX","drawGrid","gridColor","gridY","orientation","gridZ","init","call","me","key","hasOwnProperty","v","initDatGui","gui","folder","addFolder","onFinishChange","property","newValue","params","grid","GridHelper","setColors","rotation","Mesh","PlaneGeometry","MeshBasicMaterial","transparent","side","DoubleSide","opacity","drawAxes","axisOrientation","wrap","axisMaterial","MeshLambertMaterial","axis","CylinderGeometry","arrow","axisXMaterial","axisYMaterial","axisZMaterial","axisX","axisY","axisZ","arrowX","arrowY","arrowZ","extend","selector","width","innerWidth","height","innerHeight","renderImmediately","injectCache","fullScreen","helpersConfig","defaultSceneConfig","fog","initialConfig","scenes","activeScene","cameras","activeCamera","renderer","keyboard","datgui","stats","loopManager","__t3cache__","initApplication","assert","condition","message","emptyFn","Stats","dat","THREEx","getConfig","setTheme","createDefaultRenderer","createDefaultScene","createDefaultCamera","createDefaultLights","initStats","initMask","maskVisible","initFullScreen","initKeyboard","initCoordinates","gameLoop","setActiveScene","addScene","scene","Scene","defaultScene","Fog","fogColor","WebGLRenderer","setClearColor","clearColor","setSize","querySelector","appendChild","setActiveCamera","addCamera","camera","PerspectiveCamera","OrthographicCamera","defaultCamera","defaults","ratio","near","far","WindowResize","bind","createCameraControls","cameraControls","AmbientLight","cache","DirectionalLight","mask","createElement","className","style","background","display","GUI","autoPlace","zIndex","FullScreen","available","bindKey","animate","render","inject","lastObject","lastMethod","remove","apply","arguments","getFromCache","options","QuickLaunch","i","onKeyUp","get","charCodeAt","value","application","clock","Clock","pause","fps","guiControllers","paused","loop","elapsedTime","getDelta","frameRateInS","requestAnimationFrame","start","setValue","stop","_hasWebkitFullScreen","_hasMozFullScreen","activated","webkitIsFullScreen","mozFullScreen","request","webkitRequestFullScreen","Element","ALLOW_KEYBOARD_INPUT","mozRequestFullScreen","cancel","webkitCancelFullScreen","mozCancelFullScreen","opts","charCode","dblclick","toggle","__bind","fn","onKeyPress","which","unbind","windowResize","callback","aspect","updateProjectionMatrix","hasOwn","toString","isPlainObject","obj","has_own_constructor","has_is_property_of_method","constructor","src","copyIsArray","deep","Array","isArray","l","Date","now","m","g","n","o","h","p","q","r","s","f","id","b","t","cssText","a","innerHTML","c","children","j","d","k","e","REVISION","setMode","begin","end","textContent","firstChild","round","utils","common","ARR_EACH","forEach","ARR_SLICE","slice","BREAK","each","isUndefined","compose","toCall","args","itr","defer","fnc","setTimeout","toArray","isNull","isNaN","isObject","isNumber","isString","isBoolean","isFunction","hex","Color","interpret","math","defineRGBComponent","component","componentHexIndex","defineProperty","__state","space","recalculateRGB","defineHSVComponent","recalculateHSV","component_from_hex","hsv_to_rgb","result","rgb_to_hsv","COMPONENTS","toOriginal","conversion","write","rgb_to_hex","toReturn","original","INTERPRETATIONS","family","litmus","conversions","conversionName","read","THREE_CHAR_HEX","test","match","parseInt","SIX_CHAR_HEX","CSS_RGB","parseFloat","CSS_RGBA","HEX","RGB_ARRAY","RGBA_ARRAY","RGBA_OBJ","RGB_OBJ","HSVA_OBJ","HSV_OBJ","tmpComponent","hi","floor","NaN","hex_with_component","componentIndex","controllers","dom","css","load","url","doc","link","rel","href","getElementsByTagName","injected","Controller","initialValue","__onChange","__onFinishChange","onChange","updateDisplay","getValue","isModified","cssValueToPixels","val","CSS_VALUE_PIXELS","EVENT_MAP","HTMLEvents","MouseEvents","KeyboardEvents","EVENT_MAP_INV","makeSelectable","elem","selectable","onselectstart","MozUserSelect","KhtmlUserSelect","unselectable","makeFullscreen","horizontal","vertical","fakeEvent","eventType","aux","Error","evt","createEvent","initMouseEvent","bubbles","cancelable","clickCount","initKeyboardEvent","initKeyEvent","ctrlKey","altKey","shiftKey","metaKey","initEvent","func","bool","attachEvent","detachEvent","addClass","classes","split","indexOf","push","join","replace","removeClass","removeAttribute","index","splice","hasClass","RegExp","getWidth","getComputedStyle","getHeight","getOffset","offsetParent","offsetLeft","offsetTop","isActive","activeElement","OptionController","superclass","_this","__select","map","opt","setAttribute","desiredValue","selectedIndex","NumberController","numDecimals","__min","__max","__step","step","__impliedStep","log","LN10","__precision","NumberControllerBox","roundToDecimal","decimals","tenTo","attempted","__input","onBlur","onMouseDrag","prev_y","diff","__truncationSuspended","blur","NumberControllerSlider","styleSheet","i1","i2","o1","o2","__background","__foreground","useDefaultStyles","pct","FunctionController","text","__button","fire","BooleanController","__prev","__checkbox","checked","saveDialogueContents","controllerFactory","ColorController","CenteredDiv","factoryArgs","concat","before","__li","recallSavedValue","container","li","addRow","CLASS_CONTROLLER_ROW","augmentController","__controllers","liBefore","__ul","insertBefore","onResize","__gui","nextElementSibling","firstElementChild","listen","box","method","pc","pb","returned","borderLeftColor","__color","getRoot","__preset_select","markPresetModified","root","matched_index","__rememberedObjects","controller_map","__rememberedObjectIndecesToControllers","remembered","preset","preset_map","DEFAULT_DEFAULT_PRESET_NAME","getLocalStorageHash","location","addSaveMenu","showHideExplain","explain","useLocalStorage","div","__save_row","gears","button2","button3","select","addPresetOption","SUPPORTS_LOCAL_STORAGE","saveLocally","getElementById","localStorageCheckBox","localStorage","getItem","newConstructorTextArea","SAVE_DIALOGUE","hide","JSON","stringify","getSaveObject","show","focus","save","presetName","prompt","saveAs","revert","addResizeHandle","dragStart","pmouseX","__closeButton","CLASS_DRAG","drag","dragStop","__resize_handle","marginLeft","cursor","setWidth","w","getCurrentPreset","useInitialValues","saved_values","setSelected","setPresetSelectIndex","modified","updateDisplays","controllerArray","auto_place_container","CSS_NAMESPACE","HIDE_KEY_CODE","CLOSE_BUTTON_HEIGHT","auto_place_virgin","hideable_guis","saveToLocalStorage","setItem","resetWidth","__folders","__listening","DEFAULT_WIDTH","resizable","hideable","parent","scrollable","use_local_storage","defineProperties","title_row_name","closed","CLASS_CLOSED","TEXT_OPEN","TEXT_CLOSED","CLASS_MAIN","saved_gui","parse","CLASS_CLOSE_BUTTON","createTextNode","title_row","on_click_title","CLASS_AUTO_PLACE_CONTAINER","CLASS_AUTO_PLACE","toggleHide","CLASS_TOO_TALL","addColor","removeChild","destroy","new_gui_params","folders","open","close","childNodes","node","offsetHeight","remember","factory","StringController","linearGradient","vendors","vendor","hueGradient","fieldDown","setSV","unbindSV","unbindH","setH","__saturation_field","scrollLeft","scrollTop","__hue_field","__temp","__selector","__field_knob","__field_knob_border","__hue_knob","__input_textShadow","value_field","padding","backgroundColor","boxShadow","border","borderRadius","borderRight","marginRight","outline","textAlign","fontWeight","textShadow","mismatch","flip","_flip","marginTop","webkitRequestAnimationFrame","mozRequestAnimationFrame","oRequestAnimationFrame","msRequestAnimationFrame","backgroundElement","WebkitTransition","webkitTransform","layout"],"mappings":"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","sourcesContent":["(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error(\"Cannot find module '\"+o+\"'\")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})","require('./lib/OrbitControls');\n\n/**\n * t3\n * @namespace\n * @type {Object}\n */\nvar Application = require('./controller/Application');\nvar t3 = {\n  model: {\n    Coordinates: require('./model/Coordinates')\n  },\n  themes: {\n    dark: require('./themes/dark'),\n    light: require('./themes/light')\n  },\n  controller: {\n    Application: Application,\n    Keyboard: require('./controller/Keyboard'),\n    LoopManager: require('./controller/LoopManager')\n  },\n  Application: Application,\n\n  // alias\n  run: Application.run\n};\nmodule.exports = t3;","/**\n * @author qiao / https://github.com/qiao\n * @author mrdoob / http://mrdoob.com\n * @author alteredq / http://alteredqualia.com/\n * @author WestLangley / http://github.com/WestLangley\n * @author erich666 / http://erichaines.com\n */\n/*global THREE, console */\n\n// This set of controls performs orbiting, dollying (zooming), and panning. It maintains\n// the \"up\" direction as +Y, unlike the TrackballControls. Touch on tablet and phones is\n// supported.\n//\n//    Orbit - left mouse / touch: one finger move\n//    Zoom - middle mouse, or mousewheel / touch: two finger spread or squish\n//    Pan - right mouse, or arrow keys / touch: three finter swipe\n//\n// This is a drop-in replacement for (most) TrackballControls used in examples.\n// That is, include this js file and wherever you see:\n//    \tcontrols = new THREE.TrackballControls( camera );\n//      controls.target.z = 150;\n// Simple substitute \"OrbitControls\" and the control should work as-is.\nvar THREE = window.THREE;\nTHREE.OrbitControls = function ( object, domElement ) {\n\n\tthis.object = object;\n\tthis.domElement = ( domElement !== undefined ) ? domElement : document;\n\n\t// API\n\n\t// Set to false to disable this control\n\tthis.enabled = true;\n\n\t// \"target\" sets the location of focus, where the control orbits around\n\t// and where it pans with respect to.\n\tthis.target = new THREE.Vector3();\n\n\t// center is old, deprecated; use \"target\" instead\n\tthis.center = this.target;\n\n\t// This option actually enables dollying in and out; left as \"zoom\" for\n\t// backwards compatibility\n\tthis.noZoom = false;\n\tthis.zoomSpeed = 1.0;\n\n\t// Limits to how far you can dolly in and out\n\tthis.minDistance = 0;\n\tthis.maxDistance = Infinity;\n\n\t// Set to true to disable this control\n\tthis.noRotate = false;\n\tthis.rotateSpeed = 1.0;\n\n\t// Set to true to disable this control\n\tthis.noPan = false;\n\tthis.keyPanSpeed = 7.0;\t// pixels moved per arrow key push\n\n\t// Set to true to automatically rotate around the target\n\tthis.autoRotate = false;\n\tthis.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60\n\n\t// How far you can orbit vertically, upper and lower limits.\n\t// Range is 0 to Math.PI radians.\n\tthis.minPolarAngle = 0; // radians\n\tthis.maxPolarAngle = Math.PI; // radians\n\n\t// Set to true to disable use of the keys\n\tthis.noKeys = false;\n\n\t// The four arrow keys\n\tthis.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 };\n\n\t////////////\n\t// internals\n\n\tvar scope = this;\n\n\tvar EPS = 0.000001;\n\n\tvar rotateStart = new THREE.Vector2();\n\tvar rotateEnd = new THREE.Vector2();\n\tvar rotateDelta = new THREE.Vector2();\n\n\tvar panStart = new THREE.Vector2();\n\tvar panEnd = new THREE.Vector2();\n\tvar panDelta = new THREE.Vector2();\n\tvar panOffset = new THREE.Vector3();\n\n\tvar offset = new THREE.Vector3();\n\n\tvar dollyStart = new THREE.Vector2();\n\tvar dollyEnd = new THREE.Vector2();\n\tvar dollyDelta = new THREE.Vector2();\n\n\tvar phiDelta = 0;\n\tvar thetaDelta = 0;\n\tvar scale = 1;\n\tvar pan = new THREE.Vector3();\n\n\tvar lastPosition = new THREE.Vector3();\n\tvar lastQuaternion = new THREE.Quaternion();\n\n\tvar STATE = { NONE : -1, ROTATE : 0, DOLLY : 1, PAN : 2, TOUCH_ROTATE : 3, TOUCH_DOLLY : 4, TOUCH_PAN : 5 };\n\n\tvar state = STATE.NONE;\n\n\t// for reset\n\n\tthis.target0 = this.target.clone();\n\tthis.position0 = this.object.position.clone();\n\n\t// so camera.up is the orbit axis\n\n\tvar quat = new THREE.Quaternion().setFromUnitVectors( object.up, new THREE.Vector3( 0, 1, 0 ) );\n\tvar quatInverse = quat.clone().inverse();\n\n\t// events\n\n\tvar changeEvent = { type: 'change' };\n\tvar startEvent = { type: 'start'};\n\tvar endEvent = { type: 'end'};\n\n\tthis.rotateLeft = function ( angle ) {\n\n\t\tif ( angle === undefined ) {\n\n\t\t\tangle = getAutoRotationAngle();\n\n\t\t}\n\n\t\tthetaDelta -= angle;\n\n\t};\n\n\tthis.rotateUp = function ( angle ) {\n\n\t\tif ( angle === undefined ) {\n\n\t\t\tangle = getAutoRotationAngle();\n\n\t\t}\n\n\t\tphiDelta -= angle;\n\n\t};\n\n\t// pass in distance in world space to move left\n\tthis.panLeft = function ( distance ) {\n\n\t\tvar te = this.object.matrix.elements;\n\n\t\t// get X column of matrix\n\t\tpanOffset.set( te[ 0 ], te[ 1 ], te[ 2 ] );\n\t\tpanOffset.multiplyScalar( - distance );\n\t\t\n\t\tpan.add( panOffset );\n\n\t};\n\n\t// pass in distance in world space to move up\n\tthis.panUp = function ( distance ) {\n\n\t\tvar te = this.object.matrix.elements;\n\n\t\t// get Y column of matrix\n\t\tpanOffset.set( te[ 4 ], te[ 5 ], te[ 6 ] );\n\t\tpanOffset.multiplyScalar( distance );\n\t\t\n\t\tpan.add( panOffset );\n\n\t};\n\t\n\t// pass in x,y of change desired in pixel space,\n\t// right and down are positive\n\tthis.pan = function ( deltaX, deltaY ) {\n\n\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\tif ( scope.object.fov !== undefined ) {\n\n\t\t\t// perspective\n\t\t\tvar position = scope.object.position;\n\t\t\tvar offset = position.clone().sub( scope.target );\n\t\t\tvar targetDistance = offset.length();\n\n\t\t\t// half of the fov is center to top of screen\n\t\t\ttargetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 );\n\n\t\t\t// we actually don't use screenWidth, since perspective camera is fixed to screen height\n\t\t\tscope.panLeft( 2 * deltaX * targetDistance / element.clientHeight );\n\t\t\tscope.panUp( 2 * deltaY * targetDistance / element.clientHeight );\n\n\t\t} else if ( scope.object.top !== undefined ) {\n\n\t\t\t// orthographic\n\t\t\tscope.panLeft( deltaX * (scope.object.right - scope.object.left) / element.clientWidth );\n\t\t\tscope.panUp( deltaY * (scope.object.top - scope.object.bottom) / element.clientHeight );\n\n\t\t} else {\n\n\t\t\t// camera neither orthographic or perspective\n\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' );\n\n\t\t}\n\n\t};\n\n\tthis.dollyIn = function ( dollyScale ) {\n\n\t\tif ( dollyScale === undefined ) {\n\n\t\t\tdollyScale = getZoomScale();\n\n\t\t}\n\n\t\tscale /= dollyScale;\n\n\t};\n\n\tthis.dollyOut = function ( dollyScale ) {\n\n\t\tif ( dollyScale === undefined ) {\n\n\t\t\tdollyScale = getZoomScale();\n\n\t\t}\n\n\t\tscale *= dollyScale;\n\n\t};\n\n\tthis.update = function () {\n\n\t\tvar position = this.object.position;\n\n\t\toffset.copy( position ).sub( this.target );\n\n\t\t// rotate offset to \"y-axis-is-up\" space\n\t\toffset.applyQuaternion( quat );\n\n\t\t// angle from z-axis around y-axis\n\n\t\tvar theta = Math.atan2( offset.x, offset.z );\n\n\t\t// angle from y-axis\n\n\t\tvar phi = Math.atan2( Math.sqrt( offset.x * offset.x + offset.z * offset.z ), offset.y );\n\n\t\tif ( this.autoRotate ) {\n\n\t\t\tthis.rotateLeft( getAutoRotationAngle() );\n\n\t\t}\n\n\t\ttheta += thetaDelta;\n\t\tphi += phiDelta;\n\n\t\t// restrict phi to be between desired limits\n\t\tphi = Math.max( this.minPolarAngle, Math.min( this.maxPolarAngle, phi ) );\n\n\t\t// restrict phi to be betwee EPS and PI-EPS\n\t\tphi = Math.max( EPS, Math.min( Math.PI - EPS, phi ) );\n\n\t\tvar radius = offset.length() * scale;\n\n\t\t// restrict radius to be between desired limits\n\t\tradius = Math.max( this.minDistance, Math.min( this.maxDistance, radius ) );\n\t\t\n\t\t// move target to panned location\n\t\tthis.target.add( pan );\n\n\t\toffset.x = radius * Math.sin( phi ) * Math.sin( theta );\n\t\toffset.y = radius * Math.cos( phi );\n\t\toffset.z = radius * Math.sin( phi ) * Math.cos( theta );\n\n\t\t// rotate offset back to \"camera-up-vector-is-up\" space\n\t\toffset.applyQuaternion( quatInverse );\n\n\t\tposition.copy( this.target ).add( offset );\n\n\t\tthis.object.lookAt( this.target );\n\n\t\tthetaDelta = 0;\n\t\tphiDelta = 0;\n\t\tscale = 1;\n\t\tpan.set( 0, 0, 0 );\n\n\t\t// update condition is:\n\t\t// min(camera displacement, camera rotation in radians)^2 > EPS\n\t\t// using small-angle approximation cos(x/2) = 1 - x^2 / 8\n\n\t\tif ( lastPosition.distanceToSquared( this.object.position ) > EPS\n\t\t    || 8 * (1 - lastQuaternion.dot(this.object.quaternion)) > EPS ) {\n\n\t\t\tthis.dispatchEvent( changeEvent );\n\n\t\t\tlastPosition.copy( this.object.position );\n\t\t\tlastQuaternion.copy (this.object.quaternion );\n\n\t\t}\n\n\t};\n\n\n\tthis.reset = function () {\n\n\t\tstate = STATE.NONE;\n\n\t\tthis.target.copy( this.target0 );\n\t\tthis.object.position.copy( this.position0 );\n\n\t\tthis.update();\n\n\t};\n\n\tfunction getAutoRotationAngle() {\n\n\t\treturn 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;\n\n\t}\n\n\tfunction getZoomScale() {\n\n\t\treturn Math.pow( 0.95, scope.zoomSpeed );\n\n\t}\n\n\tfunction onMouseDown( event ) {\n\n\t\tif ( scope.enabled === false ) return;\n\t\tevent.preventDefault();\n\n\t\tif ( event.button === 0 ) {\n\t\t\tif ( scope.noRotate === true ) return;\n\n\t\t\tstate = STATE.ROTATE;\n\n\t\t\trotateStart.set( event.clientX, event.clientY );\n\n\t\t} else if ( event.button === 1 ) {\n\t\t\tif ( scope.noZoom === true ) return;\n\n\t\t\tstate = STATE.DOLLY;\n\n\t\t\tdollyStart.set( event.clientX, event.clientY );\n\n\t\t} else if ( event.button === 2 ) {\n\t\t\tif ( scope.noPan === true ) return;\n\n\t\t\tstate = STATE.PAN;\n\n\t\t\tpanStart.set( event.clientX, event.clientY );\n\n\t\t}\n\n\t\tdocument.addEventListener( 'mousemove', onMouseMove, false );\n\t\tdocument.addEventListener( 'mouseup', onMouseUp, false );\n\t\tscope.dispatchEvent( startEvent );\n\n\t}\n\n\tfunction onMouseMove( event ) {\n\n\t\tif ( scope.enabled === false ) return;\n\n\t\tevent.preventDefault();\n\n\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\tif ( state === STATE.ROTATE ) {\n\n\t\t\tif ( scope.noRotate === true ) return;\n\n\t\t\trotateEnd.set( event.clientX, event.clientY );\n\t\t\trotateDelta.subVectors( rotateEnd, rotateStart );\n\n\t\t\t// rotating across whole screen goes 360 degrees around\n\t\t\tscope.rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );\n\n\t\t\t// rotating up and down along whole screen attempts to go 360, but limited to 180\n\t\t\tscope.rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );\n\n\t\t\trotateStart.copy( rotateEnd );\n\n\t\t} else if ( state === STATE.DOLLY ) {\n\n\t\t\tif ( scope.noZoom === true ) return;\n\n\t\t\tdollyEnd.set( event.clientX, event.clientY );\n\t\t\tdollyDelta.subVectors( dollyEnd, dollyStart );\n\n\t\t\tif ( dollyDelta.y > 0 ) {\n\n\t\t\t\tscope.dollyIn();\n\n\t\t\t} else {\n\n\t\t\t\tscope.dollyOut();\n\n\t\t\t}\n\n\t\t\tdollyStart.copy( dollyEnd );\n\n\t\t} else if ( state === STATE.PAN ) {\n\n\t\t\tif ( scope.noPan === true ) return;\n\n\t\t\tpanEnd.set( event.clientX, event.clientY );\n\t\t\tpanDelta.subVectors( panEnd, panStart );\n\t\t\t\n\t\t\tscope.pan( panDelta.x, panDelta.y );\n\n\t\t\tpanStart.copy( panEnd );\n\n\t\t}\n\n\t\tscope.update();\n\n\t}\n\n\tfunction onMouseUp( /* event */ ) {\n\n\t\tif ( scope.enabled === false ) return;\n\n\t\tdocument.removeEventListener( 'mousemove', onMouseMove, false );\n\t\tdocument.removeEventListener( 'mouseup', onMouseUp, false );\n\t\tscope.dispatchEvent( endEvent );\n\t\tstate = STATE.NONE;\n\n\t}\n\n\tfunction onMouseWheel( event ) {\n\n\t\tif ( scope.enabled === false || scope.noZoom === true ) return;\n\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\n\t\tvar delta = 0;\n\n\t\tif ( event.wheelDelta !== undefined ) { // WebKit / Opera / Explorer 9\n\n\t\t\tdelta = event.wheelDelta;\n\n\t\t} else if ( event.detail !== undefined ) { // Firefox\n\n\t\t\tdelta = - event.detail;\n\n\t\t}\n\n\t\tif ( delta > 0 ) {\n\n\t\t\tscope.dollyOut();\n\n\t\t} else {\n\n\t\t\tscope.dollyIn();\n\n\t\t}\n\n\t\tscope.update();\n\t\tscope.dispatchEvent( startEvent );\n\t\tscope.dispatchEvent( endEvent );\n\n\t}\n\n\tfunction onKeyDown( event ) {\n\n\t\tif ( scope.enabled === false || scope.noKeys === true || scope.noPan === true ) return;\n\t\t\n\t\tswitch ( event.keyCode ) {\n\n\t\t\tcase scope.keys.UP:\n\t\t\t\tscope.pan( 0, scope.keyPanSpeed );\n\t\t\t\tscope.update();\n\t\t\t\tbreak;\n\n\t\t\tcase scope.keys.BOTTOM:\n\t\t\t\tscope.pan( 0, - scope.keyPanSpeed );\n\t\t\t\tscope.update();\n\t\t\t\tbreak;\n\n\t\t\tcase scope.keys.LEFT:\n\t\t\t\tscope.pan( scope.keyPanSpeed, 0 );\n\t\t\t\tscope.update();\n\t\t\t\tbreak;\n\n\t\t\tcase scope.keys.RIGHT:\n\t\t\t\tscope.pan( - scope.keyPanSpeed, 0 );\n\t\t\t\tscope.update();\n\t\t\t\tbreak;\n\n\t\t}\n\n\t}\n\n\tfunction touchstart( event ) {\n\n\t\tif ( scope.enabled === false ) return;\n\n\t\tswitch ( event.touches.length ) {\n\n\t\t\tcase 1:\t// one-fingered touch: rotate\n\n\t\t\t\tif ( scope.noRotate === true ) return;\n\n\t\t\t\tstate = STATE.TOUCH_ROTATE;\n\n\t\t\t\trotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\t\t\t\tbreak;\n\n\t\t\tcase 2:\t// two-fingered touch: dolly\n\n\t\t\t\tif ( scope.noZoom === true ) return;\n\n\t\t\t\tstate = STATE.TOUCH_DOLLY;\n\n\t\t\t\tvar dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;\n\t\t\t\tvar dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;\n\t\t\t\tvar distance = Math.sqrt( dx * dx + dy * dy );\n\t\t\t\tdollyStart.set( 0, distance );\n\t\t\t\tbreak;\n\n\t\t\tcase 3: // three-fingered touch: pan\n\n\t\t\t\tif ( scope.noPan === true ) return;\n\n\t\t\t\tstate = STATE.TOUCH_PAN;\n\n\t\t\t\tpanStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\n\t\t\t\tstate = STATE.NONE;\n\n\t\t}\n\n\t\tscope.dispatchEvent( startEvent );\n\n\t}\n\n\tfunction touchmove( event ) {\n\n\t\tif ( scope.enabled === false ) return;\n\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\n\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\tswitch ( event.touches.length ) {\n\n\t\t\tcase 1: // one-fingered touch: rotate\n\n\t\t\t\tif ( scope.noRotate === true ) return;\n\t\t\t\tif ( state !== STATE.TOUCH_ROTATE ) return;\n\n\t\t\t\trotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\t\t\t\trotateDelta.subVectors( rotateEnd, rotateStart );\n\n\t\t\t\t// rotating across whole screen goes 360 degrees around\n\t\t\t\tscope.rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );\n\t\t\t\t// rotating up and down along whole screen attempts to go 360, but limited to 180\n\t\t\t\tscope.rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );\n\n\t\t\t\trotateStart.copy( rotateEnd );\n\n\t\t\t\tscope.update();\n\t\t\t\tbreak;\n\n\t\t\tcase 2: // two-fingered touch: dolly\n\n\t\t\t\tif ( scope.noZoom === true ) return;\n\t\t\t\tif ( state !== STATE.TOUCH_DOLLY ) return;\n\n\t\t\t\tvar dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;\n\t\t\t\tvar dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;\n\t\t\t\tvar distance = Math.sqrt( dx * dx + dy * dy );\n\n\t\t\t\tdollyEnd.set( 0, distance );\n\t\t\t\tdollyDelta.subVectors( dollyEnd, dollyStart );\n\n\t\t\t\tif ( dollyDelta.y > 0 ) {\n\n\t\t\t\t\tscope.dollyOut();\n\n\t\t\t\t} else {\n\n\t\t\t\t\tscope.dollyIn();\n\n\t\t\t\t}\n\n\t\t\t\tdollyStart.copy( dollyEnd );\n\n\t\t\t\tscope.update();\n\t\t\t\tbreak;\n\n\t\t\tcase 3: // three-fingered touch: pan\n\n\t\t\t\tif ( scope.noPan === true ) return;\n\t\t\t\tif ( state !== STATE.TOUCH_PAN ) return;\n\n\t\t\t\tpanEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n\t\t\t\tpanDelta.subVectors( panEnd, panStart );\n\t\t\t\t\n\t\t\t\tscope.pan( panDelta.x, panDelta.y );\n\n\t\t\t\tpanStart.copy( panEnd );\n\n\t\t\t\tscope.update();\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\n\t\t\t\tstate = STATE.NONE;\n\n\t\t}\n\n\t}\n\n\tfunction touchend( /* event */ ) {\n\n\t\tif ( scope.enabled === false ) return;\n\n\t\tscope.dispatchEvent( endEvent );\n\t\tstate = STATE.NONE;\n\n\t}\n\n\tthis.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false );\n\tthis.domElement.addEventListener( 'mousedown', onMouseDown, false );\n\tthis.domElement.addEventListener( 'mousewheel', onMouseWheel, false );\n\tthis.domElement.addEventListener( 'DOMMouseScroll', onMouseWheel, false ); // firefox\n\n\tthis.domElement.addEventListener( 'touchstart', touchstart, false );\n\tthis.domElement.addEventListener( 'touchend', touchend, false );\n\tthis.domElement.addEventListener( 'touchmove', touchmove, false );\n\n\twindow.addEventListener( 'keydown', onKeyDown, false );\n\n\t// force an update at start\n\tthis.update();\n\n};\n\nTHREE.OrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype );\n","var THREE = window.THREE;\n\n/**\n * @module  model/Coordinates\n */\n\n/**\n * Coordinates helper, it creates the axes, ground and grids\n * shown in the world\n * @class\n * @param {Object} config\n * @param {Object} theme\n */\nfunction Coordinates(config, theme) {\n  config = config || {};\n\n  /**\n   * Group where all the objects (axes, ground, grids) are put\n   * @type {THREE.Object3D}\n   */\n  this.mesh = new THREE.Object3D();\n\n  /**\n   * Axes object, the mesh representing the axes is under this object \n   * under `mesh`\n   * @type {Object}\n   */\n  this.axes = {\n    name: 'Axes',\n    mesh: this.drawAllAxes({axisLength:100,axisRadius:1,axisTess:50}),\n    visible: config.axes !== undefined ? config.axes : true\n  };\n\n  /**\n   * Ground object, the mesh representing the axes is under this object\n   * under `mesh`\n   * @type {Object}\n   */\n  this.ground = {\n    name: 'Ground',\n    mesh: this.drawGround({size:100000, color: theme.groundColor}),\n    visible: config.ground !== undefined ? config.ground : true\n  };\n  \n  /**\n   * GridXZ object, the mesh representing the axes is under this object\n   * under `mesh`\n   * @type {Object}\n   */\n  this.gridX = {\n    name: 'XZ grid',\n    mesh: this.drawGrid({size:10000, scale:0.01, color: theme.gridColor}),\n    visible: config.gridX !== undefined ? config.gridX : true\n  };\n\n  /**\n   * GridYZ object, the mesh representing the axes is under this object\n   * under `mesh`\n   * @type {Object}\n   */  \n  this.gridY = {\n    name: 'YZ grid',\n    mesh: this.drawGrid({size:10000, scale:0.01, orientation:\"y\", color: theme.gridColor}),\n    visible: config.gridY !== undefined ? config.gridY : false\n  };\n  \n  /**\n   * GridXY object, the mesh representing the axes is under this object\n   * under `mesh`\n   * @type {Object}\n   */\n  this.gridZ = {\n    name: 'XY grid',\n    mesh: this.drawGrid({size:10000, scale:0.01, orientation:\"z\", color: theme.gridColor}),\n    visible: config.gridZ !== undefined ? config.gridZ : false\n  };\n\n  Coordinates.prototype.init.call(this, config);\n}\n\n/**\n * Adds the axes, ground, grid meshes to `this.mesh`\n * @param  {object} options\n * @return {this}\n */\nCoordinates.prototype.init = function (options) {\n  var me = this;\n  for (var key in me) {\n    if (me.hasOwnProperty(key)) {\n      var v = me[key];\n      if (v.mesh) {\n        me.mesh.add(v.mesh);\n        v.mesh.visible = v.visible;\n      }\n    }\n  }\n\n  return me;\n};\n\n/**\n * Creates a dat.gui folder which has controls for the \n * ground, axes and grids\n * @param  {dat.gui} gui\n * @return {this}\n */\nCoordinates.prototype.initDatGui = function (gui) {\n  var me = this,\n    folder;\n\n  folder = gui.addFolder('Scene helpers');\n  for (var key in me) {\n    if (me.hasOwnProperty(key)) {\n      var v = me[key];\n      if (v.hasOwnProperty('mesh')) {\n        folder.add(v, 'visible')\n          .name(v.name)\n          .onFinishChange((function (property) {\n            return function (newValue) {\n              property.mesh.visible = newValue;\n            };\n          })(v));\n      }\n    }\n  }\n  return me;\n};\n\n/**\n * Draws a grid\n * @param  {object} params\n * @param  {object} params.size=100\n * @param  {object} params.scale=0.1\n * @param  {object} params.color=#505050\n * @param  {object} params.orientation=0.1\n * @return {THREE.Mesh}\n */\nCoordinates.prototype.drawGrid = function (params) {\n  params = params || {};\n  var color = params.color !== undefined ? params.color:'#505050';\n  var orientation = params.orientation !== undefined ? params.orientation:\"x\";\n  var grid = new THREE.GridHelper( 500, 10 );\n  grid.setColors( 0xa8a8a8, color );\n  if (orientation === \"x\") {\n    grid.rotation.x = - Math.PI / 2;\n  } else if (orientation === \"y\") {\n    grid.rotation.y = - Math.PI / 2;\n  } else if (orientation === \"z\") {\n    grid.rotation.z = - Math.PI / 2;\n  }\n  return grid;\n};\n\n/**\n * Draws the ground\n * @param  {object} params\n * @param  {object} params.size=100\n * @param  {object} params.scale=0x000000\n * @param  {object} params.offset=-0.2\n * @return {THREE.Mesh}\n */\nCoordinates.prototype.drawGround = function (params) {\n  params = params || {};\n  var size = params.size !== undefined ? params.size:100;\n  var color = params.color !== undefined ? params.color:0x000000;\n  var offset = params.offset !== undefined ? params.offset:-0.5;\n\n  var ground = new THREE.Mesh(\n    new THREE.PlaneGeometry(size, size),\n    new THREE.MeshBasicMaterial({\n      transparent: true,\n      side: THREE.DoubleSide,\n      opacity: 0.6,\n      color: color\n    })\n  );\n  ground.rotation.x = - Math.PI / 2;\n  ground.position.y = offset;\n  return ground;\n};\n\n/**\n * Draws an axis\n * @param  {object} params\n * @param  {object} params.axisRadius=0.04\n * @param  {object} params.axisLength=11\n * @param  {object} params.axisTess=46\n * @param  {object} params.axisOrientation=x\n * @return {THREE.Mesh}\n */\nCoordinates.prototype.drawAxes = function (params) {\n  // x = red, y = green, z = blue  (RGB = xyz)\n  params = params || {};\n  var axisRadius = params.axisRadius !== undefined ? params.axisRadius:0.04;\n  var axisLength = params.axisLength !== undefined ? params.axisLength:11;\n  var axisTess = params.axisTess !== undefined ? params.axisTess:48;\n  var axisOrientation = params.axisOrientation !== undefined ? params.axisOrientation:\"x\";\n\n  var wrap = new THREE.Object3D();\n  var axisMaterial = new THREE.MeshLambertMaterial({ color: 0x000000, side: THREE.DoubleSide });\n  var axis = new THREE.Mesh(\n    new THREE.CylinderGeometry(axisRadius, axisRadius, axisLength, axisTess, 1, true), \n    axisMaterial\n  );\n  if (axisOrientation === \"x\") {\n    axis.rotation.z = - Math.PI / 2;\n    axis.position.x = axisLength/2-1;\n  } else if (axisOrientation === \"y\") {\n    axis.position.y = axisLength/2-1;\n  }\n  \n  wrap.add( axis );\n  \n  var arrow = new THREE.Mesh(\n    new THREE.CylinderGeometry(0, 4*axisRadius, 8*axisRadius, axisTess, 1, true), \n    axisMaterial\n  );\n  if (axisOrientation === \"x\") {\n    arrow.rotation.z = - Math.PI / 2;\n    arrow.position.x = axisLength - 1 + axisRadius*4/2;\n  } else if (axisOrientation === \"y\") {\n    arrow.position.y = axisLength - 1 + axisRadius*4/2;\n  }\n\n  wrap.add( arrow );\n  return wrap;\n};\n\n/**\n * Creates an Object3D which contains all axes\n * @param  {Object} params\n * @param  {object} params.axisRadius=0.04  cylinder radius\n * @param  {object} params.axisLength=11    cylinder length\n * @param  {object} params.axisTess=46      cylinder tesselation\n * @return {THREE.Object3D}\n */\nCoordinates.prototype.drawAllAxes = function (params) {\n  params = params || {};\n  var axisRadius = params.axisRadius !== undefined ? params.axisRadius:0.04;\n  var axisLength = params.axisLength !== undefined ? params.axisLength:10;\n  var axisTess = params.axisTess !== undefined ? params.axisTess:24;\n\n  var wrap = new THREE.Object3D();\n\n  var axisXMaterial = new THREE.MeshLambertMaterial({ color: 0xFF0000 });\n  var axisYMaterial = new THREE.MeshLambertMaterial({ color: 0x00FF00 });\n  var axisZMaterial = new THREE.MeshLambertMaterial({ color: 0x0000FF });\n  axisXMaterial.side = THREE.DoubleSide;\n  axisYMaterial.side = THREE.DoubleSide;\n  axisZMaterial.side = THREE.DoubleSide;\n  var axisX = new THREE.Mesh(\n    new THREE.CylinderGeometry(axisRadius, axisRadius, axisLength, axisTess, 1, true), \n    axisXMaterial\n  );\n  var axisY = new THREE.Mesh(\n    new THREE.CylinderGeometry(axisRadius, axisRadius, axisLength, axisTess, 1, true), \n    axisYMaterial\n  );\n  var axisZ = new THREE.Mesh(\n    new THREE.CylinderGeometry(axisRadius, axisRadius, axisLength, axisTess, 1, true), \n    axisZMaterial\n  );\n  axisX.rotation.z = - Math.PI / 2;\n  axisX.position.x = axisLength/2-1;\n\n  axisY.position.y = axisLength/2-1;\n  \n  axisZ.rotation.y = - Math.PI / 2;\n  axisZ.rotation.z = - Math.PI / 2;\n  axisZ.position.z = axisLength/2-1;\n\n  wrap.add( axisX );\n  wrap.add( axisY );\n  wrap.add( axisZ );\n\n  var arrowX = new THREE.Mesh(\n    new THREE.CylinderGeometry(0, 4*axisRadius, 4*axisRadius, axisTess, 1, true), \n    axisXMaterial\n  );\n  var arrowY = new THREE.Mesh(\n    new THREE.CylinderGeometry(0, 4*axisRadius, 4*axisRadius, axisTess, 1, true), \n    axisYMaterial\n  );\n  var arrowZ = new THREE.Mesh(\n    new THREE.CylinderGeometry(0, 4*axisRadius, 4*axisRadius, axisTess, 1, true), \n    axisZMaterial\n  );\n  arrowX.rotation.z = - Math.PI / 2;\n  arrowX.position.x = axisLength - 1 + axisRadius*4/2;\n\n  arrowY.position.y = axisLength - 1 + axisRadius*4/2;\n\n  arrowZ.rotation.z = - Math.PI / 2;\n  arrowZ.rotation.y = - Math.PI / 2;\n  arrowZ.position.z = axisLength - 1 + axisRadius*4/2;\n\n  wrap.add( arrowX );\n  wrap.add( arrowY );\n  wrap.add( arrowZ );\n  return wrap;\n};\n\nmodule.exports = Coordinates;","'use strict';\n\nvar assert = function (condition, message) {\n  if (!condition) {\n    throw message || 'assertion failed';\n  }\n};\n\nvar emptyFn = function () {};\nvar extend = require('extend');\nvar Stats = require('stats-js');\nvar dat = require('dat-gui');\nvar THREE = window.THREE;\n\nvar Coordinates = require('../model/Coordinates');\nvar Keyboard = require('./Keyboard');\nvar LoopManager = require('./LoopManager');\nvar THREEx = require('../lib/THREEx/');\n/**\n * @module controller/Application\n */\n\n/**\n * Each instance controls one element of the DOM, besides creating\n * the canvas for the three.js app it creates a dat.gui instance\n * (to control objects of the app with a gui) and a Stats instance\n * (to view the current framerate)\n *\n * @class\n * @param {Object} config An object containing the following:\n * @param {string} [config.id=null] The id of the DOM element to inject the elements to\n * @param {number} [config.width=window.innerWidth]\n * The width of the canvas\n * @param {number} [config.height=window.innerHeight]\n * The height of the canvas\n * @param {boolean} [config.renderImmediately=true]\n * False to disable the game loop when the application starts, if\n * you want to resume the loop call `application.loopManager.start()`\n * @param {boolean} [config.injectCache=false]\n * True to add a wrapper over `THREE.Object3D.prototype.add` and\n * `THREE.Object3D.prototype.remove` so that it catches the last element\n * and perform additional operations over it, with this mechanism\n * we allow the application to have an internal cache of the elements of\n * the application\n * @param {boolean} [config.fullScreen=false]\n * True to make this app fullscreen adding additional support for\n * window resize events\n * @param {string} [config.theme='dark']\n * Theme used in the default scene, it can be `light` or `dark`\n * @param {object} [config.ambientConfig={}]\n * Additional configuration for the ambient, see the class {@link\n * Coordinates}\n * @param {object} [config.defaultSceneConfig={}] Additional config\n * for the default scene created for this world\n */\nfunction Application(config) {\n  config = extend({\n    selector: null,\n    width: window.innerWidth,\n    height: window.innerHeight,\n    renderImmediately: true,\n    injectCache: false,\n    fullScreen: false,\n    theme: 'dark',\n    helpersConfig: {},\n    defaultSceneConfig: {\n      fog: true\n    }\n  }, config);\n\n  this.initialConfig = config;\n\n  /**\n   * Scenes in this world, each scene should be mapped with\n   * a unique id\n   * @type {Object}\n   */\n  this.scenes = {};\n\n  /**\n   * The active scene of this world\n   * @type {THREE.Scene}\n   */\n  this.activeScene = null;\n\n  /**\n   * Reference to the cameras used in this world\n   * @type {Array}\n   */\n  this.cameras = {};\n\n  /**\n   * The world can have many cameras, so the this is a reference to\n   * the active camera that's being used right now\n   * @type {T3.model.Camera}\n   */\n  this.activeCamera = null;\n\n  /**\n   * THREE Renderer\n   * @type {Object}\n   */\n  this.renderer = null;\n\n  /**\n   * Keyboard manager\n   * @type {Object}\n   */\n  this.keyboard = null;\n\n  /**\n   * Dat gui manager\n   * @type {Object}\n   */\n  this.datgui = null;\n\n  /**\n   * Reference to the Stats instance (needed to call update\n   * on the method {@link module:controller/Application#update})\n   * @type {Object}\n   */\n  this.stats = null;\n\n  /**\n   * Reference to the local loop manager\n   * @type {LoopManager}\n   */\n  this.loopManager = null;\n\n  /**\n   * Colors for the default scene\n   * @type {Object}\n   */\n  this.theme = null;\n\n  /**\n   * Application cache\n   * @type {Object}\n   */\n  this.__t3cache__ = {};\n\n  Application.prototype.initApplication.call(this);\n}\n\n/**\n * Getter for the initial config\n * @return {Object}\n */\nApplication.prototype.getConfig = function () {\n  return this.initialConfig;\n};\n\n/**\n * Bootstrap the application with the following steps:\n *\n * - Enabling cache injection\n * - Set the theme\n * - Create the renderer, default scene, default camera, some random lights\n * - Initializes dat.gui, Stats, a mask when the application is paised\n * - Initializes fullScreen events, keyboard and some helper objects\n * - Calls the game loop\n *\n */\nApplication.prototype.initApplication = function () {\n  var me = this,\n    config = me.getConfig();\n\n  me.injectCache(config.injectCache);\n\n  // theme\n  me.setTheme(config.theme);\n\n  // defaults\n  me.createDefaultRenderer();\n  me.createDefaultScene();\n  me.createDefaultCamera();\n  me.createDefaultLights();\n\n  // utils\n  me.initDatGui();\n  me.initStats();\n  me.initMask()\n    .maskVisible(!config.renderImmediately);\n  me.initFullScreen();\n  me.initKeyboard();\n  me.initCoordinates();\n\n  // game loop\n  me.gameLoop();\n};\n\n/**\n * Sets the active scene (it must be a registered scene registered\n * with {@link #addScene})\n * @param {string} key The string which was used to register the scene\n * @return {this}\n */\nApplication.prototype.setActiveScene = function (key) {\n  this.activeScene = this.scenes[key];\n  return this;\n};\n\n/**\n * Adds a scene to the scene pool\n * @param {THREE.Scene} scene\n * @param {string} key\n * @return {this}\n */\nApplication.prototype.addScene = function (scene, key) {\n  console.assert(scene instanceof THREE.Scene);\n  this.scenes[key] = scene;\n  return this;\n};\n\n/**\n * Creates a scene called 'default' and sets it as the active one\n * @return {this}\n */\nApplication.prototype.createDefaultScene = function () {\n  var me = this,\n    config = me.getConfig(),\n    defaultScene = new THREE.Scene();\n  if (config.defaultSceneConfig.fog) {\n    defaultScene.fog = new THREE.Fog(me.theme.fogColor, 2000, 4000);\n  }\n  me\n    .addScene(defaultScene, 'default')\n    .setActiveScene('default');\n  return me;\n};\n\n/**\n * Creates the default THREE.WebGLRenderer used in the world\n * @return {this}\n */\nApplication.prototype.createDefaultRenderer = function () {\n  var me = this,\n    config = me.getConfig();\n  var renderer = new THREE.WebGLRenderer({\n//      antialias: true\n  });\n  renderer.setClearColor(me.theme.clearColor, 1);\n  renderer.setSize(config.width, config.height);\n  document\n    .querySelector(config.selector)\n    .appendChild(renderer.domElement);\n  me.renderer = renderer;\n  return me;\n};\n\nApplication.prototype.setActiveCamera = function (key) {\n  this.activeCamera = this.cameras[key];\n  return this;\n};\n\nApplication.prototype.addCamera = function (camera, key) {\n  console.assert(camera instanceof THREE.PerspectiveCamera ||\n    camera instanceof THREE.OrthographicCamera);\n  this.cameras[key] = camera;\n  return this;\n};\n\n/**\n * Create the default camera used in this world which is\n * a `THREE.PerspectiveCamera`, it also adds orbit controls\n * by calling {@link #createCameraControls}\n */\nApplication.prototype.createDefaultCamera = function () {\n  var me = this,\n    config = me.getConfig(),\n    width = config.width,\n    height = config.height,\n    defaults = {\n      fov: 38,\n      ratio: width / height,\n      near: 1,\n      far: 10000\n    },\n    defaultCamera;\n\n  defaultCamera = new THREE.PerspectiveCamera(\n    defaults.fov,\n    defaults.ratio,\n    defaults.near,\n    defaults.far\n  );\n  defaultCamera.position.set(500, 300, 500);\n\n  // transparently support window resize\n  if (config.fullScreen) {\n    THREEx.WindowResize.bind(me.renderer, defaultCamera);\n  }\n\n  me\n    .createCameraControls(defaultCamera)\n    .addCamera(defaultCamera, 'default')\n    .setActiveCamera('default');\n\n  return me;\n};\n\n/**\n * Creates OrbitControls over the `camera` passed as param\n * @param  {THREE.PerspectiveCamera|THREE.OrtographicCamera} camera\n * @return {this}\n */\nApplication.prototype.createCameraControls = function (camera) {\n  var me = this;\n  camera.cameraControls = new THREE.OrbitControls(\n    camera,\n    me.renderer.domElement\n  );\n  // avoid panning to see the bottom face\n  //camera.cameraControls.maxPolarAngle = Math.PI / 2 * 0.99;\n  //camera.cameraControls.target.set(100, 100, 100);\n  camera.cameraControls.target.set(0, 0, 0);\n  return me;\n};\n\n/**\n * Creates some random lights in the default scene\n * @return {this}\n */\nApplication.prototype.createDefaultLights = function () {\n  var light,\n      scene = this.scenes['default'];\n\n  light = new THREE.AmbientLight(0x222222);\n  scene.add(light).cache('ambient-light-1');\n\n  light = new THREE.DirectionalLight( 0xFFFFFF, 1.0 );\n  light.position.set( 200, 400, 500 );\n  scene.add(light).cache('directional-light-1');\n\n  light = new THREE.DirectionalLight( 0xFFFFFF, 1.0 );\n  light.position.set( -500, 250, -200 );\n  scene.add(light).cache('directional-light-2');\n\n  return this;\n};\n\n/**\n * Sets the theme to be used in the default scene\n * @param {string} name Either the string `dark` or `light`\n * @todo Make the theme system extensible\n * @return {this}\n */\nApplication.prototype.setTheme = function (name) {\n  var me = this,\n    themes = require('../').themes;\n  assert(themes[name]);\n  me.theme = themes[name];\n  return me;\n};\n\n/**\n * Creates a mask on top of the canvas when it's paused\n * @return {this}\n */\nApplication.prototype.initMask = function () {\n  var me = this,\n    config = me.getConfig(),\n    mask,\n    hidden;\n  mask = document.createElement('div');\n  mask.className = 't3-mask';\n  // mask.style.display = 'none';\n  mask.style.position = 'absolute';\n  mask.style.top = '0px';\n  mask.style.width = '100%';\n  mask.style.height = '100%';\n  mask.style.background = 'rgba(0,0,0,0.5)';\n\n  document\n    .querySelector(config.selector)\n    .appendChild(mask);\n\n  me.mask = mask;\n  return me;\n};\n\n/**\n * Updates the mask visibility\n * @param  {boolean} v True to make it visible\n */\nApplication.prototype.maskVisible = function (v) {\n  var mask = this.mask;\n  mask.style.display = v ? 'block' : 'none';\n};\n\n/**\n * Inits the dat.gui helper which is placed under the\n * DOM element identified by the initial configuration selector\n * @return {this}\n */\nApplication.prototype.initDatGui = function () {\n  var me = this,\n    config = me.getConfig(),\n    gui = new dat.GUI({\n      autoPlace: false\n    });\n\n  extend(gui.domElement.style, {\n    position: 'absolute',\n    top: '0px',\n    right: '0px',\n    zIndex: '1'\n  });\n  document\n    .querySelector(config.selector)\n    .appendChild(gui.domElement);\n  me.datgui = gui;\n  return me;\n};\n\n/**\n * Init the Stats helper which is placed under the\n * DOM element identified by the initial configuration selector\n * @return {this}\n */\nApplication.prototype.initStats = function () {\n  var me = this,\n    config = me.getConfig(),\n    stats;\n  // add Stats.js - https://github.com/mrdoob/stats.js\n  stats = new Stats();\n  extend(stats.domElement.style, {\n    position: 'absolute',\n    zIndex: 1,\n    bottom: '0px'\n  });\n  document\n    .querySelector(config.selector)\n    .appendChild( stats.domElement );\n  me.stats = stats;\n  return me;\n};\n\n/**\n * Binds the F key to make a world go full screen\n * @todo This should be used only when the canvas is active\n */\nApplication.prototype.initFullScreen = function () {\n  var config = this.getConfig();\n  // allow 'f' to go fullscreen where this feature is supported\n  if(config.fullScreen && THREEx.FullScreen.available()) {\n    THREEx.FullScreen.bindKey();\n  }\n};\n\n/**\n * Initializes the coordinate helper (its wrapped in a model in T3)\n */\nApplication.prototype.initCoordinates = function () {\n  var config = this.getConfig();\n  this.scenes['default']\n    .add(\n      new Coordinates(config.helpersConfig, this.theme)\n        .initDatGui(this.datgui)\n        .mesh\n    );\n};\n\n/**\n * Initis the keyboard helper\n * @return {this}\n */\nApplication.prototype.initKeyboard = function () {\n  this.keyboard = new Keyboard();\n  return this;\n};\n\n/**\n * Initializes the game loop by creating an instance of {@link LoopManager}\n * @return {this}\n */\nApplication.prototype.gameLoop = function () {\n  var config = this.getConfig();\n  this.loopManager = new LoopManager(this, config.renderImmediately)\n    .initDatGui(this.datgui)\n    .animate();\n  return this;\n};\n\n/**\n * Update phase, the world updates by default:\n *\n * - The stats helper\n * - The camera controls if the active camera has one\n *\n * @param {number} delta The number of seconds elapsed\n */\nApplication.prototype.update = function (delta) {\n  var me = this;\n\n  // stats helper\n  me.stats.update();\n\n  // camera update\n  if (me.activeCamera.cameraControls) {\n    me.activeCamera.cameraControls.update(delta);\n  }\n};\n\n/**\n * Render phase, calls `this.renderer` with `this.activeScene` and\n * `this.activeCamera`\n */\nApplication.prototype.render = function () {\n  var me = this;\n  me.renderer.render(\n    me.activeScene,\n    me.activeCamera\n  );\n};\n\n/**\n * Wraps `THREE.Object3D.prototype.add` and `THREE.Object3D.prototype.remove`\n * with functions that save the last object which `add` or `remove` have been\n * called with, this allows to call the method `cache` which will cache\n * the object with an identifier allowing fast object retrieval\n *\n * @example\n *\n *   var instance = t3.Application.run({\n *     injectCache: true,\n *     init: function () {\n *       var group = new THREE.Object3D();\n *       var innerGroup = new THREE.Object3D();\n *\n *       var geometry = new THREE.BoxGeometry(1,1,1);\n *       var material = new THREE.MeshBasicMaterial({color: 0x00ff00});\n *       var cube = new THREE.Mesh(geometry, material);\n *\n *       innerGroup\n *         .add(cube)\n *         .cache('myCube');\n *\n *       group\n *         .add(innerGroup)\n *         .cache('innerGroup');\n *\n *       // removal example\n *       // group\n *       //   .remove(innerGroup)\n *       //   .cache();\n *\n *       this.activeScene\n *         .add(group)\n *         .cache('group');\n *     },\n *\n *     update: function (delta) {\n *       var cube = this.getFromCache('myCube');\n *       // perform operations on the cube\n *     }\n *   });\n *\n * @param  {boolean} inject True to enable this behavior\n */\nApplication.prototype.injectCache = function (inject) {\n  var me = this,\n      lastObject,\n      lastMethod,\n      add = THREE.Object3D.prototype.add,\n      remove = THREE.Object3D.prototype.remove,\n      cache = this.__t3cache__;\n\n  if (inject) {\n    THREE.Object3D.prototype.add = function (object) {\n      lastMethod = 'add';\n      lastObject = object;\n      return add.apply(this, arguments);\n    };\n\n    THREE.Object3D.prototype.remove = function (object) {\n      lastMethod = 'remove';\n      lastObject = object;\n      return remove.apply(this, arguments);\n    };\n\n    THREE.Object3D.prototype.cache = function (name) {\n      assert(lastObject, 'T3.Application.prototype.cache: this method' +\n        ' needs a previous call to add/remove');\n      if (lastMethod === 'add') {\n        lastObject.name = lastObject.name || name;\n        assert(lastObject.name);\n        cache[lastObject.name] = lastObject;\n      } else {\n        assert(lastObject.name);\n        delete cache[lastObject.name];\n      }\n      lastObject = null;\n      return me;\n    };\n  } else {\n    THREE.Object3D.prototype.cache = function () {\n      return this;\n    };\n  }\n};\n\n/**\n * Gets an object from the cache if `injectCache` was enabled and\n * an object was registered with {@link #cache}\n * @param  {string} name\n * @return {THREE.Object3D}\n */\nApplication.prototype.getFromCache = function (name) {\n  return this.__t3cache__[name];\n};\n\n/**\n * @static\n * Creates a subclass of Application whose instances don't need to\n * worry about the inheritance process\n * @param  {Object} options The same object passed to the {@link Application}\n * constructor\n * @param {Object} options.init Initialization phase, function called in\n * the constructor of the subclass\n * @param {Object} options.update Update phase, function called as the\n * update function of the subclass, it also calls Application's update\n * @return {t3.QuickLaunch} An instance of the subclass created in\n * this function\n */\nApplication.run = function (options) {\n  options.init = options.init || emptyFn;\n  options.update = options.update || emptyFn;\n  assert(options.selector, 'canvas selector required');\n\n  var QuickLaunch = function (options) {\n    Application.call(this, options);\n    options.init.call(this, options);\n  };\n  QuickLaunch.prototype = Object.create(Application.prototype);\n\n  QuickLaunch.prototype.update = function (delta) {\n    Application.prototype.update.call(this, delta);\n    options.update.call(this, delta);\n  };\n\n  return new QuickLaunch(options);\n};\n\nmodule.exports = Application;","/**\n * @module  themes/dark\n */\n\n/**\n * Dark theme\n * @type {Object}\n */\nmodule.exports = {\n\tclearColor: 0x3f3f3f,\n\tfogColor: 0x3f3f3f,\n  groundColor: 0x333333,\n  gridColor: 0x555555\n};","/**\n * @module themes/light\n */\n\n/**\n * Light theme\n * @name LightTheme\n * @type {Object}\n */\nmodule.exports = {\n\tclearColor: 0xf2fcff,\n  fogColor: 0xf2fcff,\n\tgroundColor: 0xeeeeee\n};","/**\n * @module  controller/Keyboard\n */\n\n/**\n * Keyboard helper\n * @class\n */\nfunction Keyboard() {\n  /**\n   * Each index correspond to the ascii value of the\n   * key pressed\n   * @type {Array}\n   */\n  this.keys = [];\n}\n\n/**\n * Adds the keydown and keyup listeners\n */\nKeyboard.prototype.init = function () {\n  var me = this,\n    i;\n  for (i = 0; i < 256; i += 1) {\n    me.keys[i] = false;\n  }\n  document.addEventListener('keydown', me.onKeyDown(), false);\n  document.addEventListener('keyup', me.onKeyUp(), false);\n};\n\n/**\n * Sets `event.keycode` as a preseed key\n * @return {function}\n */\nKeyboard.prototype.onKeyDown = function () {\n  var me = this;\n  return function (event) {\n    me.keys[event.keyCode] = true;\n  };\n};\n\n/**\n * Sets `event.keycode` as an unpressed key\n * @return {function}\n */\nKeyboard.prototype.onKeyUp = function () {\n  var me = this;\n  return function (event) {\n    me.keys[event.keyCode] = false;\n  };\n};\n\n/**\n * Gets the pressed state of the key `key`\n * @param  {string} key\n * @return {boolean}\n */\nKeyboard.prototype.get = function (key) {\n  return this.keys[key.charCodeAt(0)];\n};\n\n/**\n * Sets the pressed state of the key `key` to `value`\n * @param {string} key\n * @param {boolean} value\n */\nKeyboard.prototype.set = function (key, value) {\n  this.keys[key.charCodeAt(0)] = value;\n};\n\nmodule.exports = Keyboard;","var Application = require('./Application');\nvar THREE = window.THREE;\n\n/**\n * @module  controller/LoopManager\n */\n\n/**\n * The loop managers controls the calls made to `requestAnimationFrame`\n * of an Application\n * @class\n * @param {controller/LoopManager} application Applicaton whose frame rate\n * will be controlled\n * @param {boolean} renderImmediately True to start the call\n * to request animation frame immediately\n */\nfunction LoopManager(application, renderImmediately) {\n  /**\n   * Reference to the application\n   * @type {controller/Application}\n   */\n  this.application = application;\n  /**\n   * Clock helper (its delta method is used to update the camera)\n   * @type {THREE.Clock()}\n   */\n  this.clock = new THREE.Clock();\n  /**\n   * Toggle to pause the animation\n   * @type {boolean}\n   */\n  this.pause = !renderImmediately;\n  /**\n   * Frames per second\n   * @type {number}\n   */\n  this.fps = 60;\n\n  /**\n   * dat.gui folder objects\n   * @type {Object}\n   */\n  this.guiControllers = {};\n};\n\n/**\n * Initializes a folder to control the frame rate and sets\n * the paused state of the app\n * @param  {dat.gui} gui\n * @return {this}\n */\nLoopManager.prototype.initDatGui = function (gui) {\n  var me = this,\n      folder = gui.addFolder('Game Loop');\n  folder\n    .add(this, 'fps', 10, 60, 1)\n    .name('Frame rate');\n  \n  me.guiControllers.pause = folder\n    .add(this, 'pause')\n    .name('Paused')\n    .onFinishChange(function (paused) {\n      if (!paused) {\n        me.animate();\n      }\n      me.application.maskVisible(paused);\n    });\n  return this;\n};\n\n/**\n * Animation loop (calls application.update and application.render)\n * @return {this}\n */\nLoopManager.prototype.animate = function () {\n  var me = this,\n    elapsedTime = 0,\n    loop;\n\n  loop = function () {\n    if (me.pause) {\n      return;\n    }\n\n    var delta = me.clock.getDelta(),\n      frameRateInS = 1 / me.fps;\n\n    // constraint delta to be <= frameRate\n    // (to avoid frames with a big delta caused because of the app sent to sleep)\n    delta = Math.min(delta, frameRateInS);\n    elapsedTime += delta;\n\n    if (elapsedTime >= frameRateInS) {\n\n      // update the world and render its objects\n      me.application.update(delta);\n      me.application.render();\n\n      elapsedTime -= frameRateInS;\n    }\n\n    // details at http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating\n    window.requestAnimationFrame(loop);\n  };\n\n  loop();\n\n  return me;\n};\n\n/**\n * Starts the animation\n */\nLoopManager.prototype.start = function () {\n  var me = this;\n  me.guiControllers.pause.setValue(false);\n};\n\n/**\n * Stops the animation\n */\nLoopManager.prototype.stop = function () {\n  var me = this;\n  me.guiControllers.pause.setValue(true);\n};\n\nmodule.exports = LoopManager;","/**\n * @name THREEx\n * three.js extensions\n * @type {Object}\n */\nmodule.exports = {\n  WindowResize: require('./WindowResize'),\n  FullScreen: require('./FullScreen')\n};","/**\n * @module  lib/THREEx/FullScreen\n */\n\n/**\n* This helper makes it easy to handle the fullscreen API:\n* \n* - it hides the prefix for each browser\n* - it hides the little discrepencies of the various vendor API\n* - at the time of this writing (nov 2011) it is available in \n* \n*   [firefox nightly](http://blog.pearce.org.nz/2011/11/firefoxs-html-full-screen-api-enabled.html),\n*   [webkit nightly](http://peter.sh/2011/01/javascript-full-screen-api-navigation-timing-and-repeating-css-gradients/) and\n*   [chrome stable](http://updates.html5rocks.com/2011/10/Let-Your-Content-Do-the-Talking-Fullscreen-API).\n* \n* @namespace\n*/\nvar fullScreen = {};\n\n/**\n * test if it is possible to have fullscreen\n * @returns {boolean} true if fullscreen API is available, false otherwise\n */\nfullScreen.available = function () {\n  return this._hasWebkitFullScreen || this._hasMozFullScreen;\n};\n\n/**\n * Test if fullscreen is currently activated\n * @returns {boolean} true if fullscreen is currently activated, false otherwise\n */\nfullScreen.activated = function () {\n  if (this._hasWebkitFullScreen) {\n    return document.webkitIsFullScreen;\n  } else if (this._hasMozFullScreen) {\n    return document.mozFullScreen;\n  } else {\n    console.assert(false);\n  }\n};\n\n/**\n * Request fullscreen on a given element\n * @param {DomElement} element to make fullscreen. optional. default to document.body\n */\nfullScreen.request = function (element) {\n  element = element || document.body;\n  if (this._hasWebkitFullScreen) {\n    element.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT);\n  } else if (this._hasMozFullScreen) {\n    element.mozRequestFullScreen();\n  } else {\n    console.assert(false);\n  }\n};\n\n/**\n * Cancel fullscreen\n */\nfullScreen.cancel = function () {\n  if (this._hasWebkitFullScreen) {\n    document.webkitCancelFullScreen();\n  } else if (this._hasMozFullScreen) {\n    document.mozCancelFullScreen();\n  } else {\n    console.assert(false);\n  }\n};\n\n\n// internal functions to know which fullscreen API implementation is available\nfullScreen._hasWebkitFullScreen = 'webkitCancelFullScreen' in document ? true : false;\nfullScreen._hasMozFullScreen = 'mozCancelFullScreen' in document ? true : false;\n\n/**\n * Bind a key to renderer screenshot\n * @param {Object} opts\n * @param {Object} [opts.charcode=f]\n * @param {Object} [opts.dblClick=false] True to make it go\n * fullscreen on double click\n */\nfullScreen.bindKey = function (opts) {\n  opts = opts || {};\n  var charCode = opts.charCode || 'f'.charCodeAt(0);\n  var dblclick = opts.dblclick !== undefined ? opts.dblclick : false;\n  var element = opts.element;\n\n  var toggle = function () {\n    if (fullScreen.activated()) {\n      fullScreen.cancel();\n    } else {\n      fullScreen.request(element);\n    }\n  };\n\n  // callback to handle keypress\n  var __bind = function (fn, me) {\n    return function () {\n      return fn.apply(me, arguments);\n    };\n  };\n  var onKeyPress = __bind(function (event) {\n    // return now if the KeyPress isnt for the proper charCode\n    if (event.which !== charCode) { return; }\n    // toggle fullscreen\n    toggle();\n  }, this);\n\n  // listen to keypress\n  // NOTE: for firefox it seems mandatory to listen to document directly\n  document.addEventListener('keypress', onKeyPress, false);\n  // listen to dblclick\n  dblclick && document.addEventListener('dblclick', toggle, false);\n\n  return {\n    unbind: function () {\n      document.removeEventListener('keypress', onKeyPress, false);\n      dblclick && document.removeEventListener('dblclick', toggle, false);\n    }\n  };\n};\n\nmodule.exports = fullScreen;","/**\n * @module  lib/THREEx/WindowResize\n */\n\n/**\n * This helper makes it easy to handle window resize.\n * It will update renderer and camera when window is resized.\n *\n * @example\n * // Start updating renderer and camera\n * var windowResize = WindowResize(aRenderer, aCamera);\n * //Start updating renderer and camera\n * windowResize.stop()\n *\n * @namespace\n * @param {Object} renderer the renderer to update\n * @param {Object} Camera the camera to update\n */\nvar windowResize = function (renderer, camera) {\n\tvar callback = function() {\n\t\t// notify the renderer of the size change\n\t\trenderer.setSize( window.innerWidth, window.innerHeight );\n\t\t// update the camera\n\t\tcamera.aspect\t= window.innerWidth / window.innerHeight;\n\t\tcamera.updateProjectionMatrix();\n\t};\n\t// bind the resize event\n\twindow.addEventListener('resize', callback, false);\n\t// return .stop() the function to stop watching window resize\n\treturn {\n\t\tstop\t: function(){\n\t\t\twindow.removeEventListener('resize', callback);\n\t\t}\n\t};\n};\n\n/**\n * @static\n * @param  {THREE.WebGLRenderer} renderer\n * @param  {THREE.PerspectiveCamera} camera\n * @return {Object}\n */\nwindowResize.bind\t= function(renderer, camera){\n\treturn windowResize(renderer, camera);\n};\n\nmodule.exports = windowResize;","var hasOwn = Object.prototype.hasOwnProperty;\nvar toString = Object.prototype.toString;\nvar undefined;\n\nvar isPlainObject = function isPlainObject(obj) {\n\t'use strict';\n\tif (!obj || toString.call(obj) !== '[object Object]') {\n\t\treturn false;\n\t}\n\n\tvar has_own_constructor = hasOwn.call(obj, 'constructor');\n\tvar has_is_property_of_method = obj.constructor && obj.constructor.prototype && hasOwn.call(obj.constructor.prototype, 'isPrototypeOf');\n\t// Not own constructor property must be Object\n\tif (obj.constructor && !has_own_constructor && !has_is_property_of_method) {\n\t\treturn false;\n\t}\n\n\t// Own properties are enumerated firstly, so to speed up,\n\t// if last one is own, then all properties are own.\n\tvar key;\n\tfor (key in obj) {}\n\n\treturn key === undefined || hasOwn.call(obj, key);\n};\n\nmodule.exports = function extend() {\n\t'use strict';\n\tvar options, name, src, copy, copyIsArray, clone,\n\t\ttarget = arguments[0],\n\t\ti = 1,\n\t\tlength = arguments.length,\n\t\tdeep = false;\n\n\t// Handle a deep copy situation\n\tif (typeof target === 'boolean') {\n\t\tdeep = target;\n\t\ttarget = arguments[1] || {};\n\t\t// skip the boolean and the target\n\t\ti = 2;\n\t} else if ((typeof target !== 'object' && typeof target !== 'function') || target == null) {\n\t\ttarget = {};\n\t}\n\n\tfor (; i < length; ++i) {\n\t\toptions = arguments[i];\n\t\t// Only deal with non-null/undefined values\n\t\tif (options != null) {\n\t\t\t// Extend the base object\n\t\t\tfor (name in options) {\n\t\t\t\tsrc = target[name];\n\t\t\t\tcopy = options[name];\n\n\t\t\t\t// Prevent never-ending loop\n\t\t\t\tif (target === copy) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Recurse if we're merging plain objects or arrays\n\t\t\t\tif (deep && copy && (isPlainObject(copy) || (copyIsArray = Array.isArray(copy)))) {\n\t\t\t\t\tif (copyIsArray) {\n\t\t\t\t\t\tcopyIsArray = false;\n\t\t\t\t\t\tclone = src && Array.isArray(src) ? src : [];\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclone = src && isPlainObject(src) ? src : {};\n\t\t\t\t\t}\n\n\t\t\t\t\t// Never move original objects, clone them\n\t\t\t\t\ttarget[name] = extend(deep, clone, copy);\n\n\t\t\t\t// Don't bring in undefined values\n\t\t\t\t} else if (copy !== undefined) {\n\t\t\t\t\ttarget[name] = copy;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return the modified object\n\treturn target;\n};\n\n","// stats.js - http://github.com/mrdoob/stats.js\nvar Stats=function(){var l=Date.now(),m=l,g=0,n=Infinity,o=0,h=0,p=Infinity,q=0,r=0,s=0,f=document.createElement(\"div\");f.id=\"stats\";f.addEventListener(\"mousedown\",function(b){b.preventDefault();t(++s%2)},!1);f.style.cssText=\"width:80px;opacity:0.9;cursor:pointer\";var a=document.createElement(\"div\");a.id=\"fps\";a.style.cssText=\"padding:0 0 3px 3px;text-align:left;background-color:#002\";f.appendChild(a);var i=document.createElement(\"div\");i.id=\"fpsText\";i.style.cssText=\"color:#0ff;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px\";\ni.innerHTML=\"FPS\";a.appendChild(i);var c=document.createElement(\"div\");c.id=\"fpsGraph\";c.style.cssText=\"position:relative;width:74px;height:30px;background-color:#0ff\";for(a.appendChild(c);74>c.children.length;){var j=document.createElement(\"span\");j.style.cssText=\"width:1px;height:30px;float:left;background-color:#113\";c.appendChild(j)}var d=document.createElement(\"div\");d.id=\"ms\";d.style.cssText=\"padding:0 0 3px 3px;text-align:left;background-color:#020;display:none\";f.appendChild(d);var k=document.createElement(\"div\");\nk.id=\"msText\";k.style.cssText=\"color:#0f0;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px\";k.innerHTML=\"MS\";d.appendChild(k);var e=document.createElement(\"div\");e.id=\"msGraph\";e.style.cssText=\"position:relative;width:74px;height:30px;background-color:#0f0\";for(d.appendChild(e);74>e.children.length;)j=document.createElement(\"span\"),j.style.cssText=\"width:1px;height:30px;float:left;background-color:#131\",e.appendChild(j);var t=function(b){s=b;switch(s){case 0:a.style.display=\n\"block\";d.style.display=\"none\";break;case 1:a.style.display=\"none\",d.style.display=\"block\"}};return{REVISION:12,domElement:f,setMode:t,begin:function(){l=Date.now()},end:function(){var b=Date.now();g=b-l;n=Math.min(n,g);o=Math.max(o,g);k.textContent=g+\" MS (\"+n+\"-\"+o+\")\";var a=Math.min(30,30-30*(g/200));e.appendChild(e.firstChild).style.height=a+\"px\";r++;b>m+1E3&&(h=Math.round(1E3*r/(b-m)),p=Math.min(p,h),q=Math.max(q,h),i.textContent=h+\" FPS (\"+p+\"-\"+q+\")\",a=Math.min(30,30-30*(h/100)),c.appendChild(c.firstChild).style.height=\na+\"px\",m=b,r=0);return b},update:function(){l=this.end()}}};\"object\"===typeof module&&(module.exports=Stats);\n","module.exports = require('./vendor/dat.gui')\nmodule.exports.color = require('./vendor/dat.color')","/**\n * dat-gui JavaScript Controller Library\n * http://code.google.com/p/dat-gui\n *\n * Copyright 2011 Data Arts Team, Google Creative Lab\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\n/** @namespace */\nvar dat = module.exports = dat || {};\n\n/** @namespace */\ndat.color = dat.color || {};\n\n/** @namespace */\ndat.utils = dat.utils || {};\n\ndat.utils.common = (function () {\n  \n  var ARR_EACH = Array.prototype.forEach;\n  var ARR_SLICE = Array.prototype.slice;\n\n  /**\n   * Band-aid methods for things that should be a lot easier in JavaScript.\n   * Implementation and structure inspired by underscore.js\n   * http://documentcloud.github.com/underscore/\n   */\n\n  return { \n    \n    BREAK: {},\n  \n    extend: function(target) {\n      \n      this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n        \n        for (var key in obj)\n          if (!this.isUndefined(obj[key])) \n            target[key] = obj[key];\n        \n      }, this);\n      \n      return target;\n      \n    },\n    \n    defaults: function(target) {\n      \n      this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n        \n        for (var key in obj)\n          if (this.isUndefined(target[key])) \n            target[key] = obj[key];\n        \n      }, this);\n      \n      return target;\n    \n    },\n    \n    compose: function() {\n      var toCall = ARR_SLICE.call(arguments);\n            return function() {\n              var args = ARR_SLICE.call(arguments);\n              for (var i = toCall.length -1; i >= 0; i--) {\n                args = [toCall[i].apply(this, args)];\n              }\n              return args[0];\n            }\n    },\n    \n    each: function(obj, itr, scope) {\n\n      \n      if (ARR_EACH && obj.forEach === ARR_EACH) { \n        \n        obj.forEach(itr, scope);\n        \n      } else if (obj.length === obj.length + 0) { // Is number but not NaN\n        \n        for (var key = 0, l = obj.length; key < l; key++)\n          if (key in obj && itr.call(scope, obj[key], key) === this.BREAK) \n            return;\n            \n      } else {\n\n        for (var key in obj) \n          if (itr.call(scope, obj[key], key) === this.BREAK)\n            return;\n            \n      }\n            \n    },\n    \n    defer: function(fnc) {\n      setTimeout(fnc, 0);\n    },\n    \n    toArray: function(obj) {\n      if (obj.toArray) return obj.toArray();\n      return ARR_SLICE.call(obj);\n    },\n\n    isUndefined: function(obj) {\n      return obj === undefined;\n    },\n    \n    isNull: function(obj) {\n      return obj === null;\n    },\n    \n    isNaN: function(obj) {\n      return obj !== obj;\n    },\n    \n    isArray: Array.isArray || function(obj) {\n      return obj.constructor === Array;\n    },\n    \n    isObject: function(obj) {\n      return obj === Object(obj);\n    },\n    \n    isNumber: function(obj) {\n      return obj === obj+0;\n    },\n    \n    isString: function(obj) {\n      return obj === obj+'';\n    },\n    \n    isBoolean: function(obj) {\n      return obj === false || obj === true;\n    },\n    \n    isFunction: function(obj) {\n      return Object.prototype.toString.call(obj) === '[object Function]';\n    }\n  \n  };\n    \n})();\n\n\ndat.color.toString = (function (common) {\n\n  return function(color) {\n\n    if (color.a == 1 || common.isUndefined(color.a)) {\n\n      var s = color.hex.toString(16);\n      while (s.length < 6) {\n        s = '0' + s;\n      }\n\n      return '#' + s;\n\n    } else {\n\n      return 'rgba(' + Math.round(color.r) + ',' + Math.round(color.g) + ',' + Math.round(color.b) + ',' + color.a + ')';\n\n    }\n\n  }\n\n})(dat.utils.common);\n\n\ndat.Color = dat.color.Color = (function (interpret, math, toString, common) {\n\n  var Color = function() {\n\n    this.__state = interpret.apply(this, arguments);\n\n    if (this.__state === false) {\n      throw 'Failed to interpret color arguments';\n    }\n\n    this.__state.a = this.__state.a || 1;\n\n\n  };\n\n  Color.COMPONENTS = ['r','g','b','h','s','v','hex','a'];\n\n  common.extend(Color.prototype, {\n\n    toString: function() {\n      return toString(this);\n    },\n\n    toOriginal: function() {\n      return this.__state.conversion.write(this);\n    }\n\n  });\n\n  defineRGBComponent(Color.prototype, 'r', 2);\n  defineRGBComponent(Color.prototype, 'g', 1);\n  defineRGBComponent(Color.prototype, 'b', 0);\n\n  defineHSVComponent(Color.prototype, 'h');\n  defineHSVComponent(Color.prototype, 's');\n  defineHSVComponent(Color.prototype, 'v');\n\n  Object.defineProperty(Color.prototype, 'a', {\n\n    get: function() {\n      return this.__state.a;\n    },\n\n    set: function(v) {\n      this.__state.a = v;\n    }\n\n  });\n\n  Object.defineProperty(Color.prototype, 'hex', {\n\n    get: function() {\n\n      if (!this.__state.space !== 'HEX') {\n        this.__state.hex = math.rgb_to_hex(this.r, this.g, this.b);\n      }\n\n      return this.__state.hex;\n\n    },\n\n    set: function(v) {\n\n      this.__state.space = 'HEX';\n      this.__state.hex = v;\n\n    }\n\n  });\n\n  function defineRGBComponent(target, component, componentHexIndex) {\n\n    Object.defineProperty(target, component, {\n\n      get: function() {\n\n        if (this.__state.space === 'RGB') {\n          return this.__state[component];\n        }\n\n        recalculateRGB(this, component, componentHexIndex);\n\n        return this.__state[component];\n\n      },\n\n      set: function(v) {\n\n        if (this.__state.space !== 'RGB') {\n          recalculateRGB(this, component, componentHexIndex);\n          this.__state.space = 'RGB';\n        }\n\n        this.__state[component] = v;\n\n      }\n\n    });\n\n  }\n\n  function defineHSVComponent(target, component) {\n\n    Object.defineProperty(target, component, {\n\n      get: function() {\n\n        if (this.__state.space === 'HSV')\n          return this.__state[component];\n\n        recalculateHSV(this);\n\n        return this.__state[component];\n\n      },\n\n      set: function(v) {\n\n        if (this.__state.space !== 'HSV') {\n          recalculateHSV(this);\n          this.__state.space = 'HSV';\n        }\n\n        this.__state[component] = v;\n\n      }\n\n    });\n\n  }\n\n  function recalculateRGB(color, component, componentHexIndex) {\n\n    if (color.__state.space === 'HEX') {\n\n      color.__state[component] = math.component_from_hex(color.__state.hex, componentHexIndex);\n\n    } else if (color.__state.space === 'HSV') {\n\n      common.extend(color.__state, math.hsv_to_rgb(color.__state.h, color.__state.s, color.__state.v));\n\n    } else {\n\n      throw 'Corrupted color state';\n\n    }\n\n  }\n\n  function recalculateHSV(color) {\n\n    var result = math.rgb_to_hsv(color.r, color.g, color.b);\n\n    common.extend(color.__state,\n        {\n          s: result.s,\n          v: result.v\n        }\n    );\n\n    if (!common.isNaN(result.h)) {\n      color.__state.h = result.h;\n    } else if (common.isUndefined(color.__state.h)) {\n      color.__state.h = 0;\n    }\n\n  }\n\n  return Color;\n\n})(dat.color.interpret = (function (toString, common) {\n\n  var result, toReturn;\n\n  var interpret = function() {\n\n    toReturn = false;\n\n    var original = arguments.length > 1 ? common.toArray(arguments) : arguments[0];\n\n    common.each(INTERPRETATIONS, function(family) {\n\n      if (family.litmus(original)) {\n\n        common.each(family.conversions, function(conversion, conversionName) {\n\n          result = conversion.read(original);\n\n          if (toReturn === false && result !== false) {\n            toReturn = result;\n            result.conversionName = conversionName;\n            result.conversion = conversion;\n            return common.BREAK;\n\n          }\n\n        });\n\n        return common.BREAK;\n\n      }\n\n    });\n\n    return toReturn;\n\n  };\n\n  var INTERPRETATIONS = [\n\n    // Strings\n    {\n\n      litmus: common.isString,\n\n      conversions: {\n\n        THREE_CHAR_HEX: {\n\n          read: function(original) {\n\n            var test = original.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);\n            if (test === null) return false;\n\n            return {\n              space: 'HEX',\n              hex: parseInt(\n                  '0x' +\n                      test[1].toString() + test[1].toString() +\n                      test[2].toString() + test[2].toString() +\n                      test[3].toString() + test[3].toString())\n            };\n\n          },\n\n          write: toString\n\n        },\n\n        SIX_CHAR_HEX: {\n\n          read: function(original) {\n\n            var test = original.match(/^#([A-F0-9]{6})$/i);\n            if (test === null) return false;\n\n            return {\n              space: 'HEX',\n              hex: parseInt('0x' + test[1].toString())\n            };\n\n          },\n\n          write: toString\n\n        },\n\n        CSS_RGB: {\n\n          read: function(original) {\n\n            var test = original.match(/^rgb\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\)/);\n            if (test === null) return false;\n\n            return {\n              space: 'RGB',\n              r: parseFloat(test[1]),\n              g: parseFloat(test[2]),\n              b: parseFloat(test[3])\n            };\n\n          },\n\n          write: toString\n\n        },\n\n        CSS_RGBA: {\n\n          read: function(original) {\n\n            var test = original.match(/^rgba\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\,\\s*(.+)\\s*\\)/);\n            if (test === null) return false;\n\n            return {\n              space: 'RGB',\n              r: parseFloat(test[1]),\n              g: parseFloat(test[2]),\n              b: parseFloat(test[3]),\n              a: parseFloat(test[4])\n            };\n\n          },\n\n          write: toString\n\n        }\n\n      }\n\n    },\n\n    // Numbers\n    {\n\n      litmus: common.isNumber,\n\n      conversions: {\n\n        HEX: {\n          read: function(original) {\n            return {\n              space: 'HEX',\n              hex: original,\n              conversionName: 'HEX'\n            }\n          },\n\n          write: function(color) {\n            return color.hex;\n          }\n        }\n\n      }\n\n    },\n\n    // Arrays\n    {\n\n      litmus: common.isArray,\n\n      conversions: {\n\n        RGB_ARRAY: {\n          read: function(original) {\n            if (original.length != 3) return false;\n            return {\n              space: 'RGB',\n              r: original[0],\n              g: original[1],\n              b: original[2]\n            };\n          },\n\n          write: function(color) {\n            return [color.r, color.g, color.b];\n          }\n\n        },\n\n        RGBA_ARRAY: {\n          read: function(original) {\n            if (original.length != 4) return false;\n            return {\n              space: 'RGB',\n              r: original[0],\n              g: original[1],\n              b: original[2],\n              a: original[3]\n            };\n          },\n\n          write: function(color) {\n            return [color.r, color.g, color.b, color.a];\n          }\n\n        }\n\n      }\n\n    },\n\n    // Objects\n    {\n\n      litmus: common.isObject,\n\n      conversions: {\n\n        RGBA_OBJ: {\n          read: function(original) {\n            if (common.isNumber(original.r) &&\n                common.isNumber(original.g) &&\n                common.isNumber(original.b) &&\n                common.isNumber(original.a)) {\n              return {\n                space: 'RGB',\n                r: original.r,\n                g: original.g,\n                b: original.b,\n                a: original.a\n              }\n            }\n            return false;\n          },\n\n          write: function(color) {\n            return {\n              r: color.r,\n              g: color.g,\n              b: color.b,\n              a: color.a\n            }\n          }\n        },\n\n        RGB_OBJ: {\n          read: function(original) {\n            if (common.isNumber(original.r) &&\n                common.isNumber(original.g) &&\n                common.isNumber(original.b)) {\n              return {\n                space: 'RGB',\n                r: original.r,\n                g: original.g,\n                b: original.b\n              }\n            }\n            return false;\n          },\n\n          write: function(color) {\n            return {\n              r: color.r,\n              g: color.g,\n              b: color.b\n            }\n          }\n        },\n\n        HSVA_OBJ: {\n          read: function(original) {\n            if (common.isNumber(original.h) &&\n                common.isNumber(original.s) &&\n                common.isNumber(original.v) &&\n                common.isNumber(original.a)) {\n              return {\n                space: 'HSV',\n                h: original.h,\n                s: original.s,\n                v: original.v,\n                a: original.a\n              }\n            }\n            return false;\n          },\n\n          write: function(color) {\n            return {\n              h: color.h,\n              s: color.s,\n              v: color.v,\n              a: color.a\n            }\n          }\n        },\n\n        HSV_OBJ: {\n          read: function(original) {\n            if (common.isNumber(original.h) &&\n                common.isNumber(original.s) &&\n                common.isNumber(original.v)) {\n              return {\n                space: 'HSV',\n                h: original.h,\n                s: original.s,\n                v: original.v\n              }\n            }\n            return false;\n          },\n\n          write: function(color) {\n            return {\n              h: color.h,\n              s: color.s,\n              v: color.v\n            }\n          }\n\n        }\n\n      }\n\n    }\n\n\n  ];\n\n  return interpret;\n\n\n})(dat.color.toString,\ndat.utils.common),\ndat.color.math = (function () {\n\n  var tmpComponent;\n\n  return {\n\n    hsv_to_rgb: function(h, s, v) {\n\n      var hi = Math.floor(h / 60) % 6;\n\n      var f = h / 60 - Math.floor(h / 60);\n      var p = v * (1.0 - s);\n      var q = v * (1.0 - (f * s));\n      var t = v * (1.0 - ((1.0 - f) * s));\n      var c = [\n        [v, t, p],\n        [q, v, p],\n        [p, v, t],\n        [p, q, v],\n        [t, p, v],\n        [v, p, q]\n      ][hi];\n\n      return {\n        r: c[0] * 255,\n        g: c[1] * 255,\n        b: c[2] * 255\n      };\n\n    },\n\n    rgb_to_hsv: function(r, g, b) {\n\n      var min = Math.min(r, g, b),\n          max = Math.max(r, g, b),\n          delta = max - min,\n          h, s;\n\n      if (max != 0) {\n        s = delta / max;\n      } else {\n        return {\n          h: NaN,\n          s: 0,\n          v: 0\n        };\n      }\n\n      if (r == max) {\n        h = (g - b) / delta;\n      } else if (g == max) {\n        h = 2 + (b - r) / delta;\n      } else {\n        h = 4 + (r - g) / delta;\n      }\n      h /= 6;\n      if (h < 0) {\n        h += 1;\n      }\n\n      return {\n        h: h * 360,\n        s: s,\n        v: max / 255\n      };\n    },\n\n    rgb_to_hex: function(r, g, b) {\n      var hex = this.hex_with_component(0, 2, r);\n      hex = this.hex_with_component(hex, 1, g);\n      hex = this.hex_with_component(hex, 0, b);\n      return hex;\n    },\n\n    component_from_hex: function(hex, componentIndex) {\n      return (hex >> (componentIndex * 8)) & 0xFF;\n    },\n\n    hex_with_component: function(hex, componentIndex, value) {\n      return value << (tmpComponent = componentIndex * 8) | (hex & ~ (0xFF << tmpComponent));\n    }\n\n  }\n\n})(),\ndat.color.toString,\ndat.utils.common);","/**\n * dat-gui JavaScript Controller Library\n * http://code.google.com/p/dat-gui\n *\n * Copyright 2011 Data Arts Team, Google Creative Lab\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\n/** @namespace */\nvar dat = module.exports = dat || {};\n\n/** @namespace */\ndat.gui = dat.gui || {};\n\n/** @namespace */\ndat.utils = dat.utils || {};\n\n/** @namespace */\ndat.controllers = dat.controllers || {};\n\n/** @namespace */\ndat.dom = dat.dom || {};\n\n/** @namespace */\ndat.color = dat.color || {};\n\ndat.utils.css = (function () {\n  return {\n    load: function (url, doc) {\n      doc = doc || document;\n      var link = doc.createElement('link');\n      link.type = 'text/css';\n      link.rel = 'stylesheet';\n      link.href = url;\n      doc.getElementsByTagName('head')[0].appendChild(link);\n    },\n    inject: function(css, doc) {\n      doc = doc || document;\n      var injected = document.createElement('style');\n      injected.type = 'text/css';\n      injected.innerHTML = css;\n      doc.getElementsByTagName('head')[0].appendChild(injected);\n    }\n  }\n})();\n\n\ndat.utils.common = (function () {\n  \n  var ARR_EACH = Array.prototype.forEach;\n  var ARR_SLICE = Array.prototype.slice;\n\n  /**\n   * Band-aid methods for things that should be a lot easier in JavaScript.\n   * Implementation and structure inspired by underscore.js\n   * http://documentcloud.github.com/underscore/\n   */\n\n  return { \n    \n    BREAK: {},\n  \n    extend: function(target) {\n      \n      this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n        \n        for (var key in obj)\n          if (!this.isUndefined(obj[key])) \n            target[key] = obj[key];\n        \n      }, this);\n      \n      return target;\n      \n    },\n    \n    defaults: function(target) {\n      \n      this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n        \n        for (var key in obj)\n          if (this.isUndefined(target[key])) \n            target[key] = obj[key];\n        \n      }, this);\n      \n      return target;\n    \n    },\n    \n    compose: function() {\n      var toCall = ARR_SLICE.call(arguments);\n            return function() {\n              var args = ARR_SLICE.call(arguments);\n              for (var i = toCall.length -1; i >= 0; i--) {\n                args = [toCall[i].apply(this, args)];\n              }\n              return args[0];\n            }\n    },\n    \n    each: function(obj, itr, scope) {\n\n      \n      if (ARR_EACH && obj.forEach === ARR_EACH) { \n        \n        obj.forEach(itr, scope);\n        \n      } else if (obj.length === obj.length + 0) { // Is number but not NaN\n        \n        for (var key = 0, l = obj.length; key < l; key++)\n          if (key in obj && itr.call(scope, obj[key], key) === this.BREAK) \n            return;\n            \n      } else {\n\n        for (var key in obj) \n          if (itr.call(scope, obj[key], key) === this.BREAK)\n            return;\n            \n      }\n            \n    },\n    \n    defer: function(fnc) {\n      setTimeout(fnc, 0);\n    },\n    \n    toArray: function(obj) {\n      if (obj.toArray) return obj.toArray();\n      return ARR_SLICE.call(obj);\n    },\n\n    isUndefined: function(obj) {\n      return obj === undefined;\n    },\n    \n    isNull: function(obj) {\n      return obj === null;\n    },\n    \n    isNaN: function(obj) {\n      return obj !== obj;\n    },\n    \n    isArray: Array.isArray || function(obj) {\n      return obj.constructor === Array;\n    },\n    \n    isObject: function(obj) {\n      return obj === Object(obj);\n    },\n    \n    isNumber: function(obj) {\n      return obj === obj+0;\n    },\n    \n    isString: function(obj) {\n      return obj === obj+'';\n    },\n    \n    isBoolean: function(obj) {\n      return obj === false || obj === true;\n    },\n    \n    isFunction: function(obj) {\n      return Object.prototype.toString.call(obj) === '[object Function]';\n    }\n  \n  };\n    \n})();\n\n\ndat.controllers.Controller = (function (common) {\n\n  /**\n   * @class An \"abstract\" class that represents a given property of an object.\n   *\n   * @param {Object} object The object to be manipulated\n   * @param {string} property The name of the property to be manipulated\n   *\n   * @member dat.controllers\n   */\n  var Controller = function(object, property) {\n\n    this.initialValue = object[property];\n\n    /**\n     * Those who extend this class will put their DOM elements in here.\n     * @type {DOMElement}\n     */\n    this.domElement = document.createElement('div');\n\n    /**\n     * The object to manipulate\n     * @type {Object}\n     */\n    this.object = object;\n\n    /**\n     * The name of the property to manipulate\n     * @type {String}\n     */\n    this.property = property;\n\n    /**\n     * The function to be called on change.\n     * @type {Function}\n     * @ignore\n     */\n    this.__onChange = undefined;\n\n    /**\n     * The function to be called on finishing change.\n     * @type {Function}\n     * @ignore\n     */\n    this.__onFinishChange = undefined;\n\n  };\n\n  common.extend(\n\n      Controller.prototype,\n\n      /** @lends dat.controllers.Controller.prototype */\n      {\n\n        /**\n         * Specify that a function fire every time someone changes the value with\n         * this Controller.\n         *\n         * @param {Function} fnc This function will be called whenever the value\n         * is modified via this Controller.\n         * @returns {dat.controllers.Controller} this\n         */\n        onChange: function(fnc) {\n          this.__onChange = fnc;\n          return this;\n        },\n\n        /**\n         * Specify that a function fire every time someone \"finishes\" changing\n         * the value wih this Controller. Useful for values that change\n         * incrementally like numbers or strings.\n         *\n         * @param {Function} fnc This function will be called whenever\n         * someone \"finishes\" changing the value via this Controller.\n         * @returns {dat.controllers.Controller} this\n         */\n        onFinishChange: function(fnc) {\n          this.__onFinishChange = fnc;\n          return this;\n        },\n\n        /**\n         * Change the value of <code>object[property]</code>\n         *\n         * @param {Object} newValue The new value of <code>object[property]</code>\n         */\n        setValue: function(newValue) {\n          this.object[this.property] = newValue;\n          if (this.__onChange) {\n            this.__onChange.call(this, newValue);\n          }\n          this.updateDisplay();\n          return this;\n        },\n\n        /**\n         * Gets the value of <code>object[property]</code>\n         *\n         * @returns {Object} The current value of <code>object[property]</code>\n         */\n        getValue: function() {\n          return this.object[this.property];\n        },\n\n        /**\n         * Refreshes the visual display of a Controller in order to keep sync\n         * with the object's current value.\n         * @returns {dat.controllers.Controller} this\n         */\n        updateDisplay: function() {\n          return this;\n        },\n\n        /**\n         * @returns {Boolean} true if the value has deviated from initialValue\n         */\n        isModified: function() {\n          return this.initialValue !== this.getValue()\n        }\n\n      }\n\n  );\n\n  return Controller;\n\n\n})(dat.utils.common);\n\n\ndat.dom.dom = (function (common) {\n\n  var EVENT_MAP = {\n    'HTMLEvents': ['change'],\n    'MouseEvents': ['click','mousemove','mousedown','mouseup', 'mouseover'],\n    'KeyboardEvents': ['keydown']\n  };\n\n  var EVENT_MAP_INV = {};\n  common.each(EVENT_MAP, function(v, k) {\n    common.each(v, function(e) {\n      EVENT_MAP_INV[e] = k;\n    });\n  });\n\n  var CSS_VALUE_PIXELS = /(\\d+(\\.\\d+)?)px/;\n\n  function cssValueToPixels(val) {\n\n    if (val === '0' || common.isUndefined(val)) return 0;\n\n    var match = val.match(CSS_VALUE_PIXELS);\n\n    if (!common.isNull(match)) {\n      return parseFloat(match[1]);\n    }\n\n    // TODO ...ems? %?\n\n    return 0;\n\n  }\n\n  /**\n   * @namespace\n   * @member dat.dom\n   */\n  var dom = {\n\n    /**\n     * \n     * @param elem\n     * @param selectable\n     */\n    makeSelectable: function(elem, selectable) {\n\n      if (elem === undefined || elem.style === undefined) return;\n\n      elem.onselectstart = selectable ? function() {\n        return false;\n      } : function() {\n      };\n\n      elem.style.MozUserSelect = selectable ? 'auto' : 'none';\n      elem.style.KhtmlUserSelect = selectable ? 'auto' : 'none';\n      elem.unselectable = selectable ? 'on' : 'off';\n\n    },\n\n    /**\n     *\n     * @param elem\n     * @param horizontal\n     * @param vertical\n     */\n    makeFullscreen: function(elem, horizontal, vertical) {\n\n      if (common.isUndefined(horizontal)) horizontal = true;\n      if (common.isUndefined(vertical)) vertical = true;\n\n      elem.style.position = 'absolute';\n\n      if (horizontal) {\n        elem.style.left = 0;\n        elem.style.right = 0;\n      }\n      if (vertical) {\n        elem.style.top = 0;\n        elem.style.bottom = 0;\n      }\n\n    },\n\n    /**\n     *\n     * @param elem\n     * @param eventType\n     * @param params\n     */\n    fakeEvent: function(elem, eventType, params, aux) {\n      params = params || {};\n      var className = EVENT_MAP_INV[eventType];\n      if (!className) {\n        throw new Error('Event type ' + eventType + ' not supported.');\n      }\n      var evt = document.createEvent(className);\n      switch (className) {\n        case 'MouseEvents':\n          var clientX = params.x || params.clientX || 0;\n          var clientY = params.y || params.clientY || 0;\n          evt.initMouseEvent(eventType, params.bubbles || false,\n              params.cancelable || true, window, params.clickCount || 1,\n              0, //screen X\n              0, //screen Y\n              clientX, //client X\n              clientY, //client Y\n              false, false, false, false, 0, null);\n          break;\n        case 'KeyboardEvents':\n          var init = evt.initKeyboardEvent || evt.initKeyEvent; // webkit || moz\n          common.defaults(params, {\n            cancelable: true,\n            ctrlKey: false,\n            altKey: false,\n            shiftKey: false,\n            metaKey: false,\n            keyCode: undefined,\n            charCode: undefined\n          });\n          init(eventType, params.bubbles || false,\n              params.cancelable, window,\n              params.ctrlKey, params.altKey,\n              params.shiftKey, params.metaKey,\n              params.keyCode, params.charCode);\n          break;\n        default:\n          evt.initEvent(eventType, params.bubbles || false,\n              params.cancelable || true);\n          break;\n      }\n      common.defaults(evt, aux);\n      elem.dispatchEvent(evt);\n    },\n\n    /**\n     *\n     * @param elem\n     * @param event\n     * @param func\n     * @param bool\n     */\n    bind: function(elem, event, func, bool) {\n      bool = bool || false;\n      if (elem.addEventListener)\n        elem.addEventListener(event, func, bool);\n      else if (elem.attachEvent)\n        elem.attachEvent('on' + event, func);\n      return dom;\n    },\n\n    /**\n     *\n     * @param elem\n     * @param event\n     * @param func\n     * @param bool\n     */\n    unbind: function(elem, event, func, bool) {\n      bool = bool || false;\n      if (elem.removeEventListener)\n        elem.removeEventListener(event, func, bool);\n      else if (elem.detachEvent)\n        elem.detachEvent('on' + event, func);\n      return dom;\n    },\n\n    /**\n     *\n     * @param elem\n     * @param className\n     */\n    addClass: function(elem, className) {\n      if (elem.className === undefined) {\n        elem.className = className;\n      } else if (elem.className !== className) {\n        var classes = elem.className.split(/ +/);\n        if (classes.indexOf(className) == -1) {\n          classes.push(className);\n          elem.className = classes.join(' ').replace(/^\\s+/, '').replace(/\\s+$/, '');\n        }\n      }\n      return dom;\n    },\n\n    /**\n     *\n     * @param elem\n     * @param className\n     */\n    removeClass: function(elem, className) {\n      if (className) {\n        if (elem.className === undefined) {\n          // elem.className = className;\n        } else if (elem.className === className) {\n          elem.removeAttribute('class');\n        } else {\n          var classes = elem.className.split(/ +/);\n          var index = classes.indexOf(className);\n          if (index != -1) {\n            classes.splice(index, 1);\n            elem.className = classes.join(' ');\n          }\n        }\n      } else {\n        elem.className = undefined;\n      }\n      return dom;\n    },\n\n    hasClass: function(elem, className) {\n      return new RegExp('(?:^|\\\\s+)' + className + '(?:\\\\s+|$)').test(elem.className) || false;\n    },\n\n    /**\n     *\n     * @param elem\n     */\n    getWidth: function(elem) {\n\n      var style = getComputedStyle(elem);\n\n      return cssValueToPixels(style['border-left-width']) +\n          cssValueToPixels(style['border-right-width']) +\n          cssValueToPixels(style['padding-left']) +\n          cssValueToPixels(style['padding-right']) +\n          cssValueToPixels(style['width']);\n    },\n\n    /**\n     *\n     * @param elem\n     */\n    getHeight: function(elem) {\n\n      var style = getComputedStyle(elem);\n\n      return cssValueToPixels(style['border-top-width']) +\n          cssValueToPixels(style['border-bottom-width']) +\n          cssValueToPixels(style['padding-top']) +\n          cssValueToPixels(style['padding-bottom']) +\n          cssValueToPixels(style['height']);\n    },\n\n    /**\n     *\n     * @param elem\n     */\n    getOffset: function(elem) {\n      var offset = {left: 0, top:0};\n      if (elem.offsetParent) {\n        do {\n          offset.left += elem.offsetLeft;\n          offset.top += elem.offsetTop;\n        } while (elem = elem.offsetParent);\n      }\n      return offset;\n    },\n\n    // http://stackoverflow.com/posts/2684561/revisions\n    /**\n     * \n     * @param elem\n     */\n    isActive: function(elem) {\n      return elem === document.activeElement && ( elem.type || elem.href );\n    }\n\n  };\n\n  return dom;\n\n})(dat.utils.common);\n\n\ndat.controllers.OptionController = (function (Controller, dom, common) {\n\n  /**\n   * @class Provides a select input to alter the property of an object, using a\n   * list of accepted values.\n   *\n   * @extends dat.controllers.Controller\n   *\n   * @param {Object} object The object to be manipulated\n   * @param {string} property The name of the property to be manipulated\n   * @param {Object|string[]} options A map of labels to acceptable values, or\n   * a list of acceptable string values.\n   *\n   * @member dat.controllers\n   */\n  var OptionController = function(object, property, options) {\n\n    OptionController.superclass.call(this, object, property);\n\n    var _this = this;\n\n    /**\n     * The drop down menu\n     * @ignore\n     */\n    this.__select = document.createElement('select');\n\n    if (common.isArray(options)) {\n      var map = {};\n      common.each(options, function(element) {\n        map[element] = element;\n      });\n      options = map;\n    }\n\n    common.each(options, function(value, key) {\n\n      var opt = document.createElement('option');\n      opt.innerHTML = key;\n      opt.setAttribute('value', value);\n      _this.__select.appendChild(opt);\n\n    });\n\n    // Acknowledge original value\n    this.updateDisplay();\n\n    dom.bind(this.__select, 'change', function() {\n      var desiredValue = this.options[this.selectedIndex].value;\n      _this.setValue(desiredValue);\n    });\n\n    this.domElement.appendChild(this.__select);\n\n  };\n\n  OptionController.superclass = Controller;\n\n  common.extend(\n\n      OptionController.prototype,\n      Controller.prototype,\n\n      {\n\n        setValue: function(v) {\n          var toReturn = OptionController.superclass.prototype.setValue.call(this, v);\n          if (this.__onFinishChange) {\n            this.__onFinishChange.call(this, this.getValue());\n          }\n          return toReturn;\n        },\n\n        updateDisplay: function() {\n          this.__select.value = this.getValue();\n          return OptionController.superclass.prototype.updateDisplay.call(this);\n        }\n\n      }\n\n  );\n\n  return OptionController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.NumberController = (function (Controller, common) {\n\n  /**\n   * @class Represents a given property of an object that is a number.\n   *\n   * @extends dat.controllers.Controller\n   *\n   * @param {Object} object The object to be manipulated\n   * @param {string} property The name of the property to be manipulated\n   * @param {Object} [params] Optional parameters\n   * @param {Number} [params.min] Minimum allowed value\n   * @param {Number} [params.max] Maximum allowed value\n   * @param {Number} [params.step] Increment by which to change value\n   *\n   * @member dat.controllers\n   */\n  var NumberController = function(object, property, params) {\n\n    NumberController.superclass.call(this, object, property);\n\n    params = params || {};\n\n    this.__min = params.min;\n    this.__max = params.max;\n    this.__step = params.step;\n\n    if (common.isUndefined(this.__step)) {\n\n      if (this.initialValue == 0) {\n        this.__impliedStep = 1; // What are we, psychics?\n      } else {\n        // Hey Doug, check this out.\n        this.__impliedStep = Math.pow(10, Math.floor(Math.log(this.initialValue)/Math.LN10))/10;\n      }\n\n    } else {\n\n      this.__impliedStep = this.__step;\n\n    }\n\n    this.__precision = numDecimals(this.__impliedStep);\n\n\n  };\n\n  NumberController.superclass = Controller;\n\n  common.extend(\n\n      NumberController.prototype,\n      Controller.prototype,\n\n      /** @lends dat.controllers.NumberController.prototype */\n      {\n\n        setValue: function(v) {\n\n          if (this.__min !== undefined && v < this.__min) {\n            v = this.__min;\n          } else if (this.__max !== undefined && v > this.__max) {\n            v = this.__max;\n          }\n\n          if (this.__step !== undefined && v % this.__step != 0) {\n            v = Math.round(v / this.__step) * this.__step;\n          }\n\n          return NumberController.superclass.prototype.setValue.call(this, v);\n\n        },\n\n        /**\n         * Specify a minimum value for <code>object[property]</code>.\n         *\n         * @param {Number} minValue The minimum value for\n         * <code>object[property]</code>\n         * @returns {dat.controllers.NumberController} this\n         */\n        min: function(v) {\n          this.__min = v;\n          return this;\n        },\n\n        /**\n         * Specify a maximum value for <code>object[property]</code>.\n         *\n         * @param {Number} maxValue The maximum value for\n         * <code>object[property]</code>\n         * @returns {dat.controllers.NumberController} this\n         */\n        max: function(v) {\n          this.__max = v;\n          return this;\n        },\n\n        /**\n         * Specify a step value that dat.controllers.NumberController\n         * increments by.\n         *\n         * @param {Number} stepValue The step value for\n         * dat.controllers.NumberController\n         * @default if minimum and maximum specified increment is 1% of the\n         * difference otherwise stepValue is 1\n         * @returns {dat.controllers.NumberController} this\n         */\n        step: function(v) {\n          this.__step = v;\n          return this;\n        }\n\n      }\n\n  );\n\n  function numDecimals(x) {\n    x = x.toString();\n    if (x.indexOf('.') > -1) {\n      return x.length - x.indexOf('.') - 1;\n    } else {\n      return 0;\n    }\n  }\n\n  return NumberController;\n\n})(dat.controllers.Controller,\ndat.utils.common);\n\n\ndat.controllers.NumberControllerBox = (function (NumberController, dom, common) {\n\n  /**\n   * @class Represents a given property of an object that is a number and\n   * provides an input element with which to manipulate it.\n   *\n   * @extends dat.controllers.Controller\n   * @extends dat.controllers.NumberController\n   *\n   * @param {Object} object The object to be manipulated\n   * @param {string} property The name of the property to be manipulated\n   * @param {Object} [params] Optional parameters\n   * @param {Number} [params.min] Minimum allowed value\n   * @param {Number} [params.max] Maximum allowed value\n   * @param {Number} [params.step] Increment by which to change value\n   *\n   * @member dat.controllers\n   */\n  var NumberControllerBox = function(object, property, params) {\n\n    this.__truncationSuspended = false;\n\n    NumberControllerBox.superclass.call(this, object, property, params);\n\n    var _this = this;\n\n    /**\n     * {Number} Previous mouse y position\n     * @ignore\n     */\n    var prev_y;\n\n    this.__input = document.createElement('input');\n    this.__input.setAttribute('type', 'text');\n\n    // Makes it so manually specified values are not truncated.\n\n    dom.bind(this.__input, 'change', onChange);\n    dom.bind(this.__input, 'blur', onBlur);\n    dom.bind(this.__input, 'mousedown', onMouseDown);\n    dom.bind(this.__input, 'keydown', function(e) {\n\n      // When pressing entire, you can be as precise as you want.\n      if (e.keyCode === 13) {\n        _this.__truncationSuspended = true;\n        this.blur();\n        _this.__truncationSuspended = false;\n      }\n\n    });\n\n    function onChange() {\n      var attempted = parseFloat(_this.__input.value);\n      if (!common.isNaN(attempted)) _this.setValue(attempted);\n    }\n\n    function onBlur() {\n      onChange();\n      if (_this.__onFinishChange) {\n        _this.__onFinishChange.call(_this, _this.getValue());\n      }\n    }\n\n    function onMouseDown(e) {\n      dom.bind(window, 'mousemove', onMouseDrag);\n      dom.bind(window, 'mouseup', onMouseUp);\n      prev_y = e.clientY;\n    }\n\n    function onMouseDrag(e) {\n\n      var diff = prev_y - e.clientY;\n      _this.setValue(_this.getValue() + diff * _this.__impliedStep);\n\n      prev_y = e.clientY;\n\n    }\n\n    function onMouseUp() {\n      dom.unbind(window, 'mousemove', onMouseDrag);\n      dom.unbind(window, 'mouseup', onMouseUp);\n    }\n\n    this.updateDisplay();\n\n    this.domElement.appendChild(this.__input);\n\n  };\n\n  NumberControllerBox.superclass = NumberController;\n\n  common.extend(\n\n      NumberControllerBox.prototype,\n      NumberController.prototype,\n\n      {\n\n        updateDisplay: function() {\n\n          this.__input.value = this.__truncationSuspended ? this.getValue() : roundToDecimal(this.getValue(), this.__precision);\n          return NumberControllerBox.superclass.prototype.updateDisplay.call(this);\n        }\n\n      }\n\n  );\n\n  function roundToDecimal(value, decimals) {\n    var tenTo = Math.pow(10, decimals);\n    return Math.round(value * tenTo) / tenTo;\n  }\n\n  return NumberControllerBox;\n\n})(dat.controllers.NumberController,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.NumberControllerSlider = (function (NumberController, dom, css, common, styleSheet) {\n\n  /**\n   * @class Represents a given property of an object that is a number, contains\n   * a minimum and maximum, and provides a slider element with which to\n   * manipulate it. It should be noted that the slider element is made up of\n   * <code>&lt;div&gt;</code> tags, <strong>not</strong> the html5\n   * <code>&lt;slider&gt;</code> element.\n   *\n   * @extends dat.controllers.Controller\n   * @extends dat.controllers.NumberController\n   * \n   * @param {Object} object The object to be manipulated\n   * @param {string} property The name of the property to be manipulated\n   * @param {Number} minValue Minimum allowed value\n   * @param {Number} maxValue Maximum allowed value\n   * @param {Number} stepValue Increment by which to change value\n   *\n   * @member dat.controllers\n   */\n  var NumberControllerSlider = function(object, property, min, max, step) {\n\n    NumberControllerSlider.superclass.call(this, object, property, { min: min, max: max, step: step });\n\n    var _this = this;\n\n    this.__background = document.createElement('div');\n    this.__foreground = document.createElement('div');\n    \n\n\n    dom.bind(this.__background, 'mousedown', onMouseDown);\n    \n    dom.addClass(this.__background, 'slider');\n    dom.addClass(this.__foreground, 'slider-fg');\n\n    function onMouseDown(e) {\n\n      dom.bind(window, 'mousemove', onMouseDrag);\n      dom.bind(window, 'mouseup', onMouseUp);\n\n      onMouseDrag(e);\n    }\n\n    function onMouseDrag(e) {\n\n      e.preventDefault();\n\n      var offset = dom.getOffset(_this.__background);\n      var width = dom.getWidth(_this.__background);\n      \n      _this.setValue(\n        map(e.clientX, offset.left, offset.left + width, _this.__min, _this.__max)\n      );\n\n      return false;\n\n    }\n\n    function onMouseUp() {\n      dom.unbind(window, 'mousemove', onMouseDrag);\n      dom.unbind(window, 'mouseup', onMouseUp);\n      if (_this.__onFinishChange) {\n        _this.__onFinishChange.call(_this, _this.getValue());\n      }\n    }\n\n    this.updateDisplay();\n\n    this.__background.appendChild(this.__foreground);\n    this.domElement.appendChild(this.__background);\n\n  };\n\n  NumberControllerSlider.superclass = NumberController;\n\n  /**\n   * Injects default stylesheet for slider elements.\n   */\n  NumberControllerSlider.useDefaultStyles = function() {\n    css.inject(styleSheet);\n  };\n\n  common.extend(\n\n      NumberControllerSlider.prototype,\n      NumberController.prototype,\n\n      {\n\n        updateDisplay: function() {\n          var pct = (this.getValue() - this.__min)/(this.__max - this.__min);\n          this.__foreground.style.width = pct*100+'%';\n          return NumberControllerSlider.superclass.prototype.updateDisplay.call(this);\n        }\n\n      }\n\n\n\n  );\n\n  function map(v, i1, i2, o1, o2) {\n    return o1 + (o2 - o1) * ((v - i1) / (i2 - i1));\n  }\n\n  return NumberControllerSlider;\n  \n})(dat.controllers.NumberController,\ndat.dom.dom,\ndat.utils.css,\ndat.utils.common,\n\".slider {\\n  box-shadow: inset 0 2px 4px rgba(0,0,0,0.15);\\n  height: 1em;\\n  border-radius: 1em;\\n  background-color: #eee;\\n  padding: 0 0.5em;\\n  overflow: hidden;\\n}\\n\\n.slider-fg {\\n  padding: 1px 0 2px 0;\\n  background-color: #aaa;\\n  height: 1em;\\n  margin-left: -0.5em;\\n  padding-right: 0.5em;\\n  border-radius: 1em 0 0 1em;\\n}\\n\\n.slider-fg:after {\\n  display: inline-block;\\n  border-radius: 1em;\\n  background-color: #fff;\\n  border:  1px solid #aaa;\\n  content: '';\\n  float: right;\\n  margin-right: -1em;\\n  margin-top: -1px;\\n  height: 0.9em;\\n  width: 0.9em;\\n}\");\n\n\ndat.controllers.FunctionController = (function (Controller, dom, common) {\n\n  /**\n   * @class Provides a GUI interface to fire a specified method, a property of an object.\n   *\n   * @extends dat.controllers.Controller\n   *\n   * @param {Object} object The object to be manipulated\n   * @param {string} property The name of the property to be manipulated\n   *\n   * @member dat.controllers\n   */\n  var FunctionController = function(object, property, text) {\n\n    FunctionController.superclass.call(this, object, property);\n\n    var _this = this;\n\n    this.__button = document.createElement('div');\n    this.__button.innerHTML = text === undefined ? 'Fire' : text;\n    dom.bind(this.__button, 'click', function(e) {\n      e.preventDefault();\n      _this.fire();\n      return false;\n    });\n\n    dom.addClass(this.__button, 'button');\n\n    this.domElement.appendChild(this.__button);\n\n\n  };\n\n  FunctionController.superclass = Controller;\n\n  common.extend(\n\n      FunctionController.prototype,\n      Controller.prototype,\n      {\n        \n        fire: function() {\n          if (this.__onChange) {\n            this.__onChange.call(this);\n          }\n          if (this.__onFinishChange) {\n            this.__onFinishChange.call(this, this.getValue());\n          }\n          this.getValue().call(this.object);\n        }\n      }\n\n  );\n\n  return FunctionController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.controllers.BooleanController = (function (Controller, dom, common) {\n\n  /**\n   * @class Provides a checkbox input to alter the boolean property of an object.\n   * @extends dat.controllers.Controller\n   *\n   * @param {Object} object The object to be manipulated\n   * @param {string} property The name of the property to be manipulated\n   *\n   * @member dat.controllers\n   */\n  var BooleanController = function(object, property) {\n\n    BooleanController.superclass.call(this, object, property);\n\n    var _this = this;\n    this.__prev = this.getValue();\n\n    this.__checkbox = document.createElement('input');\n    this.__checkbox.setAttribute('type', 'checkbox');\n\n\n    dom.bind(this.__checkbox, 'change', onChange, false);\n\n    this.domElement.appendChild(this.__checkbox);\n\n    // Match original value\n    this.updateDisplay();\n\n    function onChange() {\n      _this.setValue(!_this.__prev);\n    }\n\n  };\n\n  BooleanController.superclass = Controller;\n\n  common.extend(\n\n      BooleanController.prototype,\n      Controller.prototype,\n\n      {\n\n        setValue: function(v) {\n          var toReturn = BooleanController.superclass.prototype.setValue.call(this, v);\n          if (this.__onFinishChange) {\n            this.__onFinishChange.call(this, this.getValue());\n          }\n          this.__prev = this.getValue();\n          return toReturn;\n        },\n\n        updateDisplay: function() {\n          \n          if (this.getValue() === true) {\n            this.__checkbox.setAttribute('checked', 'checked');\n            this.__checkbox.checked = true;    \n          } else {\n              this.__checkbox.checked = false;\n          }\n\n          return BooleanController.superclass.prototype.updateDisplay.call(this);\n\n        }\n\n\n      }\n\n  );\n\n  return BooleanController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common);\n\n\ndat.color.toString = (function (common) {\n\n  return function(color) {\n\n    if (color.a == 1 || common.isUndefined(color.a)) {\n\n      var s = color.hex.toString(16);\n      while (s.length < 6) {\n        s = '0' + s;\n      }\n\n      return '#' + s;\n\n    } else {\n\n      return 'rgba(' + Math.round(color.r) + ',' + Math.round(color.g) + ',' + Math.round(color.b) + ',' + color.a + ')';\n\n    }\n\n  }\n\n})(dat.utils.common);\n\n\ndat.color.interpret = (function (toString, common) {\n\n  var result, toReturn;\n\n  var interpret = function() {\n\n    toReturn = false;\n\n    var original = arguments.length > 1 ? common.toArray(arguments) : arguments[0];\n\n    common.each(INTERPRETATIONS, function(family) {\n\n      if (family.litmus(original)) {\n\n        common.each(family.conversions, function(conversion, conversionName) {\n\n          result = conversion.read(original);\n\n          if (toReturn === false && result !== false) {\n            toReturn = result;\n            result.conversionName = conversionName;\n            result.conversion = conversion;\n            return common.BREAK;\n\n          }\n\n        });\n\n        return common.BREAK;\n\n      }\n\n    });\n\n    return toReturn;\n\n  };\n\n  var INTERPRETATIONS = [\n\n    // Strings\n    {\n\n      litmus: common.isString,\n\n      conversions: {\n\n        THREE_CHAR_HEX: {\n\n          read: function(original) {\n\n            var test = original.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);\n            if (test === null) return false;\n\n            return {\n              space: 'HEX',\n              hex: parseInt(\n                  '0x' +\n                      test[1].toString() + test[1].toString() +\n                      test[2].toString() + test[2].toString() +\n                      test[3].toString() + test[3].toString())\n            };\n\n          },\n\n          write: toString\n\n        },\n\n        SIX_CHAR_HEX: {\n\n          read: function(original) {\n\n            var test = original.match(/^#([A-F0-9]{6})$/i);\n            if (test === null) return false;\n\n            return {\n              space: 'HEX',\n              hex: parseInt('0x' + test[1].toString())\n            };\n\n          },\n\n          write: toString\n\n        },\n\n        CSS_RGB: {\n\n          read: function(original) {\n\n            var test = original.match(/^rgb\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\)/);\n            if (test === null) return false;\n\n            return {\n              space: 'RGB',\n              r: parseFloat(test[1]),\n              g: parseFloat(test[2]),\n              b: parseFloat(test[3])\n            };\n\n          },\n\n          write: toString\n\n        },\n\n        CSS_RGBA: {\n\n          read: function(original) {\n\n            var test = original.match(/^rgba\\(\\s*(.+)\\s*,\\s*(.+)\\s*,\\s*(.+)\\s*\\,\\s*(.+)\\s*\\)/);\n            if (test === null) return false;\n\n            return {\n              space: 'RGB',\n              r: parseFloat(test[1]),\n              g: parseFloat(test[2]),\n              b: parseFloat(test[3]),\n              a: parseFloat(test[4])\n            };\n\n          },\n\n          write: toString\n\n        }\n\n      }\n\n    },\n\n    // Numbers\n    {\n\n      litmus: common.isNumber,\n\n      conversions: {\n\n        HEX: {\n          read: function(original) {\n            return {\n              space: 'HEX',\n              hex: original,\n              conversionName: 'HEX'\n            }\n          },\n\n          write: function(color) {\n            return color.hex;\n          }\n        }\n\n      }\n\n    },\n\n    // Arrays\n    {\n\n      litmus: common.isArray,\n\n      conversions: {\n\n        RGB_ARRAY: {\n          read: function(original) {\n            if (original.length != 3) return false;\n            return {\n              space: 'RGB',\n              r: original[0],\n              g: original[1],\n              b: original[2]\n            };\n          },\n\n          write: function(color) {\n            return [color.r, color.g, color.b];\n          }\n\n        },\n\n        RGBA_ARRAY: {\n          read: function(original) {\n            if (original.length != 4) return false;\n            return {\n              space: 'RGB',\n              r: original[0],\n              g: original[1],\n              b: original[2],\n              a: original[3]\n            };\n          },\n\n          write: function(color) {\n            return [color.r, color.g, color.b, color.a];\n          }\n\n        }\n\n      }\n\n    },\n\n    // Objects\n    {\n\n      litmus: common.isObject,\n\n      conversions: {\n\n        RGBA_OBJ: {\n          read: function(original) {\n            if (common.isNumber(original.r) &&\n                common.isNumber(original.g) &&\n                common.isNumber(original.b) &&\n                common.isNumber(original.a)) {\n              return {\n                space: 'RGB',\n                r: original.r,\n                g: original.g,\n                b: original.b,\n                a: original.a\n              }\n            }\n            return false;\n          },\n\n          write: function(color) {\n            return {\n              r: color.r,\n              g: color.g,\n              b: color.b,\n              a: color.a\n            }\n          }\n        },\n\n        RGB_OBJ: {\n          read: function(original) {\n            if (common.isNumber(original.r) &&\n                common.isNumber(original.g) &&\n                common.isNumber(original.b)) {\n              return {\n                space: 'RGB',\n                r: original.r,\n                g: original.g,\n                b: original.b\n              }\n            }\n            return false;\n          },\n\n          write: function(color) {\n            return {\n              r: color.r,\n              g: color.g,\n              b: color.b\n            }\n          }\n        },\n\n        HSVA_OBJ: {\n          read: function(original) {\n            if (common.isNumber(original.h) &&\n                common.isNumber(original.s) &&\n                common.isNumber(original.v) &&\n                common.isNumber(original.a)) {\n              return {\n                space: 'HSV',\n                h: original.h,\n                s: original.s,\n                v: original.v,\n                a: original.a\n              }\n            }\n            return false;\n          },\n\n          write: function(color) {\n            return {\n              h: color.h,\n              s: color.s,\n              v: color.v,\n              a: color.a\n            }\n          }\n        },\n\n        HSV_OBJ: {\n          read: function(original) {\n            if (common.isNumber(original.h) &&\n                common.isNumber(original.s) &&\n                common.isNumber(original.v)) {\n              return {\n                space: 'HSV',\n                h: original.h,\n                s: original.s,\n                v: original.v\n              }\n            }\n            return false;\n          },\n\n          write: function(color) {\n            return {\n              h: color.h,\n              s: color.s,\n              v: color.v\n            }\n          }\n\n        }\n\n      }\n\n    }\n\n\n  ];\n\n  return interpret;\n\n\n})(dat.color.toString,\ndat.utils.common);\n\n\ndat.GUI = dat.gui.GUI = (function (css, saveDialogueContents, styleSheet, controllerFactory, Controller, BooleanController, FunctionController, NumberControllerBox, NumberControllerSlider, OptionController, ColorController, requestAnimationFrame, CenteredDiv, dom, common) {\n\n  css.inject(styleSheet);\n\n  /** Outer-most className for GUI's */\n  var CSS_NAMESPACE = 'dg';\n\n  var HIDE_KEY_CODE = 72;\n\n  /** The only value shared between the JS and SCSS. Use caution. */\n  var CLOSE_BUTTON_HEIGHT = 20;\n\n  var DEFAULT_DEFAULT_PRESET_NAME = 'Default';\n\n  var SUPPORTS_LOCAL_STORAGE = (function() {\n    try {\n      return 'localStorage' in window && window['localStorage'] !== null;\n    } catch (e) {\n      return false;\n    }\n  })();\n\n  var SAVE_DIALOGUE;\n\n  /** Have we yet to create an autoPlace GUI? */\n  var auto_place_virgin = true;\n\n  /** Fixed position div that auto place GUI's go inside */\n  var auto_place_container;\n\n  /** Are we hiding the GUI's ? */\n  var hide = false;\n\n  /** GUI's which should be hidden */\n  var hideable_guis = [];\n\n  /**\n   * A lightweight controller library for JavaScript. It allows you to easily\n   * manipulate variables and fire functions on the fly.\n   * @class\n   *\n   * @member dat.gui\n   *\n   * @param {Object} [params]\n   * @param {String} [params.name] The name of this GUI.\n   * @param {Object} [params.load] JSON object representing the saved state of\n   * this GUI.\n   * @param {Boolean} [params.auto=true]\n   * @param {dat.gui.GUI} [params.parent] The GUI I'm nested in.\n   * @param {Boolean} [params.closed] If true, starts closed\n   */\n  var GUI = function(params) {\n\n    var _this = this;\n\n    /**\n     * Outermost DOM Element\n     * @type DOMElement\n     */\n    this.domElement = document.createElement('div');\n    this.__ul = document.createElement('ul');\n    this.domElement.appendChild(this.__ul);\n\n    dom.addClass(this.domElement, CSS_NAMESPACE);\n\n    /**\n     * Nested GUI's by name\n     * @ignore\n     */\n    this.__folders = {};\n\n    this.__controllers = [];\n\n    /**\n     * List of objects I'm remembering for save, only used in top level GUI\n     * @ignore\n     */\n    this.__rememberedObjects = [];\n\n    /**\n     * Maps the index of remembered objects to a map of controllers, only used\n     * in top level GUI.\n     *\n     * @private\n     * @ignore\n     *\n     * @example\n     * [\n     *  {\n     *    propertyName: Controller,\n     *    anotherPropertyName: Controller\n     *  },\n     *  {\n     *    propertyName: Controller\n     *  }\n     * ]\n     */\n    this.__rememberedObjectIndecesToControllers = [];\n\n    this.__listening = [];\n\n    params = params || {};\n\n    // Default parameters\n    params = common.defaults(params, {\n      autoPlace: true,\n      width: GUI.DEFAULT_WIDTH\n    });\n\n    params = common.defaults(params, {\n      resizable: params.autoPlace,\n      hideable: params.autoPlace\n    });\n\n\n    if (!common.isUndefined(params.load)) {\n\n      // Explicit preset\n      if (params.preset) params.load.preset = params.preset;\n\n    } else {\n\n      params.load = { preset: DEFAULT_DEFAULT_PRESET_NAME };\n\n    }\n\n    if (common.isUndefined(params.parent) && params.hideable) {\n      hideable_guis.push(this);\n    }\n\n    // Only root level GUI's are resizable.\n    params.resizable = common.isUndefined(params.parent) && params.resizable;\n\n\n    if (params.autoPlace && common.isUndefined(params.scrollable)) {\n      params.scrollable = true;\n    }\n//    params.scrollable = common.isUndefined(params.parent) && params.scrollable === true;\n\n    // Not part of params because I don't want people passing this in via\n    // constructor. Should be a 'remembered' value.\n    var use_local_storage =\n        SUPPORTS_LOCAL_STORAGE &&\n            localStorage.getItem(getLocalStorageHash(this, 'isLocal')) === 'true';\n\n    Object.defineProperties(this,\n\n        /** @lends dat.gui.GUI.prototype */\n        {\n\n          /**\n           * The parent <code>GUI</code>\n           * @type dat.gui.GUI\n           */\n          parent: {\n            get: function() {\n              return params.parent;\n            }\n          },\n\n          scrollable: {\n            get: function() {\n              return params.scrollable;\n            }\n          },\n\n          /**\n           * Handles <code>GUI</code>'s element placement for you\n           * @type Boolean\n           */\n          autoPlace: {\n            get: function() {\n              return params.autoPlace;\n            }\n          },\n\n          /**\n           * The identifier for a set of saved values\n           * @type String\n           */\n          preset: {\n\n            get: function() {\n              if (_this.parent) {\n                return _this.getRoot().preset;\n              } else {\n                return params.load.preset;\n              }\n            },\n\n            set: function(v) {\n              if (_this.parent) {\n                _this.getRoot().preset = v;\n              } else {\n                params.load.preset = v;\n              }\n              setPresetSelectIndex(this);\n              _this.revert();\n            }\n\n          },\n\n          /**\n           * The width of <code>GUI</code> element\n           * @type Number\n           */\n          width: {\n            get: function() {\n              return params.width;\n            },\n            set: function(v) {\n              params.width = v;\n              setWidth(_this, v);\n            }\n          },\n\n          /**\n           * The name of <code>GUI</code>. Used for folders. i.e\n           * a folder's name\n           * @type String\n           */\n          name: {\n            get: function() {\n              return params.name;\n            },\n            set: function(v) {\n              // TODO Check for collisions among sibling folders\n              params.name = v;\n              if (title_row_name) {\n                title_row_name.innerHTML = params.name;\n              }\n            }\n          },\n\n          /**\n           * Whether the <code>GUI</code> is collapsed or not\n           * @type Boolean\n           */\n          closed: {\n            get: function() {\n              return params.closed;\n            },\n            set: function(v) {\n              params.closed = v;\n              if (params.closed) {\n                dom.addClass(_this.__ul, GUI.CLASS_CLOSED);\n              } else {\n                dom.removeClass(_this.__ul, GUI.CLASS_CLOSED);\n              }\n              // For browsers that aren't going to respect the CSS transition,\n              // Lets just check our height against the window height right off\n              // the bat.\n              this.onResize();\n\n              if (_this.__closeButton) {\n                _this.__closeButton.innerHTML = v ? GUI.TEXT_OPEN : GUI.TEXT_CLOSED;\n              }\n            }\n          },\n\n          /**\n           * Contains all presets\n           * @type Object\n           */\n          load: {\n            get: function() {\n              return params.load;\n            }\n          },\n\n          /**\n           * Determines whether or not to use <a href=\"https://developer.mozilla.org/en/DOM/Storage#localStorage\">localStorage</a> as the means for\n           * <code>remember</code>ing\n           * @type Boolean\n           */\n          useLocalStorage: {\n\n            get: function() {\n              return use_local_storage;\n            },\n            set: function(bool) {\n              if (SUPPORTS_LOCAL_STORAGE) {\n                use_local_storage = bool;\n                if (bool) {\n                  dom.bind(window, 'unload', saveToLocalStorage);\n                } else {\n                  dom.unbind(window, 'unload', saveToLocalStorage);\n                }\n                localStorage.setItem(getLocalStorageHash(_this, 'isLocal'), bool);\n              }\n            }\n\n          }\n\n        });\n\n    // Are we a root level GUI?\n    if (common.isUndefined(params.parent)) {\n\n      params.closed = false;\n\n      dom.addClass(this.domElement, GUI.CLASS_MAIN);\n      dom.makeSelectable(this.domElement, false);\n\n      // Are we supposed to be loading locally?\n      if (SUPPORTS_LOCAL_STORAGE) {\n\n        if (use_local_storage) {\n\n          _this.useLocalStorage = true;\n\n          var saved_gui = localStorage.getItem(getLocalStorageHash(this, 'gui'));\n\n          if (saved_gui) {\n            params.load = JSON.parse(saved_gui);\n          }\n\n        }\n\n      }\n\n      this.__closeButton = document.createElement('div');\n      this.__closeButton.innerHTML = GUI.TEXT_CLOSED;\n      dom.addClass(this.__closeButton, GUI.CLASS_CLOSE_BUTTON);\n      this.domElement.appendChild(this.__closeButton);\n\n      dom.bind(this.__closeButton, 'click', function() {\n\n        _this.closed = !_this.closed;\n\n\n      });\n\n\n      // Oh, you're a nested GUI!\n    } else {\n\n      if (params.closed === undefined) {\n        params.closed = true;\n      }\n\n      var title_row_name = document.createTextNode(params.name);\n      dom.addClass(title_row_name, 'controller-name');\n\n      var title_row = addRow(_this, title_row_name);\n\n      var on_click_title = function(e) {\n        e.preventDefault();\n        _this.closed = !_this.closed;\n        return false;\n      };\n\n      dom.addClass(this.__ul, GUI.CLASS_CLOSED);\n\n      dom.addClass(title_row, 'title');\n      dom.bind(title_row, 'click', on_click_title);\n\n      if (!params.closed) {\n        this.closed = false;\n      }\n\n    }\n\n    if (params.autoPlace) {\n\n      if (common.isUndefined(params.parent)) {\n\n        if (auto_place_virgin) {\n          auto_place_container = document.createElement('div');\n          dom.addClass(auto_place_container, CSS_NAMESPACE);\n          dom.addClass(auto_place_container, GUI.CLASS_AUTO_PLACE_CONTAINER);\n          document.body.appendChild(auto_place_container);\n          auto_place_virgin = false;\n        }\n\n        // Put it in the dom for you.\n        auto_place_container.appendChild(this.domElement);\n\n        // Apply the auto styles\n        dom.addClass(this.domElement, GUI.CLASS_AUTO_PLACE);\n\n      }\n\n\n      // Make it not elastic.\n      if (!this.parent) setWidth(_this, params.width);\n\n    }\n\n    dom.bind(window, 'resize', function() { _this.onResize() });\n    dom.bind(this.__ul, 'webkitTransitionEnd', function() { _this.onResize(); });\n    dom.bind(this.__ul, 'transitionend', function() { _this.onResize() });\n    dom.bind(this.__ul, 'oTransitionEnd', function() { _this.onResize() });\n    this.onResize();\n\n\n    if (params.resizable) {\n      addResizeHandle(this);\n    }\n\n    function saveToLocalStorage() {\n      localStorage.setItem(getLocalStorageHash(_this, 'gui'), JSON.stringify(_this.getSaveObject()));\n    }\n\n    var root = _this.getRoot();\n    function resetWidth() {\n        var root = _this.getRoot();\n        root.width += 1;\n        common.defer(function() {\n          root.width -= 1;\n        });\n      }\n\n      if (!params.parent) {\n        resetWidth();\n      }\n\n  };\n\n  GUI.toggleHide = function() {\n\n    hide = !hide;\n    common.each(hideable_guis, function(gui) {\n      gui.domElement.style.zIndex = hide ? -999 : 999;\n      gui.domElement.style.opacity = hide ? 0 : 1;\n    });\n  };\n\n  GUI.CLASS_AUTO_PLACE = 'a';\n  GUI.CLASS_AUTO_PLACE_CONTAINER = 'ac';\n  GUI.CLASS_MAIN = 'main';\n  GUI.CLASS_CONTROLLER_ROW = 'cr';\n  GUI.CLASS_TOO_TALL = 'taller-than-window';\n  GUI.CLASS_CLOSED = 'closed';\n  GUI.CLASS_CLOSE_BUTTON = 'close-button';\n  GUI.CLASS_DRAG = 'drag';\n\n  GUI.DEFAULT_WIDTH = 245;\n  GUI.TEXT_CLOSED = 'Close Controls';\n  GUI.TEXT_OPEN = 'Open Controls';\n\n  dom.bind(window, 'keydown', function(e) {\n\n    if (document.activeElement.type !== 'text' &&\n        (e.which === HIDE_KEY_CODE || e.keyCode == HIDE_KEY_CODE)) {\n      GUI.toggleHide();\n    }\n\n  }, false);\n\n  common.extend(\n\n      GUI.prototype,\n\n      /** @lends dat.gui.GUI */\n      {\n\n        /**\n         * @param object\n         * @param property\n         * @returns {dat.controllers.Controller} The new controller that was added.\n         * @instance\n         */\n        add: function(object, property) {\n\n          return add(\n              this,\n              object,\n              property,\n              {\n                factoryArgs: Array.prototype.slice.call(arguments, 2)\n              }\n          );\n\n        },\n\n        /**\n         * @param object\n         * @param property\n         * @returns {dat.controllers.ColorController} The new controller that was added.\n         * @instance\n         */\n        addColor: function(object, property) {\n\n          return add(\n              this,\n              object,\n              property,\n              {\n                color: true\n              }\n          );\n\n        },\n\n        /**\n         * @param controller\n         * @instance\n         */\n        remove: function(controller) {\n\n          // TODO listening?\n          this.__ul.removeChild(controller.__li);\n          this.__controllers.slice(this.__controllers.indexOf(controller), 1);\n          var _this = this;\n          common.defer(function() {\n            _this.onResize();\n          });\n\n        },\n\n        destroy: function() {\n\n          if (this.autoPlace) {\n            auto_place_container.removeChild(this.domElement);\n          }\n\n        },\n\n        /**\n         * @param name\n         * @returns {dat.gui.GUI} The new folder.\n         * @throws {Error} if this GUI already has a folder by the specified\n         * name\n         * @instance\n         */\n        addFolder: function(name) {\n\n          // We have to prevent collisions on names in order to have a key\n          // by which to remember saved values\n          if (this.__folders[name] !== undefined) {\n            throw new Error('You already have a folder in this GUI by the' +\n                ' name \"' + name + '\"');\n          }\n\n          var new_gui_params = { name: name, parent: this };\n\n          // We need to pass down the autoPlace trait so that we can\n          // attach event listeners to open/close folder actions to\n          // ensure that a scrollbar appears if the window is too short.\n          new_gui_params.autoPlace = this.autoPlace;\n\n          // Do we have saved appearance data for this folder?\n\n          if (this.load && // Anything loaded?\n              this.load.folders && // Was my parent a dead-end?\n              this.load.folders[name]) { // Did daddy remember me?\n\n            // Start me closed if I was closed\n            new_gui_params.closed = this.load.folders[name].closed;\n\n            // Pass down the loaded data\n            new_gui_params.load = this.load.folders[name];\n\n          }\n\n          var gui = new GUI(new_gui_params);\n          this.__folders[name] = gui;\n\n          var li = addRow(this, gui.domElement);\n          dom.addClass(li, 'folder');\n          return gui;\n\n        },\n\n        open: function() {\n          this.closed = false;\n        },\n\n        close: function() {\n          this.closed = true;\n        },\n\n        onResize: function() {\n\n          var root = this.getRoot();\n\n          if (root.scrollable) {\n\n            var top = dom.getOffset(root.__ul).top;\n            var h = 0;\n\n            common.each(root.__ul.childNodes, function(node) {\n              if (! (root.autoPlace && node === root.__save_row))\n                h += dom.getHeight(node);\n            });\n\n            if (window.innerHeight - top - CLOSE_BUTTON_HEIGHT < h) {\n              dom.addClass(root.domElement, GUI.CLASS_TOO_TALL);\n              root.__ul.style.height = window.innerHeight - top - CLOSE_BUTTON_HEIGHT + 'px';\n            } else {\n              dom.removeClass(root.domElement, GUI.CLASS_TOO_TALL);\n              root.__ul.style.height = 'auto';\n            }\n\n          }\n\n          if (root.__resize_handle) {\n            common.defer(function() {\n              root.__resize_handle.style.height = root.__ul.offsetHeight + 'px';\n            });\n          }\n\n          if (root.__closeButton) {\n            root.__closeButton.style.width = root.width + 'px';\n          }\n\n        },\n\n        /**\n         * Mark objects for saving. The order of these objects cannot change as\n         * the GUI grows. When remembering new objects, append them to the end\n         * of the list.\n         *\n         * @param {Object...} objects\n         * @throws {Error} if not called on a top level GUI.\n         * @instance\n         */\n        remember: function() {\n\n          if (common.isUndefined(SAVE_DIALOGUE)) {\n            SAVE_DIALOGUE = new CenteredDiv();\n            SAVE_DIALOGUE.domElement.innerHTML = saveDialogueContents;\n          }\n\n          if (this.parent) {\n            throw new Error(\"You can only call remember on a top level GUI.\");\n          }\n\n          var _this = this;\n\n          common.each(Array.prototype.slice.call(arguments), function(object) {\n            if (_this.__rememberedObjects.length == 0) {\n              addSaveMenu(_this);\n            }\n            if (_this.__rememberedObjects.indexOf(object) == -1) {\n              _this.__rememberedObjects.push(object);\n            }\n          });\n\n          if (this.autoPlace) {\n            // Set save row width\n            setWidth(this, this.width);\n          }\n\n        },\n\n        /**\n         * @returns {dat.gui.GUI} the topmost parent GUI of a nested GUI.\n         * @instance\n         */\n        getRoot: function() {\n          var gui = this;\n          while (gui.parent) {\n            gui = gui.parent;\n          }\n          return gui;\n        },\n\n        /**\n         * @returns {Object} a JSON object representing the current state of\n         * this GUI as well as its remembered properties.\n         * @instance\n         */\n        getSaveObject: function() {\n\n          var toReturn = this.load;\n\n          toReturn.closed = this.closed;\n\n          // Am I remembering any values?\n          if (this.__rememberedObjects.length > 0) {\n\n            toReturn.preset = this.preset;\n\n            if (!toReturn.remembered) {\n              toReturn.remembered = {};\n            }\n\n            toReturn.remembered[this.preset] = getCurrentPreset(this);\n\n          }\n\n          toReturn.folders = {};\n          common.each(this.__folders, function(element, key) {\n            toReturn.folders[key] = element.getSaveObject();\n          });\n\n          return toReturn;\n\n        },\n\n        save: function() {\n\n          if (!this.load.remembered) {\n            this.load.remembered = {};\n          }\n\n          this.load.remembered[this.preset] = getCurrentPreset(this);\n          markPresetModified(this, false);\n\n        },\n\n        saveAs: function(presetName) {\n\n          if (!this.load.remembered) {\n\n            // Retain default values upon first save\n            this.load.remembered = {};\n            this.load.remembered[DEFAULT_DEFAULT_PRESET_NAME] = getCurrentPreset(this, true);\n\n          }\n\n          this.load.remembered[presetName] = getCurrentPreset(this);\n          this.preset = presetName;\n          addPresetOption(this, presetName, true);\n\n        },\n\n        revert: function(gui) {\n\n          common.each(this.__controllers, function(controller) {\n            // Make revert work on Default.\n            if (!this.getRoot().load.remembered) {\n              controller.setValue(controller.initialValue);\n            } else {\n              recallSavedValue(gui || this.getRoot(), controller);\n            }\n          }, this);\n\n          common.each(this.__folders, function(folder) {\n            folder.revert(folder);\n          });\n\n          if (!gui) {\n            markPresetModified(this.getRoot(), false);\n          }\n\n\n        },\n\n        listen: function(controller) {\n\n          var init = this.__listening.length == 0;\n          this.__listening.push(controller);\n          if (init) updateDisplays(this.__listening);\n\n        }\n\n      }\n\n  );\n\n  function add(gui, object, property, params) {\n\n    if (object[property] === undefined) {\n      throw new Error(\"Object \" + object + \" has no property \\\"\" + property + \"\\\"\");\n    }\n\n    var controller;\n\n    if (params.color) {\n\n      controller = new ColorController(object, property);\n\n    } else {\n\n      var factoryArgs = [object,property].concat(params.factoryArgs);\n      controller = controllerFactory.apply(gui, factoryArgs);\n\n    }\n\n    if (params.before instanceof Controller) {\n      params.before = params.before.__li;\n    }\n\n    recallSavedValue(gui, controller);\n\n    dom.addClass(controller.domElement, 'c');\n\n    var name = document.createElement('span');\n    dom.addClass(name, 'property-name');\n    name.innerHTML = controller.property;\n\n    var container = document.createElement('div');\n    container.appendChild(name);\n    container.appendChild(controller.domElement);\n\n    var li = addRow(gui, container, params.before);\n\n    dom.addClass(li, GUI.CLASS_CONTROLLER_ROW);\n    dom.addClass(li, typeof controller.getValue());\n\n    augmentController(gui, li, controller);\n\n    gui.__controllers.push(controller);\n\n    return controller;\n\n  }\n\n  /**\n   * Add a row to the end of the GUI or before another row.\n   *\n   * @param gui\n   * @param [dom] If specified, inserts the dom content in the new row\n   * @param [liBefore] If specified, places the new row before another row\n   */\n  function addRow(gui, dom, liBefore) {\n    var li = document.createElement('li');\n    if (dom) li.appendChild(dom);\n    if (liBefore) {\n      gui.__ul.insertBefore(li, params.before);\n    } else {\n      gui.__ul.appendChild(li);\n    }\n    gui.onResize();\n    return li;\n  }\n\n  function augmentController(gui, li, controller) {\n\n    controller.__li = li;\n    controller.__gui = gui;\n\n    common.extend(controller, {\n\n      options: function(options) {\n\n        if (arguments.length > 1) {\n          controller.remove();\n\n          return add(\n              gui,\n              controller.object,\n              controller.property,\n              {\n                before: controller.__li.nextElementSibling,\n                factoryArgs: [common.toArray(arguments)]\n              }\n          );\n\n        }\n\n        if (common.isArray(options) || common.isObject(options)) {\n          controller.remove();\n\n          return add(\n              gui,\n              controller.object,\n              controller.property,\n              {\n                before: controller.__li.nextElementSibling,\n                factoryArgs: [options]\n              }\n          );\n\n        }\n\n      },\n\n      name: function(v) {\n        controller.__li.firstElementChild.firstElementChild.innerHTML = v;\n        return controller;\n      },\n\n      listen: function() {\n        controller.__gui.listen(controller);\n        return controller;\n      },\n\n      remove: function() {\n        controller.__gui.remove(controller);\n        return controller;\n      }\n\n    });\n\n    // All sliders should be accompanied by a box.\n    if (controller instanceof NumberControllerSlider) {\n\n      var box = new NumberControllerBox(controller.object, controller.property,\n          { min: controller.__min, max: controller.__max, step: controller.__step });\n\n      common.each(['updateDisplay', 'onChange', 'onFinishChange'], function(method) {\n        var pc = controller[method];\n        var pb = box[method];\n        controller[method] = box[method] = function() {\n          var args = Array.prototype.slice.call(arguments);\n          pc.apply(controller, args);\n          return pb.apply(box, args);\n        }\n      });\n\n      dom.addClass(li, 'has-slider');\n      controller.domElement.insertBefore(box.domElement, controller.domElement.firstElementChild);\n\n    }\n    else if (controller instanceof NumberControllerBox) {\n\n      var r = function(returned) {\n\n        // Have we defined both boundaries?\n        if (common.isNumber(controller.__min) && common.isNumber(controller.__max)) {\n\n          // Well, then lets just replace this with a slider.\n          controller.remove();\n          return add(\n              gui,\n              controller.object,\n              controller.property,\n              {\n                before: controller.__li.nextElementSibling,\n                factoryArgs: [controller.__min, controller.__max, controller.__step]\n              });\n\n        }\n\n        return returned;\n\n      };\n\n      controller.min = common.compose(r, controller.min);\n      controller.max = common.compose(r, controller.max);\n\n    }\n    else if (controller instanceof BooleanController) {\n\n      dom.bind(li, 'click', function() {\n        dom.fakeEvent(controller.__checkbox, 'click');\n      });\n\n      dom.bind(controller.__checkbox, 'click', function(e) {\n        e.stopPropagation(); // Prevents double-toggle\n      })\n\n    }\n    else if (controller instanceof FunctionController) {\n\n      dom.bind(li, 'click', function() {\n        dom.fakeEvent(controller.__button, 'click');\n      });\n\n      dom.bind(li, 'mouseover', function() {\n        dom.addClass(controller.__button, 'hover');\n      });\n\n      dom.bind(li, 'mouseout', function() {\n        dom.removeClass(controller.__button, 'hover');\n      });\n\n    }\n    else if (controller instanceof ColorController) {\n\n      dom.addClass(li, 'color');\n      controller.updateDisplay = common.compose(function(r) {\n        li.style.borderLeftColor = controller.__color.toString();\n        return r;\n      }, controller.updateDisplay);\n\n      controller.updateDisplay();\n\n    }\n\n    controller.setValue = common.compose(function(r) {\n      if (gui.getRoot().__preset_select && controller.isModified()) {\n        markPresetModified(gui.getRoot(), true);\n      }\n      return r;\n    }, controller.setValue);\n\n  }\n\n  function recallSavedValue(gui, controller) {\n\n    // Find the topmost GUI, that's where remembered objects live.\n    var root = gui.getRoot();\n\n    // Does the object we're controlling match anything we've been told to\n    // remember?\n    var matched_index = root.__rememberedObjects.indexOf(controller.object);\n\n    // Why yes, it does!\n    if (matched_index != -1) {\n\n      // Let me fetch a map of controllers for thcommon.isObject.\n      var controller_map =\n          root.__rememberedObjectIndecesToControllers[matched_index];\n\n      // Ohp, I believe this is the first controller we've created for this\n      // object. Lets make the map fresh.\n      if (controller_map === undefined) {\n        controller_map = {};\n        root.__rememberedObjectIndecesToControllers[matched_index] =\n            controller_map;\n      }\n\n      // Keep track of this controller\n      controller_map[controller.property] = controller;\n\n      // Okay, now have we saved any values for this controller?\n      if (root.load && root.load.remembered) {\n\n        var preset_map = root.load.remembered;\n\n        // Which preset are we trying to load?\n        var preset;\n\n        if (preset_map[gui.preset]) {\n\n          preset = preset_map[gui.preset];\n\n        } else if (preset_map[DEFAULT_DEFAULT_PRESET_NAME]) {\n\n          // Uhh, you can have the default instead?\n          preset = preset_map[DEFAULT_DEFAULT_PRESET_NAME];\n\n        } else {\n\n          // Nada.\n\n          return;\n\n        }\n\n\n        // Did the loaded object remember thcommon.isObject?\n        if (preset[matched_index] &&\n\n          // Did we remember this particular property?\n            preset[matched_index][controller.property] !== undefined) {\n\n          // We did remember something for this guy ...\n          var value = preset[matched_index][controller.property];\n\n          // And that's what it is.\n          controller.initialValue = value;\n          controller.setValue(value);\n\n        }\n\n      }\n\n    }\n\n  }\n\n  function getLocalStorageHash(gui, key) {\n    // TODO how does this deal with multiple GUI's?\n    return document.location.href + '.' + key;\n\n  }\n\n  function addSaveMenu(gui) {\n\n    var div = gui.__save_row = document.createElement('li');\n\n    dom.addClass(gui.domElement, 'has-save');\n\n    gui.__ul.insertBefore(div, gui.__ul.firstChild);\n\n    dom.addClass(div, 'save-row');\n\n    var gears = document.createElement('span');\n    gears.innerHTML = '&nbsp;';\n    dom.addClass(gears, 'button gears');\n\n    // TODO replace with FunctionController\n    var button = document.createElement('span');\n    button.innerHTML = 'Save';\n    dom.addClass(button, 'button');\n    dom.addClass(button, 'save');\n\n    var button2 = document.createElement('span');\n    button2.innerHTML = 'New';\n    dom.addClass(button2, 'button');\n    dom.addClass(button2, 'save-as');\n\n    var button3 = document.createElement('span');\n    button3.innerHTML = 'Revert';\n    dom.addClass(button3, 'button');\n    dom.addClass(button3, 'revert');\n\n    var select = gui.__preset_select = document.createElement('select');\n\n    if (gui.load && gui.load.remembered) {\n\n      common.each(gui.load.remembered, function(value, key) {\n        addPresetOption(gui, key, key == gui.preset);\n      });\n\n    } else {\n      addPresetOption(gui, DEFAULT_DEFAULT_PRESET_NAME, false);\n    }\n\n    dom.bind(select, 'change', function() {\n\n\n      for (var index = 0; index < gui.__preset_select.length; index++) {\n        gui.__preset_select[index].innerHTML = gui.__preset_select[index].value;\n      }\n\n      gui.preset = this.value;\n\n    });\n\n    div.appendChild(select);\n    div.appendChild(gears);\n    div.appendChild(button);\n    div.appendChild(button2);\n    div.appendChild(button3);\n\n    if (SUPPORTS_LOCAL_STORAGE) {\n\n      var saveLocally = document.getElementById('dg-save-locally');\n      var explain = document.getElementById('dg-local-explain');\n\n      saveLocally.style.display = 'block';\n\n      var localStorageCheckBox = document.getElementById('dg-local-storage');\n\n      if (localStorage.getItem(getLocalStorageHash(gui, 'isLocal')) === 'true') {\n        localStorageCheckBox.setAttribute('checked', 'checked');\n      }\n\n      function showHideExplain() {\n        explain.style.display = gui.useLocalStorage ? 'block' : 'none';\n      }\n\n      showHideExplain();\n\n      // TODO: Use a boolean controller, fool!\n      dom.bind(localStorageCheckBox, 'change', function() {\n        gui.useLocalStorage = !gui.useLocalStorage;\n        showHideExplain();\n      });\n\n    }\n\n    var newConstructorTextArea = document.getElementById('dg-new-constructor');\n\n    dom.bind(newConstructorTextArea, 'keydown', function(e) {\n      if (e.metaKey && (e.which === 67 || e.keyCode == 67)) {\n        SAVE_DIALOGUE.hide();\n      }\n    });\n\n    dom.bind(gears, 'click', function() {\n      newConstructorTextArea.innerHTML = JSON.stringify(gui.getSaveObject(), undefined, 2);\n      SAVE_DIALOGUE.show();\n      newConstructorTextArea.focus();\n      newConstructorTextArea.select();\n    });\n\n    dom.bind(button, 'click', function() {\n      gui.save();\n    });\n\n    dom.bind(button2, 'click', function() {\n      var presetName = prompt('Enter a new preset name.');\n      if (presetName) gui.saveAs(presetName);\n    });\n\n    dom.bind(button3, 'click', function() {\n      gui.revert();\n    });\n\n//    div.appendChild(button2);\n\n  }\n\n  function addResizeHandle(gui) {\n\n    gui.__resize_handle = document.createElement('div');\n\n    common.extend(gui.__resize_handle.style, {\n\n      width: '6px',\n      marginLeft: '-3px',\n      height: '200px',\n      cursor: 'ew-resize',\n      position: 'absolute'\n//      border: '1px solid blue'\n\n    });\n\n    var pmouseX;\n\n    dom.bind(gui.__resize_handle, 'mousedown', dragStart);\n    dom.bind(gui.__closeButton, 'mousedown', dragStart);\n\n    gui.domElement.insertBefore(gui.__resize_handle, gui.domElement.firstElementChild);\n\n    function dragStart(e) {\n\n      e.preventDefault();\n\n      pmouseX = e.clientX;\n\n      dom.addClass(gui.__closeButton, GUI.CLASS_DRAG);\n      dom.bind(window, 'mousemove', drag);\n      dom.bind(window, 'mouseup', dragStop);\n\n      return false;\n\n    }\n\n    function drag(e) {\n\n      e.preventDefault();\n\n      gui.width += pmouseX - e.clientX;\n      gui.onResize();\n      pmouseX = e.clientX;\n\n      return false;\n\n    }\n\n    function dragStop() {\n\n      dom.removeClass(gui.__closeButton, GUI.CLASS_DRAG);\n      dom.unbind(window, 'mousemove', drag);\n      dom.unbind(window, 'mouseup', dragStop);\n\n    }\n\n  }\n\n  function setWidth(gui, w) {\n    gui.domElement.style.width = w + 'px';\n    // Auto placed save-rows are position fixed, so we have to\n    // set the width manually if we want it to bleed to the edge\n    if (gui.__save_row && gui.autoPlace) {\n      gui.__save_row.style.width = w + 'px';\n    }if (gui.__closeButton) {\n      gui.__closeButton.style.width = w + 'px';\n    }\n  }\n\n  function getCurrentPreset(gui, useInitialValues) {\n\n    var toReturn = {};\n\n    // For each object I'm remembering\n    common.each(gui.__rememberedObjects, function(val, index) {\n\n      var saved_values = {};\n\n      // The controllers I've made for thcommon.isObject by property\n      var controller_map =\n          gui.__rememberedObjectIndecesToControllers[index];\n\n      // Remember each value for each property\n      common.each(controller_map, function(controller, property) {\n        saved_values[property] = useInitialValues ? controller.initialValue : controller.getValue();\n      });\n\n      // Save the values for thcommon.isObject\n      toReturn[index] = saved_values;\n\n    });\n\n    return toReturn;\n\n  }\n\n  function addPresetOption(gui, name, setSelected) {\n    var opt = document.createElement('option');\n    opt.innerHTML = name;\n    opt.value = name;\n    gui.__preset_select.appendChild(opt);\n    if (setSelected) {\n      gui.__preset_select.selectedIndex = gui.__preset_select.length - 1;\n    }\n  }\n\n  function setPresetSelectIndex(gui) {\n    for (var index = 0; index < gui.__preset_select.length; index++) {\n      if (gui.__preset_select[index].value == gui.preset) {\n        gui.__preset_select.selectedIndex = index;\n      }\n    }\n  }\n\n  function markPresetModified(gui, modified) {\n    var opt = gui.__preset_select[gui.__preset_select.selectedIndex];\n//    console.log('mark', modified, opt);\n    if (modified) {\n      opt.innerHTML = opt.value + \"*\";\n    } else {\n      opt.innerHTML = opt.value;\n    }\n  }\n\n  function updateDisplays(controllerArray) {\n\n\n    if (controllerArray.length != 0) {\n\n      requestAnimationFrame(function() {\n        updateDisplays(controllerArray);\n      });\n\n    }\n\n    common.each(controllerArray, function(c) {\n      c.updateDisplay();\n    });\n\n  }\n\n  return GUI;\n\n})(dat.utils.css,\n\"<div id=\\\"dg-save\\\" class=\\\"dg dialogue\\\">\\n\\n  Here's the new load parameter for your <code>GUI</code>'s constructor:\\n\\n  <textarea id=\\\"dg-new-constructor\\\"></textarea>\\n\\n  <div id=\\\"dg-save-locally\\\">\\n\\n    <input id=\\\"dg-local-storage\\\" type=\\\"checkbox\\\"/> Automatically save\\n    values to <code>localStorage</code> on exit.\\n\\n    <div id=\\\"dg-local-explain\\\">The values saved to <code>localStorage</code> will\\n      override those passed to <code>dat.GUI</code>'s constructor. This makes it\\n      easier to work incrementally, but <code>localStorage</code> is fragile,\\n      and your friends may not see the same values you do.\\n      \\n    </div>\\n    \\n  </div>\\n\\n</div>\",\n\".dg ul{list-style:none;margin:0;padding:0;width:100%;clear:both}.dg.ac{position:fixed;top:0;left:0;right:0;height:0;z-index:0}.dg:not(.ac) .main{overflow:hidden}.dg.main{-webkit-transition:opacity 0.1s linear;-o-transition:opacity 0.1s linear;-moz-transition:opacity 0.1s linear;transition:opacity 0.1s linear}.dg.main.taller-than-window{overflow-y:auto}.dg.main.taller-than-window .close-button{opacity:1;margin-top:-1px;border-top:1px solid #2c2c2c}.dg.main ul.closed .close-button{opacity:1 !important}.dg.main:hover .close-button,.dg.main .close-button.drag{opacity:1}.dg.main .close-button{-webkit-transition:opacity 0.1s linear;-o-transition:opacity 0.1s linear;-moz-transition:opacity 0.1s linear;transition:opacity 0.1s linear;border:0;position:absolute;line-height:19px;height:20px;cursor:pointer;text-align:center;background-color:#000}.dg.main .close-button:hover{background-color:#111}.dg.a{float:right;margin-right:15px;overflow-x:hidden}.dg.a.has-save ul{margin-top:27px}.dg.a.has-save ul.closed{margin-top:0}.dg.a .save-row{position:fixed;top:0;z-index:1002}.dg li{-webkit-transition:height 0.1s ease-out;-o-transition:height 0.1s ease-out;-moz-transition:height 0.1s ease-out;transition:height 0.1s ease-out}.dg li:not(.folder){cursor:auto;height:27px;line-height:27px;overflow:hidden;padding:0 4px 0 5px}.dg li.folder{padding:0;border-left:4px solid rgba(0,0,0,0)}.dg li.title{cursor:pointer;margin-left:-4px}.dg .closed li:not(.title),.dg .closed ul li,.dg .closed ul li > *{height:0;overflow:hidden;border:0}.dg .cr{clear:both;padding-left:3px;height:27px}.dg .property-name{cursor:default;float:left;clear:left;width:40%;overflow:hidden;text-overflow:ellipsis}.dg .c{float:left;width:60%}.dg .c input[type=text]{border:0;margin-top:4px;padding:3px;width:100%;float:right}.dg .has-slider input[type=text]{width:30%;margin-left:0}.dg .slider{float:left;width:66%;margin-left:-5px;margin-right:0;height:19px;margin-top:4px}.dg .slider-fg{height:100%}.dg .c input[type=checkbox]{margin-top:9px}.dg .c select{margin-top:5px}.dg .cr.function,.dg .cr.function .property-name,.dg .cr.function *,.dg .cr.boolean,.dg .cr.boolean *{cursor:pointer}.dg .selector{display:none;position:absolute;margin-left:-9px;margin-top:23px;z-index:10}.dg .c:hover .selector,.dg .selector.drag{display:block}.dg li.save-row{padding:0}.dg li.save-row .button{display:inline-block;padding:0px 6px}.dg.dialogue{background-color:#222;width:460px;padding:15px;font-size:13px;line-height:15px}#dg-new-constructor{padding:10px;color:#222;font-family:Monaco, monospace;font-size:10px;border:0;resize:none;box-shadow:inset 1px 1px 1px #888;word-wrap:break-word;margin:12px 0;display:block;width:440px;overflow-y:scroll;height:100px;position:relative}#dg-local-explain{display:none;font-size:11px;line-height:17px;border-radius:3px;background-color:#333;padding:8px;margin-top:10px}#dg-local-explain code{font-size:10px}#dat-gui-save-locally{display:none}.dg{color:#eee;font:11px 'Lucida Grande', sans-serif;text-shadow:0 -1px 0 #111}.dg.main::-webkit-scrollbar{width:5px;background:#1a1a1a}.dg.main::-webkit-scrollbar-corner{height:0;display:none}.dg.main::-webkit-scrollbar-thumb{border-radius:5px;background:#676767}.dg li:not(.folder){background:#1a1a1a;border-bottom:1px solid #2c2c2c}.dg li.save-row{line-height:25px;background:#dad5cb;border:0}.dg li.save-row select{margin-left:5px;width:108px}.dg li.save-row .button{margin-left:5px;margin-top:1px;border-radius:2px;font-size:9px;line-height:7px;padding:4px 4px 5px 4px;background:#c5bdad;color:#fff;text-shadow:0 1px 0 #b0a58f;box-shadow:0 -1px 0 #b0a58f;cursor:pointer}.dg li.save-row .button.gears{background:#c5bdad url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAANCAYAAAB/9ZQ7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQJJREFUeNpiYKAU/P//PwGIC/ApCABiBSAW+I8AClAcgKxQ4T9hoMAEUrxx2QSGN6+egDX+/vWT4e7N82AMYoPAx/evwWoYoSYbACX2s7KxCxzcsezDh3evFoDEBYTEEqycggWAzA9AuUSQQgeYPa9fPv6/YWm/Acx5IPb7ty/fw+QZblw67vDs8R0YHyQhgObx+yAJkBqmG5dPPDh1aPOGR/eugW0G4vlIoTIfyFcA+QekhhHJhPdQxbiAIguMBTQZrPD7108M6roWYDFQiIAAv6Aow/1bFwXgis+f2LUAynwoIaNcz8XNx3Dl7MEJUDGQpx9gtQ8YCueB+D26OECAAQDadt7e46D42QAAAABJRU5ErkJggg==) 2px 1px no-repeat;height:7px;width:8px}.dg li.save-row .button:hover{background-color:#bab19e;box-shadow:0 -1px 0 #b0a58f}.dg li.folder{border-bottom:0}.dg li.title{padding-left:16px;background:#000 url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat;cursor:pointer;border-bottom:1px solid rgba(255,255,255,0.2)}.dg .closed li.title{background-image:url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlGIWqMCbWAEAOw==)}.dg .cr.boolean{border-left:3px solid #806787}.dg .cr.function{border-left:3px solid #e61d5f}.dg .cr.number{border-left:3px solid #2fa1d6}.dg .cr.number input[type=text]{color:#2fa1d6}.dg .cr.string{border-left:3px solid #1ed36f}.dg .cr.string input[type=text]{color:#1ed36f}.dg .cr.function:hover,.dg .cr.boolean:hover{background:#111}.dg .c input[type=text]{background:#303030;outline:none}.dg .c input[type=text]:hover{background:#3c3c3c}.dg .c input[type=text]:focus{background:#494949;color:#fff}.dg .c .slider{background:#303030;cursor:ew-resize}.dg .c .slider-fg{background:#2fa1d6}.dg .c .slider:hover{background:#3c3c3c}.dg .c .slider:hover .slider-fg{background:#44abda}\\n\",\ndat.controllers.factory = (function (OptionController, NumberControllerBox, NumberControllerSlider, StringController, FunctionController, BooleanController, common) {\n\n      return function(object, property) {\n\n        var initialValue = object[property];\n\n        // Providing options?\n        if (common.isArray(arguments[2]) || common.isObject(arguments[2])) {\n          return new OptionController(object, property, arguments[2]);\n        }\n\n        // Providing a map?\n\n        if (common.isNumber(initialValue)) {\n\n          if (common.isNumber(arguments[2]) && common.isNumber(arguments[3])) {\n\n            // Has min and max.\n            return new NumberControllerSlider(object, property, arguments[2], arguments[3]);\n\n          } else {\n\n            return new NumberControllerBox(object, property, { min: arguments[2], max: arguments[3] });\n\n          }\n\n        }\n\n        if (common.isString(initialValue)) {\n          return new StringController(object, property);\n        }\n\n        if (common.isFunction(initialValue)) {\n          return new FunctionController(object, property, '');\n        }\n\n        if (common.isBoolean(initialValue)) {\n          return new BooleanController(object, property);\n        }\n\n      }\n\n    })(dat.controllers.OptionController,\ndat.controllers.NumberControllerBox,\ndat.controllers.NumberControllerSlider,\ndat.controllers.StringController = (function (Controller, dom, common) {\n\n  /**\n   * @class Provides a text input to alter the string property of an object.\n   *\n   * @extends dat.controllers.Controller\n   *\n   * @param {Object} object The object to be manipulated\n   * @param {string} property The name of the property to be manipulated\n   *\n   * @member dat.controllers\n   */\n  var StringController = function(object, property) {\n\n    StringController.superclass.call(this, object, property);\n\n    var _this = this;\n\n    this.__input = document.createElement('input');\n    this.__input.setAttribute('type', 'text');\n\n    dom.bind(this.__input, 'keyup', onChange);\n    dom.bind(this.__input, 'change', onChange);\n    dom.bind(this.__input, 'blur', onBlur);\n    dom.bind(this.__input, 'keydown', function(e) {\n      if (e.keyCode === 13) {\n        this.blur();\n      }\n    });\n    \n\n    function onChange() {\n      _this.setValue(_this.__input.value);\n    }\n\n    function onBlur() {\n      if (_this.__onFinishChange) {\n        _this.__onFinishChange.call(_this, _this.getValue());\n      }\n    }\n\n    this.updateDisplay();\n\n    this.domElement.appendChild(this.__input);\n\n  };\n\n  StringController.superclass = Controller;\n\n  common.extend(\n\n      StringController.prototype,\n      Controller.prototype,\n\n      {\n\n        updateDisplay: function() {\n          // Stops the caret from moving on account of:\n          // keyup -> setValue -> updateDisplay\n          if (!dom.isActive(this.__input)) {\n            this.__input.value = this.getValue();\n          }\n          return StringController.superclass.prototype.updateDisplay.call(this);\n        }\n\n      }\n\n  );\n\n  return StringController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.utils.common),\ndat.controllers.FunctionController,\ndat.controllers.BooleanController,\ndat.utils.common),\ndat.controllers.Controller,\ndat.controllers.BooleanController,\ndat.controllers.FunctionController,\ndat.controllers.NumberControllerBox,\ndat.controllers.NumberControllerSlider,\ndat.controllers.OptionController,\ndat.controllers.ColorController = (function (Controller, dom, Color, interpret, common) {\n\n  var ColorController = function(object, property) {\n\n    ColorController.superclass.call(this, object, property);\n\n    this.__color = new Color(this.getValue());\n    this.__temp = new Color(0);\n\n    var _this = this;\n\n    this.domElement = document.createElement('div');\n\n    dom.makeSelectable(this.domElement, false);\n\n    this.__selector = document.createElement('div');\n    this.__selector.className = 'selector';\n\n    this.__saturation_field = document.createElement('div');\n    this.__saturation_field.className = 'saturation-field';\n\n    this.__field_knob = document.createElement('div');\n    this.__field_knob.className = 'field-knob';\n    this.__field_knob_border = '2px solid ';\n\n    this.__hue_knob = document.createElement('div');\n    this.__hue_knob.className = 'hue-knob';\n\n    this.__hue_field = document.createElement('div');\n    this.__hue_field.className = 'hue-field';\n\n    this.__input = document.createElement('input');\n    this.__input.type = 'text';\n    this.__input_textShadow = '0 1px 1px ';\n\n    dom.bind(this.__input, 'keydown', function(e) {\n      if (e.keyCode === 13) { // on enter\n        onBlur.call(this);\n      }\n    });\n\n    dom.bind(this.__input, 'blur', onBlur);\n\n    dom.bind(this.__selector, 'mousedown', function(e) {\n\n      dom\n        .addClass(this, 'drag')\n        .bind(window, 'mouseup', function(e) {\n          dom.removeClass(_this.__selector, 'drag');\n        });\n\n    });\n\n    var value_field = document.createElement('div');\n\n    common.extend(this.__selector.style, {\n      width: '122px',\n      height: '102px',\n      padding: '3px',\n      backgroundColor: '#222',\n      boxShadow: '0px 1px 3px rgba(0,0,0,0.3)'\n    });\n\n    common.extend(this.__field_knob.style, {\n      position: 'absolute',\n      width: '12px',\n      height: '12px',\n      border: this.__field_knob_border + (this.__color.v < .5 ? '#fff' : '#000'),\n      boxShadow: '0px 1px 3px rgba(0,0,0,0.5)',\n      borderRadius: '12px',\n      zIndex: 1\n    });\n    \n    common.extend(this.__hue_knob.style, {\n      position: 'absolute',\n      width: '15px',\n      height: '2px',\n      borderRight: '4px solid #fff',\n      zIndex: 1\n    });\n\n    common.extend(this.__saturation_field.style, {\n      width: '100px',\n      height: '100px',\n      border: '1px solid #555',\n      marginRight: '3px',\n      display: 'inline-block',\n      cursor: 'pointer'\n    });\n\n    common.extend(value_field.style, {\n      width: '100%',\n      height: '100%',\n      background: 'none'\n    });\n    \n    linearGradient(value_field, 'top', 'rgba(0,0,0,0)', '#000');\n\n    common.extend(this.__hue_field.style, {\n      width: '15px',\n      height: '100px',\n      display: 'inline-block',\n      border: '1px solid #555',\n      cursor: 'ns-resize'\n    });\n\n    hueGradient(this.__hue_field);\n\n    common.extend(this.__input.style, {\n      outline: 'none',\n//      width: '120px',\n      textAlign: 'center',\n//      padding: '4px',\n//      marginBottom: '6px',\n      color: '#fff',\n      border: 0,\n      fontWeight: 'bold',\n      textShadow: this.__input_textShadow + 'rgba(0,0,0,0.7)'\n    });\n\n    dom.bind(this.__saturation_field, 'mousedown', fieldDown);\n    dom.bind(this.__field_knob, 'mousedown', fieldDown);\n\n    dom.bind(this.__hue_field, 'mousedown', function(e) {\n      setH(e);\n      dom.bind(window, 'mousemove', setH);\n      dom.bind(window, 'mouseup', unbindH);\n    });\n\n    function fieldDown(e) {\n      setSV(e);\n      // document.body.style.cursor = 'none';\n      dom.bind(window, 'mousemove', setSV);\n      dom.bind(window, 'mouseup', unbindSV);\n    }\n\n    function unbindSV() {\n      dom.unbind(window, 'mousemove', setSV);\n      dom.unbind(window, 'mouseup', unbindSV);\n      // document.body.style.cursor = 'default';\n    }\n\n    function onBlur() {\n      var i = interpret(this.value);\n      if (i !== false) {\n        _this.__color.__state = i;\n        _this.setValue(_this.__color.toOriginal());\n      } else {\n        this.value = _this.__color.toString();\n      }\n    }\n\n    function unbindH() {\n      dom.unbind(window, 'mousemove', setH);\n      dom.unbind(window, 'mouseup', unbindH);\n    }\n\n    this.__saturation_field.appendChild(value_field);\n    this.__selector.appendChild(this.__field_knob);\n    this.__selector.appendChild(this.__saturation_field);\n    this.__selector.appendChild(this.__hue_field);\n    this.__hue_field.appendChild(this.__hue_knob);\n\n    this.domElement.appendChild(this.__input);\n    this.domElement.appendChild(this.__selector);\n\n    this.updateDisplay();\n\n    function setSV(e) {\n\n      e.preventDefault();\n\n      var w = dom.getWidth(_this.__saturation_field);\n      var o = dom.getOffset(_this.__saturation_field);\n      var s = (e.clientX - o.left + document.body.scrollLeft) / w;\n      var v = 1 - (e.clientY - o.top + document.body.scrollTop) / w;\n\n      if (v > 1) v = 1;\n      else if (v < 0) v = 0;\n\n      if (s > 1) s = 1;\n      else if (s < 0) s = 0;\n\n      _this.__color.v = v;\n      _this.__color.s = s;\n\n      _this.setValue(_this.__color.toOriginal());\n\n\n      return false;\n\n    }\n\n    function setH(e) {\n\n      e.preventDefault();\n\n      var s = dom.getHeight(_this.__hue_field);\n      var o = dom.getOffset(_this.__hue_field);\n      var h = 1 - (e.clientY - o.top + document.body.scrollTop) / s;\n\n      if (h > 1) h = 1;\n      else if (h < 0) h = 0;\n\n      _this.__color.h = h * 360;\n\n      _this.setValue(_this.__color.toOriginal());\n\n      return false;\n\n    }\n\n  };\n\n  ColorController.superclass = Controller;\n\n  common.extend(\n\n      ColorController.prototype,\n      Controller.prototype,\n\n      {\n\n        updateDisplay: function() {\n\n          var i = interpret(this.getValue());\n\n          if (i !== false) {\n\n            var mismatch = false;\n\n            // Check for mismatch on the interpreted value.\n\n            common.each(Color.COMPONENTS, function(component) {\n              if (!common.isUndefined(i[component]) &&\n                  !common.isUndefined(this.__color.__state[component]) &&\n                  i[component] !== this.__color.__state[component]) {\n                mismatch = true;\n                return {}; // break\n              }\n            }, this);\n\n            // If nothing diverges, we keep our previous values\n            // for statefulness, otherwise we recalculate fresh\n            if (mismatch) {\n              common.extend(this.__color.__state, i);\n            }\n\n          }\n\n          common.extend(this.__temp.__state, this.__color.__state);\n\n          this.__temp.a = 1;\n\n          var flip = (this.__color.v < .5 || this.__color.s > .5) ? 255 : 0;\n          var _flip = 255 - flip;\n\n          common.extend(this.__field_knob.style, {\n            marginLeft: 100 * this.__color.s - 7 + 'px',\n            marginTop: 100 * (1 - this.__color.v) - 7 + 'px',\n            backgroundColor: this.__temp.toString(),\n            border: this.__field_knob_border + 'rgb(' + flip + ',' + flip + ',' + flip +')'\n          });\n\n          this.__hue_knob.style.marginTop = (1 - this.__color.h / 360) * 100 + 'px'\n\n          this.__temp.s = 1;\n          this.__temp.v = 1;\n\n          linearGradient(this.__saturation_field, 'left', '#fff', this.__temp.toString());\n\n          common.extend(this.__input.style, {\n            backgroundColor: this.__input.value = this.__color.toString(),\n            color: 'rgb(' + flip + ',' + flip + ',' + flip +')',\n            textShadow: this.__input_textShadow + 'rgba(' + _flip + ',' + _flip + ',' + _flip +',.7)'\n          });\n\n        }\n\n      }\n\n  );\n  \n  var vendors = ['-moz-','-o-','-webkit-','-ms-',''];\n  \n  function linearGradient(elem, x, a, b) {\n    elem.style.background = '';\n    common.each(vendors, function(vendor) {\n      elem.style.cssText += 'background: ' + vendor + 'linear-gradient('+x+', '+a+' 0%, ' + b + ' 100%); ';\n    });\n  }\n  \n  function hueGradient(elem) {\n    elem.style.background = '';\n    elem.style.cssText += 'background: -moz-linear-gradient(top,  #ff0000 0%, #ff00ff 17%, #0000ff 34%, #00ffff 50%, #00ff00 67%, #ffff00 84%, #ff0000 100%);'\n    elem.style.cssText += 'background: -webkit-linear-gradient(top,  #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n    elem.style.cssText += 'background: -o-linear-gradient(top,  #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n    elem.style.cssText += 'background: -ms-linear-gradient(top,  #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n    elem.style.cssText += 'background: linear-gradient(top,  #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'\n  }\n\n\n  return ColorController;\n\n})(dat.controllers.Controller,\ndat.dom.dom,\ndat.color.Color = (function (interpret, math, toString, common) {\n\n  var Color = function() {\n\n    this.__state = interpret.apply(this, arguments);\n\n    if (this.__state === false) {\n      throw 'Failed to interpret color arguments';\n    }\n\n    this.__state.a = this.__state.a || 1;\n\n\n  };\n\n  Color.COMPONENTS = ['r','g','b','h','s','v','hex','a'];\n\n  common.extend(Color.prototype, {\n\n    toString: function() {\n      return toString(this);\n    },\n\n    toOriginal: function() {\n      return this.__state.conversion.write(this);\n    }\n\n  });\n\n  defineRGBComponent(Color.prototype, 'r', 2);\n  defineRGBComponent(Color.prototype, 'g', 1);\n  defineRGBComponent(Color.prototype, 'b', 0);\n\n  defineHSVComponent(Color.prototype, 'h');\n  defineHSVComponent(Color.prototype, 's');\n  defineHSVComponent(Color.prototype, 'v');\n\n  Object.defineProperty(Color.prototype, 'a', {\n\n    get: function() {\n      return this.__state.a;\n    },\n\n    set: function(v) {\n      this.__state.a = v;\n    }\n\n  });\n\n  Object.defineProperty(Color.prototype, 'hex', {\n\n    get: function() {\n\n      if (!this.__state.space !== 'HEX') {\n        this.__state.hex = math.rgb_to_hex(this.r, this.g, this.b);\n      }\n\n      return this.__state.hex;\n\n    },\n\n    set: function(v) {\n\n      this.__state.space = 'HEX';\n      this.__state.hex = v;\n\n    }\n\n  });\n\n  function defineRGBComponent(target, component, componentHexIndex) {\n\n    Object.defineProperty(target, component, {\n\n      get: function() {\n\n        if (this.__state.space === 'RGB') {\n          return this.__state[component];\n        }\n\n        recalculateRGB(this, component, componentHexIndex);\n\n        return this.__state[component];\n\n      },\n\n      set: function(v) {\n\n        if (this.__state.space !== 'RGB') {\n          recalculateRGB(this, component, componentHexIndex);\n          this.__state.space = 'RGB';\n        }\n\n        this.__state[component] = v;\n\n      }\n\n    });\n\n  }\n\n  function defineHSVComponent(target, component) {\n\n    Object.defineProperty(target, component, {\n\n      get: function() {\n\n        if (this.__state.space === 'HSV')\n          return this.__state[component];\n\n        recalculateHSV(this);\n\n        return this.__state[component];\n\n      },\n\n      set: function(v) {\n\n        if (this.__state.space !== 'HSV') {\n          recalculateHSV(this);\n          this.__state.space = 'HSV';\n        }\n\n        this.__state[component] = v;\n\n      }\n\n    });\n\n  }\n\n  function recalculateRGB(color, component, componentHexIndex) {\n\n    if (color.__state.space === 'HEX') {\n\n      color.__state[component] = math.component_from_hex(color.__state.hex, componentHexIndex);\n\n    } else if (color.__state.space === 'HSV') {\n\n      common.extend(color.__state, math.hsv_to_rgb(color.__state.h, color.__state.s, color.__state.v));\n\n    } else {\n\n      throw 'Corrupted color state';\n\n    }\n\n  }\n\n  function recalculateHSV(color) {\n\n    var result = math.rgb_to_hsv(color.r, color.g, color.b);\n\n    common.extend(color.__state,\n        {\n          s: result.s,\n          v: result.v\n        }\n    );\n\n    if (!common.isNaN(result.h)) {\n      color.__state.h = result.h;\n    } else if (common.isUndefined(color.__state.h)) {\n      color.__state.h = 0;\n    }\n\n  }\n\n  return Color;\n\n})(dat.color.interpret,\ndat.color.math = (function () {\n\n  var tmpComponent;\n\n  return {\n\n    hsv_to_rgb: function(h, s, v) {\n\n      var hi = Math.floor(h / 60) % 6;\n\n      var f = h / 60 - Math.floor(h / 60);\n      var p = v * (1.0 - s);\n      var q = v * (1.0 - (f * s));\n      var t = v * (1.0 - ((1.0 - f) * s));\n      var c = [\n        [v, t, p],\n        [q, v, p],\n        [p, v, t],\n        [p, q, v],\n        [t, p, v],\n        [v, p, q]\n      ][hi];\n\n      return {\n        r: c[0] * 255,\n        g: c[1] * 255,\n        b: c[2] * 255\n      };\n\n    },\n\n    rgb_to_hsv: function(r, g, b) {\n\n      var min = Math.min(r, g, b),\n          max = Math.max(r, g, b),\n          delta = max - min,\n          h, s;\n\n      if (max != 0) {\n        s = delta / max;\n      } else {\n        return {\n          h: NaN,\n          s: 0,\n          v: 0\n        };\n      }\n\n      if (r == max) {\n        h = (g - b) / delta;\n      } else if (g == max) {\n        h = 2 + (b - r) / delta;\n      } else {\n        h = 4 + (r - g) / delta;\n      }\n      h /= 6;\n      if (h < 0) {\n        h += 1;\n      }\n\n      return {\n        h: h * 360,\n        s: s,\n        v: max / 255\n      };\n    },\n\n    rgb_to_hex: function(r, g, b) {\n      var hex = this.hex_with_component(0, 2, r);\n      hex = this.hex_with_component(hex, 1, g);\n      hex = this.hex_with_component(hex, 0, b);\n      return hex;\n    },\n\n    component_from_hex: function(hex, componentIndex) {\n      return (hex >> (componentIndex * 8)) & 0xFF;\n    },\n\n    hex_with_component: function(hex, componentIndex, value) {\n      return value << (tmpComponent = componentIndex * 8) | (hex & ~ (0xFF << tmpComponent));\n    }\n\n  }\n\n})(),\ndat.color.toString,\ndat.utils.common),\ndat.color.interpret,\ndat.utils.common),\ndat.utils.requestAnimationFrame = (function () {\n\n  /**\n   * requirejs version of Paul Irish's RequestAnimationFrame\n   * http://paulirish.com/2011/requestanimationframe-for-smart-animating/\n   */\n\n  return window.webkitRequestAnimationFrame ||\n      window.mozRequestAnimationFrame ||\n      window.oRequestAnimationFrame ||\n      window.msRequestAnimationFrame ||\n      function(callback, element) {\n\n        window.setTimeout(callback, 1000 / 60);\n\n      };\n})(),\ndat.dom.CenteredDiv = (function (dom, common) {\n\n\n  var CenteredDiv = function() {\n\n    this.backgroundElement = document.createElement('div');\n    common.extend(this.backgroundElement.style, {\n      backgroundColor: 'rgba(0,0,0,0.8)',\n      top: 0,\n      left: 0,\n      display: 'none',\n      zIndex: '1000',\n      opacity: 0,\n      WebkitTransition: 'opacity 0.2s linear'\n    });\n\n    dom.makeFullscreen(this.backgroundElement);\n    this.backgroundElement.style.position = 'fixed';\n\n    this.domElement = document.createElement('div');\n    common.extend(this.domElement.style, {\n      position: 'fixed',\n      display: 'none',\n      zIndex: '1001',\n      opacity: 0,\n      WebkitTransition: '-webkit-transform 0.2s ease-out, opacity 0.2s linear'\n    });\n\n\n    document.body.appendChild(this.backgroundElement);\n    document.body.appendChild(this.domElement);\n\n    var _this = this;\n    dom.bind(this.backgroundElement, 'click', function() {\n      _this.hide();\n    });\n\n\n  };\n\n  CenteredDiv.prototype.show = function() {\n\n    var _this = this;\n    \n\n\n    this.backgroundElement.style.display = 'block';\n\n    this.domElement.style.display = 'block';\n    this.domElement.style.opacity = 0;\n//    this.domElement.style.top = '52%';\n    this.domElement.style.webkitTransform = 'scale(1.1)';\n\n    this.layout();\n\n    common.defer(function() {\n      _this.backgroundElement.style.opacity = 1;\n      _this.domElement.style.opacity = 1;\n      _this.domElement.style.webkitTransform = 'scale(1)';\n    });\n\n  };\n\n  CenteredDiv.prototype.hide = function() {\n\n    var _this = this;\n\n    var hide = function() {\n\n      _this.domElement.style.display = 'none';\n      _this.backgroundElement.style.display = 'none';\n\n      dom.unbind(_this.domElement, 'webkitTransitionEnd', hide);\n      dom.unbind(_this.domElement, 'transitionend', hide);\n      dom.unbind(_this.domElement, 'oTransitionEnd', hide);\n\n    };\n\n    dom.bind(this.domElement, 'webkitTransitionEnd', hide);\n    dom.bind(this.domElement, 'transitionend', hide);\n    dom.bind(this.domElement, 'oTransitionEnd', hide);\n\n    this.backgroundElement.style.opacity = 0;\n//    this.domElement.style.top = '48%';\n    this.domElement.style.opacity = 0;\n    this.domElement.style.webkitTransform = 'scale(1.1)';\n\n  };\n\n  CenteredDiv.prototype.layout = function() {\n    this.domElement.style.left = window.innerWidth/2 - dom.getWidth(this.domElement) / 2 + 'px';\n    this.domElement.style.top = window.innerHeight/2 - dom.getHeight(this.domElement) / 2 + 'px';\n  };\n  \n  function lockScroll(e) {\n    console.log(e);\n  }\n\n  return CenteredDiv;\n\n})(dat.dom.dom,\ndat.utils.common),\ndat.dom.dom,\ndat.utils.common);"]}