text: /**
   * dat-gui JavaScript Controller Library
   * http://code.google.com/p/dat-gui
   *
   * Copyright 2011 Data Arts Team, Google Creative Lab
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   * http://www.apache.org/licenses/LICENSE-2.0
   */
  var dat = dat || {};
  dat.gui = dat.gui || {};
  dat.utils = dat.utils || {};
  dat.controllers = dat.controllers || {};
  dat.dom = dat.dom || {};
  dat.color = dat.color || {};
  dat.utils.css = function() {
  	return {
  		load: function(e, a) {
  			var a = a || document,
  				c = a.createElement("link");
  			c.type = "text/css";
  			c.rel = "stylesheet";
  			c.href = e;
  			a.getElementsByTagName("head")[0].appendChild(c)
  		},
  		inject: function(e, a) {
  			var a = a || document,
  				c = document.createElement("style");
  			c.type = "text/css";
  			c.innerHTML = e;
  			a.getElementsByTagName("head")[0].appendChild(c)
  		}
  	}
  }();
  dat.utils.common = function() {
  	var e = Array.prototype.forEach,
  		a = Array.prototype.slice;
  	return {
  		BREAK: {},
  		extend: function(c) {
  			this.each(a.call(arguments, 1), function(a) {
  				for(var f in a) this.isUndefined(a[f]) || (c[f] = a[f])
  			}, this);
  			return c
  		},
  		defaults: function(c) {
  			this.each(a.call(arguments, 1), function(a) {
  				for(var f in a) this.isUndefined(c[f]) && (c[f] = a[f])
  			}, this);
  			return c
  		},
  		compose: function() {
  			var c = a.call(arguments);
  			return function() {
  				for(var d = a.call(arguments), f = c.length - 1; f >= 0; f--) d = [c[f].apply(this, d)];
  				return d[0]
  			}
  		},
  		each: function(a, d, f) {
  			if(e && a.forEach === e) a.forEach(d, f);
  			else if(a.length === a.length + 0)
  				for(var b = 0, n = a.length; b < n; b++) {
  					if(b in a && d.call(f, a[b], b) === this.BREAK) break
  				} else
  					for(b in a)
  						if(d.call(f, a[b], b) === this.BREAK) break
  		},
  		defer: function(a) {
  			setTimeout(a, 0)
  		},
  		toArray: function(c) {
  			return c.toArray ? c.toArray() : a.call(c)
  		},
  		isUndefined: function(a) {
  			return a === void 0
  		},
  		isNull: function(a) {
  			return a === null
  		},
  		isNaN: function(a) {
  			return a !== a
  		},
  		isArray: Array.isArray || function(a) {
  			return a.constructor === Array
  		},
  		isObject: function(a) {
  			return a ===
  				Object(a)
  		},
  		isNumber: function(a) {
  			return a === a + 0
  		},
  		isString: function(a) {
  			return a === a + ""
  		},
  		isBoolean: function(a) {
  			return a === false || a === true
  		},
  		isFunction: function(a) {
  			return Object.prototype.toString.call(a) === "[object Function]"
  		}
  	}
  }();
  dat.controllers.Controller = function(e) {
  	var a = function(a, d) {
  		this.initialValue = a[d];
  		this.domElement = document.createElement("div");
  		this.object = a;
  		this.property = d;
  		this.__onFinishChange = this.__onChange = void 0
  	};
  	e.extend(a.prototype, {
  		onChange: function(a) {
  			this.__onChange = a;
  			return this
  		},
  		onFinishChange: function(a) {
  			this.__onFinishChange = a;
  			return this
  		},
  		setValue: function(a) {
  			this.object[this.property] = a;
  			this.__onChange && this.__onChange.call(this, a);
  			this.updateDisplay();
  			return this
  		},
  		getValue: function() {
  			return this.object[this.property]
  		},
  		updateDisplay: function() {
  			return this
  		},
  		isModified: function() {
  			return this.initialValue !== this.getValue()
  		}
  	});
  	return a
  }(dat.utils.common);
  dat.dom.dom = function(e) {
  	function a(b) {
  		if(b === "0" || e.isUndefined(b)) return 0;
  		b = b.match(d);
  		return !e.isNull(b) ? parseFloat(b[1]) : 0
  	}
  	var c = {};
  	e.each({
  		HTMLEvents: ["change"],
  		MouseEvents: ["click", "mousemove", "mousedown", "mouseup", "mouseover"],
  		KeyboardEvents: ["keydown"]
  	}, function(b, a) {
  		e.each(b, function(b) {
  			c[b] = a
  		})
  	});
  	var d = /(\d+(\.\d+)?)px/,
  		f = {
  			makeSelectable: function(b, a) {
  				if(!(b === void 0 || b.style === void 0)) b.onselectstart = a ? function() {
  						return false
  					} : function() {}, b.style.MozUserSelect = a ? "auto" : "none", b.style.KhtmlUserSelect =
  					a ? "auto" : "none", b.unselectable = a ? "on" : "off"
  			},
  			makeFullscreen: function(b, a, d) {
  				e.isUndefined(a) && (a = true);
  				e.isUndefined(d) && (d = true);
  				b.style.position = "absolute";
  				if(a) b.style.left = 0, b.style.right = 0;
  				if(d) b.style.top = 0, b.style.bottom = 0
  			},
  			fakeEvent: function(b, a, d, f) {
  				var d = d || {},
  					m = c[a];
  				if(!m) throw Error("Event type " + a + " not supported.");
  				var l = document.createEvent(m);
  				switch(m) {
  					case "MouseEvents":
  						l.initMouseEvent(a, d.bubbles || false, d.cancelable || true, window, d.clickCount || 1, 0, 0, d.x || d.clientX || 0, d.y || d.clientY ||
  							0, false, false, false, false, 0, null);
  						break;
  					case "KeyboardEvents":
  						m = l.initKeyboardEvent || l.initKeyEvent;
  						e.defaults(d, {
  							cancelable: true,
  							ctrlKey: false,
  							altKey: false,
  							shiftKey: false,
  							metaKey: false,
  							keyCode: void 0,
  							charCode: void 0
  						});
  						m(a, d.bubbles || false, d.cancelable, window, d.ctrlKey, d.altKey, d.shiftKey, d.metaKey, d.keyCode, d.charCode);
  						break;
  					default:
  						l.initEvent(a, d.bubbles || false, d.cancelable || true)
  				}
  				e.defaults(l, f);
  				b.dispatchEvent(l)
  			},
  			bind: function(b, a, d, c) {
  				b.addEventListener ? b.addEventListener(a, d, c || false) : b.attachEvent &&
  					b.attachEvent("on" + a, d);
  				return f
  			},
  			unbind: function(b, a, d, c) {
  				b.removeEventListener ? b.removeEventListener(a, d, c || false) : b.detachEvent && b.detachEvent("on" + a, d);
  				return f
  			},
  			addClass: function(b, a) {
  				if(b.className === void 0) b.className = a;
  				else if(b.className !== a) {
  					var d = b.className.split(/ +/);
  					if(d.indexOf(a) == -1) d.push(a), b.className = d.join(" ").replace(/^\s+/, "").replace(/\s+$/, "")
  				}
  				return f
  			},
  			removeClass: function(b, a) {
  				if(a) {
  					if(b.className !== void 0)
  						if(b.className === a) b.removeAttribute("class");
  						else {
  							var d = b.className.split(/ +/),
  								c = d.indexOf(a);
  							if(c != -1) d.splice(c, 1), b.className = d.join(" ")
  						}
  				} else b.className = void 0;
  				return f
  			},
  			hasClass: function(a, d) {
  				return RegExp("(?:^|\\s+)" + d + "(?:\\s+|$)").test(a.className) || false
  			},
  			getWidth: function(b) {
  				b = getComputedStyle(b);
  				return a(b["border-left-width"]) + a(b["border-right-width"]) + a(b["padding-left"]) + a(b["padding-right"]) + a(b.width)
  			},
  			getHeight: function(b) {
  				b = getComputedStyle(b);
  				return a(b["border-top-width"]) + a(b["border-bottom-width"]) + a(b["padding-top"]) + a(b["padding-bottom"]) + a(b.height)
  			},
  			getOffset: function(a) {
  				var d = {
  					left: 0,
  					top: 0
  				};
  				if(a.offsetParent) {
  					do d.left += a.offsetLeft, d.top += a.offsetTop; while (a = a.offsetParent)
  				}
  				return d
  			},
  			isActive: function(a) {
  				return a === document.activeElement && (a.type || a.href)
  			}
  		};
  	return f
  }(dat.utils.common);
  dat.controllers.OptionController = function(e, a, c) {
  	var d = function(f, b, e) {
  		d.superclass.call(this, f, b);
  		var h = this;
  		this.__select = document.createElement("select");
  		if(c.isArray(e)) {
  			var j = {};
  			c.each(e, function(a) {
  				j[a] = a
  			});
  			e = j
  		}
  		c.each(e, function(a, b) {
  			var d = document.createElement("option");
  			d.innerHTML = b;
  			d.setAttribute("value", a);
  			h.__select.appendChild(d)
  		});
  		this.updateDisplay();
  		a.bind(this.__select, "change", function() {
  			h.setValue(this.options[this.selectedIndex].value)
  		});
  		this.domElement.appendChild(this.__select)
  	};
  	d.superclass = e;
  	c.extend(d.prototype, e.prototype, {
  		setValue: function(a) {
  			a = d.superclass.prototype.setValue.call(this, a);
  			this.__onFinishChange && this.__onFinishChange.call(this, this.getValue());
  			return a
  		},
  		updateDisplay: function() {
  			this.__select.value = this.getValue();
  			return d.superclass.prototype.updateDisplay.call(this)
  		}
  	});
  	return d
  }(dat.controllers.Controller, dat.dom.dom, dat.utils.common);
  dat.controllers.NumberController = function(e, a) {
  	var c = function(d, f, b) {
  		c.superclass.call(this, d, f);
  		b = b || {};
  		this.__min = b.min;
  		this.__max = b.max;
  		this.__step = b.step;
  		d = this.__impliedStep = a.isUndefined(this.__step) ? this.initialValue == 0 ? 1 : Math.pow(10, Math.floor(Math.log(this.initialValue) / Math.LN10)) / 10 : this.__step;
  		d = d.toString();
  		this.__precision = d.indexOf(".") > -1 ? d.length - d.indexOf(".") - 1 : 0
  	};
  	c.superclass = e;
  	a.extend(c.prototype, e.prototype, {
  		setValue: function(a) {
  			if(this.__min !== void 0 && a < this.__min) a = this.__min;
  			else if(this.__max !== void 0 && a > this.__max) a = this.__max;
  			this.__step !== void 0 && a % this.__step != 0 && (a = Math.round(a / this.__step) * this.__step);
  			return c.superclass.prototype.setValue.call(this, a)
  		},
  		min: function(a) {
  			this.__min = a;
  			return this
  		},
  		max: function(a) {
  			this.__max = a;
  			return this
  		},
  		step: function(a) {
  			this.__step = a;
  			return this
  		}
  	});
  	return c
  }(dat.controllers.Controller, dat.utils.common);
  dat.controllers.NumberControllerBox = function(e, a, c) {
  	var d = function(f, b, e) {
  		function h() {
  			var a = parseFloat(l.__input.value);
  			c.isNaN(a) || l.setValue(a)
  		}
  
  		function j(a) {
  			var b = o - a.clientY;
  			l.setValue(l.getValue() + b * l.__impliedStep);
  			o = a.clientY
  		}
  
  		function m() {
  			a.unbind(window, "mousemove", j);
  			a.unbind(window, "mouseup", m)
  		}
  		this.__truncationSuspended = false;
  		d.superclass.call(this, f, b, e);
  		var l = this,
  			o;
  		this.__input = document.createElement("input");
  		this.__input.setAttribute("type", "text");
  		a.bind(this.__input, "change", h);
  		a.bind(this.__input, "blur", function() {
  			h();
  			l.__onFinishChange && l.__onFinishChange.call(l, l.getValue())
  		});
  		a.bind(this.__input, "mousedown", function(b) {
  			a.bind(window, "mousemove", j);
  			a.bind(window, "mouseup", m);
  			o = b.clientY
  		});
  		a.bind(this.__input, "keydown", function(a) {
  			if(a.keyCode === 13) l.__truncationSuspended = true, this.blur(), l.__truncationSuspended = false
  		});
  		this.updateDisplay();
  		this.domElement.appendChild(this.__input)
  	};
  	d.superclass = e;
  	c.extend(d.prototype, e.prototype, {
  		updateDisplay: function() {
  			var a = this.__input,
  				b;
  			if(this.__truncationSuspended) b = this.getValue();
  			else {
  				b = this.getValue();
  				var c = Math.pow(10, this.__precision);
  				b = Math.round(b * c) / c
  			}
  			a.value = b;
  			return d.superclass.prototype.updateDisplay.call(this)
  		}
  	});
  	return d
  }(dat.controllers.NumberController, dat.dom.dom, dat.utils.common);
  dat.controllers.NumberControllerSlider = function(e, a, c, d, f) {
  	var b = function(d, c, f, e, l) {
  		function o(b) {
  			b.preventDefault();
  			var d = a.getOffset(g.__background),
  				c = a.getWidth(g.__background);
  			g.setValue(g.__min + (g.__max - g.__min) * ((b.clientX - d.left) / (d.left + c - d.left)));
  			return false
  		}
  
  		function y() {
  			a.unbind(window, "mousemove", o);
  			a.unbind(window, "mouseup", y);
  			g.__onFinishChange && g.__onFinishChange.call(g, g.getValue())
  		}
  		b.superclass.call(this, d, c, {
  			min: f,
  			max: e,
  			step: l
  		});
  		var g = this;
  		this.__background = document.createElement("div");
  		this.__foreground = document.createElement("div");
  		a.bind(this.__background, "mousedown", function(b) {
  			a.bind(window, "mousemove", o);
  			a.bind(window, "mouseup", y);
  			o(b)
  		});
  		a.addClass(this.__background, "slider");
  		a.addClass(this.__foreground, "slider-fg");
  		this.updateDisplay();
  		this.__background.appendChild(this.__foreground);
  		this.domElement.appendChild(this.__background)
  	};
  	b.superclass = e;
  	b.useDefaultStyles = function() {
  		c.inject(f)
  	};
  	d.extend(b.prototype, e.prototype, {
  		updateDisplay: function() {
  			this.__foreground.style.width =
  				(this.getValue() - this.__min) / (this.__max - this.__min) * 100 + "%";
  			return b.superclass.prototype.updateDisplay.call(this)
  		}
  	});
  	return b
  }(dat.controllers.NumberController, dat.dom.dom, dat.utils.css, dat.utils.common, ".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}");
  dat.controllers.FunctionController = function(e, a, c) {
  	var d = function(c, b, e) {
  		d.superclass.call(this, c, b);
  		var h = this;
  		this.__button = document.createElement("div");
  		this.__button.innerHTML = e === void 0 ? "Fire" : e;
  		a.bind(this.__button, "click", function(a) {
  			a.preventDefault();
  			h.fire();
  			return false
  		});
  		a.addClass(this.__button, "button");
  		this.domElement.appendChild(this.__button)
  	};
  	d.superclass = e;
  	c.extend(d.prototype, e.prototype, {
  		fire: function() {
  			this.__onChange && this.__onChange.call(this);
  			this.__onFinishChange && this.__onFinishChange.call(this,
  				this.getValue());
  			this.getValue().call(this.object)
  		}
  	});
  	return d
  }(dat.controllers.Controller, dat.dom.dom, dat.utils.common);
  dat.controllers.BooleanController = function(e, a, c) {
  	var d = function(c, b) {
  		d.superclass.call(this, c, b);
  		var e = this;
  		this.__prev = this.getValue();
  		this.__checkbox = document.createElement("input");
  		this.__checkbox.setAttribute("type", "checkbox");
  		a.bind(this.__checkbox, "change", function() {
  			e.setValue(!e.__prev)
  		}, false);
  		this.domElement.appendChild(this.__checkbox);
  		this.updateDisplay()
  	};
  	d.superclass = e;
  	c.extend(d.prototype, e.prototype, {
  		setValue: function(a) {
  			a = d.superclass.prototype.setValue.call(this, a);
  			this.__onFinishChange &&
  				this.__onFinishChange.call(this, this.getValue());
  			this.__prev = this.getValue();
  			return a
  		},
  		updateDisplay: function() {
  			this.getValue() === true ? (this.__checkbox.setAttribute("checked", "checked"), this.__checkbox.checked = true) : this.__checkbox.checked = false;
  			return d.superclass.prototype.updateDisplay.call(this)
  		}
  	});
  	return d
  }(dat.controllers.Controller, dat.dom.dom, dat.utils.common);
  dat.color.toString = function(e) {
  	return function(a) {
  		if(a.a == 1 || e.isUndefined(a.a)) {
  			for(a = a.hex.toString(16); a.length < 6;) a = "0" + a;
  			return "#" + a
  		} else return "rgba(" + Math.round(a.r) + "," + Math.round(a.g) + "," + Math.round(a.b) + "," + a.a + ")"
  	}
  }(dat.utils.common);
  dat.color.interpret = function(e, a) {
  	var c, d, f = [{
  		litmus: a.isString,
  		conversions: {
  			THREE_CHAR_HEX: {
  				read: function(a) {
  					a = a.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);
  					return a === null ? false : {
  						space: "HEX",
  						hex: parseInt("0x" + a[1].toString() + a[1].toString() + a[2].toString() + a[2].toString() + a[3].toString() + a[3].toString())
  					}
  				},
  				write: e
  			},
  			SIX_CHAR_HEX: {
  				read: function(a) {
  					a = a.match(/^#([A-F0-9]{6})$/i);
  					return a === null ? false : {
  						space: "HEX",
  						hex: parseInt("0x" + a[1].toString())
  					}
  				},
  				write: e
  			},
  			CSS_RGB: {
  				read: function(a) {
  					a = a.match(/^rgb\(\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*\)/);
  					return a === null ? false : {
  						space: "RGB",
  						r: parseFloat(a[1]),
  						g: parseFloat(a[2]),
  						b: parseFloat(a[3])
  					}
  				},
  				write: e
  			},
  			CSS_RGBA: {
  				read: function(a) {
  					a = a.match(/^rgba\(\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*\,\s*(.+)\s*\)/);
  					return a === null ? false : {
  						space: "RGB",
  						r: parseFloat(a[1]),
  						g: parseFloat(a[2]),
  						b: parseFloat(a[3]),
  						a: parseFloat(a[4])
  					}
  				},
  				write: e
  			}
  		}
  	}, {
  		litmus: a.isNumber,
  		conversions: {
  			HEX: {
  				read: function(a) {
  					return {
  						space: "HEX",
  						hex: a,
  						conversionName: "HEX"
  					}
  				},
  				write: function(a) {
  					return a.hex
  				}
  			}
  		}
  	}, {
  		litmus: a.isArray,
  		conversions: {
  			RGB_ARRAY: {
  				read: function(a) {
  					return a.length !=
  						3 ? false : {
  							space: "RGB",
  							r: a[0],
  							g: a[1],
  							b: a[2]
  						}
  				},
  				write: function(a) {
  					return [a.r, a.g, a.b]
  				}
  			},
  			RGBA_ARRAY: {
  				read: function(a) {
  					return a.length != 4 ? false : {
  						space: "RGB",
  						r: a[0],
  						g: a[1],
  						b: a[2],
  						a: a[3]
  					}
  				},
  				write: function(a) {
  					return [a.r, a.g, a.b, a.a]
  				}
  			}
  		}
  	}, {
  		litmus: a.isObject,
  		conversions: {
  			RGBA_OBJ: {
  				read: function(b) {
  					return a.isNumber(b.r) && a.isNumber(b.g) && a.isNumber(b.b) && a.isNumber(b.a) ? {
  						space: "RGB",
  						r: b.r,
  						g: b.g,
  						b: b.b,
  						a: b.a
  					} : false
  				},
  				write: function(a) {
  					return {
  						r: a.r,
  						g: a.g,
  						b: a.b,
  						a: a.a
  					}
  				}
  			},
  			RGB_OBJ: {
  				read: function(b) {
  					return a.isNumber(b.r) &&
  						a.isNumber(b.g) && a.isNumber(b.b) ? {
  							space: "RGB",
  							r: b.r,
  							g: b.g,
  							b: b.b
  						} : false
  				},
  				write: function(a) {
  					return {
  						r: a.r,
  						g: a.g,
  						b: a.b
  					}
  				}
  			},
  			HSVA_OBJ: {
  				read: function(b) {
  					return a.isNumber(b.h) && a.isNumber(b.s) && a.isNumber(b.v) && a.isNumber(b.a) ? {
  						space: "HSV",
  						h: b.h,
  						s: b.s,
  						v: b.v,
  						a: b.a
  					} : false
  				},
  				write: function(a) {
  					return {
  						h: a.h,
  						s: a.s,
  						v: a.v,
  						a: a.a
  					}
  				}
  			},
  			HSV_OBJ: {
  				read: function(b) {
  					return a.isNumber(b.h) && a.isNumber(b.s) && a.isNumber(b.v) ? {
  						space: "HSV",
  						h: b.h,
  						s: b.s,
  						v: b.v
  					} : false
  				},
  				write: function(a) {
  					return {
  						h: a.h,
  						s: a.s,
  						v: a.v
  					}
  				}
  			}
  		}
  	}];
  	return function() {
  		d =
  			false;
  		var b = arguments.length > 1 ? a.toArray(arguments) : arguments[0];
  		a.each(f, function(e) {
  			if(e.litmus(b)) return a.each(e.conversions, function(e, f) {
  				c = e.read(b);
  				if(d === false && c !== false) return d = c, c.conversionName = f, c.conversion = e, a.BREAK
  			}), a.BREAK
  		});
  		return d
  	}
  }(dat.color.toString, dat.utils.common);
  dat.GUI = dat.gui.GUI = function(e, a, c, d, f, b, n, h, j, m, l, o, y, g, i) {
  	function q(a, b, r, c) {
  		if(b[r] === void 0) throw Error("Object " + b + ' has no property "' + r + '"');
  		c.color ? b = new l(b, r) : (b = [b, r].concat(c.factoryArgs), b = d.apply(a, b));
  		if(c.before instanceof f) c.before = c.before.__li;
  		t(a, b);
  		g.addClass(b.domElement, "c");
  		r = document.createElement("span");
  		g.addClass(r, "property-name");
  		r.innerHTML = b.property;
  		var e = document.createElement("div");
  		e.appendChild(r);
  		e.appendChild(b.domElement);
  		c = s(a, e, c.before);
  		g.addClass(c, k.CLASS_CONTROLLER_ROW);
  		g.addClass(c, typeof b.getValue());
  		p(a, c, b);
  		a.__controllers.push(b);
  		return b
  	}
  
  	function s(a, b, d) {
  		var c = document.createElement("li");
  		b && c.appendChild(b);
  		d ? a.__ul.insertBefore(c, params.before) : a.__ul.appendChild(c);
  		a.onResize();
  		return c
  	}
  
  	function p(a, d, c) {
  		c.__li = d;
  		c.__gui = a;
  		i.extend(c, {
  			options: function(b) {
  				if(arguments.length > 1) return c.remove(), q(a, c.object, c.property, {
  					before: c.__li.nextElementSibling,
  					factoryArgs: [i.toArray(arguments)]
  				});
  				if(i.isArray(b) || i.isObject(b)) return c.remove(), q(a, c.object, c.property, {
  					before: c.__li.nextElementSibling,
  					factoryArgs: [b]
  				})
  			},
  			name: function(a) {
  				c.__li.firstElementChild.firstElementChild.innerHTML = a;
  				return c
  			},
  			listen: function() {
  				c.__gui.listen(c);
  				return c
  			},
  			remove: function() {
  				c.__gui.remove(c);
  				return c
  			}
  		});
  		if(c instanceof j) {
  			var e = new h(c.object, c.property, {
  				min: c.__min,
  				max: c.__max,
  				step: c.__step
  			});
  			i.each(["updateDisplay", "onChange", "onFinishChange"], function(a) {
  				var b = c[a],
  					H = e[a];
  				c[a] = e[a] = function() {
  					var a = Array.prototype.slice.call(arguments);
  					b.apply(c, a);
  					return H.apply(e, a)
  				}
  			});
  			g.addClass(d, "has-slider");
  			c.domElement.insertBefore(e.domElement, c.domElement.firstElementChild)
  		} else if(c instanceof h) {
  			var f = function(b) {
  				return i.isNumber(c.__min) && i.isNumber(c.__max) ? (c.remove(), q(a, c.object, c.property, {
  					before: c.__li.nextElementSibling,
  					factoryArgs: [c.__min, c.__max, c.__step]
  				})) : b
  			};
  			c.min = i.compose(f, c.min);
  			c.max = i.compose(f, c.max)
  		} else if(c instanceof b) g.bind(d, "click", function() {
  			g.fakeEvent(c.__checkbox, "click")
  		}), g.bind(c.__checkbox, "click", function(a) {
  			a.stopPropagation()
  		});
  		else if(c instanceof n) g.bind(d, "click", function() {
  			g.fakeEvent(c.__button, "click")
  		}), g.bind(d, "mouseover", function() {
  			g.addClass(c.__button, "hover")
  		}), g.bind(d, "mouseout", function() {
  			g.removeClass(c.__button, "hover")
  		});
  		else if(c instanceof l) g.addClass(d, "color"), c.updateDisplay = i.compose(function(a) {
  			d.style.borderLeftColor = c.__color.toString();
  			return a
  		}, c.updateDisplay), c.updateDisplay();
  		c.setValue = i.compose(function(b) {
  			a.getRoot().__preset_select && c.isModified() && B(a.getRoot(), true);
  			return b
  		}, c.setValue)
  	}
  
  	function t(a, b) {
  		var c = a.getRoot(),
  			d = c.__rememberedObjects.indexOf(b.object);
  		if(d != -1) {
  			var e = c.__rememberedObjectIndecesToControllers[d];
  			e === void 0 && (e = {}, c.__rememberedObjectIndecesToControllers[d] = e);
  			e[b.property] = b;
  			if(c.load && c.load.remembered) {
  				c = c.load.remembered;
  				if(c[a.preset]) c = c[a.preset];
  				else if(c[w]) c = c[w];
  				else return;
  				if(c[d] && c[d][b.property] !== void 0) d = c[d][b.property], b.initialValue = d, b.setValue(d)
  			}
  		}
  	}
  
  	function I(a) {
  		var b = a.__save_row = document.createElement("li");
  		g.addClass(a.domElement,
  			"has-save");
  		a.__ul.insertBefore(b, a.__ul.firstChild);
  		g.addClass(b, "save-row");
  		var c = document.createElement("span");
  		c.innerHTML = "&nbsp;";
  		g.addClass(c, "button gears");
  		var d = document.createElement("span");
  		d.innerHTML = "Save";
  		g.addClass(d, "button");
  		g.addClass(d, "save");
  		var e = document.createElement("span");
  		e.innerHTML = "New";
  		g.addClass(e, "button");
  		g.addClass(e, "save-as");
  		var f = document.createElement("span");
  		f.innerHTML = "Revert";
  		g.addClass(f, "button");
  		g.addClass(f, "revert");
  		var m = a.__preset_select = document.createElement("select");
  		a.load && a.load.remembered ? i.each(a.load.remembered, function(b, c) {
  			C(a, c, c == a.preset)
  		}) : C(a, w, false);
  		g.bind(m, "change", function() {
  			for(var b = 0; b < a.__preset_select.length; b++) a.__preset_select[b].innerHTML = a.__preset_select[b].value;
  			a.preset = this.value
  		});
  		b.appendChild(m);
  		b.appendChild(c);
  		b.appendChild(d);
  		b.appendChild(e);
  		b.appendChild(f);
  		if(u) {
  			var b = document.getElementById("dg-save-locally"),
  				l = document.getElementById("dg-local-explain");
  			b.style.display = "block";
  			b = document.getElementById("dg-local-storage");
  			localStorage.getItem(document.location.href + ".isLocal") === "true" && b.setAttribute("checked", "checked");
  			var o = function() {
  				l.style.display = a.useLocalStorage ? "block" : "none"
  			};
  			o();
  			g.bind(b, "change", function() {
  				a.useLocalStorage = !a.useLocalStorage;
  				o()
  			})
  		}
  		var h = document.getElementById("dg-new-constructor");
  		g.bind(h, "keydown", function(a) {
  			a.metaKey && (a.which === 67 || a.keyCode == 67) && x.hide()
  		});
  		g.bind(c, "click", function() {
  			h.innerHTML = JSON.stringify(a.getSaveObject(), void 0, 2);
  			x.show();
  			h.focus();
  			h.select()
  		});
  		g.bind(d,
  			"click",
  			function() {
  				a.save()
  			});
  		g.bind(e, "click", function() {
  			var b = prompt("Enter a new preset name.");
  			b && a.saveAs(b)
  		});
  		g.bind(f, "click", function() {
  			a.revert()
  		})
  	}
  
  	function J(a) {
  		function b(f) {
  			f.preventDefault();
  			e = f.clientX;
  			g.addClass(a.__closeButton, k.CLASS_DRAG);
  			g.bind(window, "mousemove", c);
  			g.bind(window, "mouseup", d);
  			return false
  		}
  
  		function c(b) {
  			b.preventDefault();
  			a.width += e - b.clientX;
  			a.onResize();
  			e = b.clientX;
  			return false
  		}
  
  		function d() {
  			g.removeClass(a.__closeButton, k.CLASS_DRAG);
  			g.unbind(window, "mousemove",
  				c);
  			g.unbind(window, "mouseup", d)
  		}
  		a.__resize_handle = document.createElement("div");
  		i.extend(a.__resize_handle.style, {
  			width: "6px",
  			marginLeft: "-3px",
  			height: "200px",
  			cursor: "ew-resize",
  			position: "absolute"
  		});
  		var e;
  		g.bind(a.__resize_handle, "mousedown", b);
  		g.bind(a.__closeButton, "mousedown", b);
  		a.domElement.insertBefore(a.__resize_handle, a.domElement.firstElementChild)
  	}
  
  	function D(a, b) {
  		a.domElement.style.width = b + "px";
  		if(a.__save_row && a.autoPlace) a.__save_row.style.width = b + "px";
  		if(a.__closeButton) a.__closeButton.style.width =
  			b + "px"
  	}
  
  	function z(a, b) {
  		var c = {};
  		i.each(a.__rememberedObjects, function(d, e) {
  			var f = {};
  			i.each(a.__rememberedObjectIndecesToControllers[e], function(a, c) {
  				f[c] = b ? a.initialValue : a.getValue()
  			});
  			c[e] = f
  		});
  		return c
  	}
  
  	function C(a, b, c) {
  		var d = document.createElement("option");
  		d.innerHTML = b;
  		d.value = b;
  		a.__preset_select.appendChild(d);
  		if(c) a.__preset_select.selectedIndex = a.__preset_select.length - 1
  	}
  
  	function B(a, b) {
  		var c = a.__preset_select[a.__preset_select.selectedIndex];
  		c.innerHTML = b ? c.value + "*" : c.value
  	}
  
  	function E(a) {
  		a.length !=
  			0 && o(function() {
  				E(a)
  			});
  		i.each(a, function(a) {
  			a.updateDisplay()
  		})
  	}
  	e.inject(c);
  	var w = "Default",
  		u;
  	try {
  		u = "localStorage" in window && window.localStorage !== null
  	} catch(K) {
  		u = false
  	}
  	var x, F = true,
  		v, A = false,
  		G = [],
  		k = function(a) {
  			function b() {
  				localStorage.setItem(document.location.href + ".gui", JSON.stringify(d.getSaveObject()))
  			}
  
  			function c() {
  				var a = d.getRoot();
  				a.width += 1;
  				i.defer(function() {
  					a.width -= 1
  				})
  			}
  			var d = this;
  			this.domElement = document.createElement("div");
  			this.__ul = document.createElement("ul");
  			this.domElement.appendChild(this.__ul);
  			g.addClass(this.domElement, "dg");
  			this.__folders = {};
  			this.__controllers = [];
  			this.__rememberedObjects = [];
  			this.__rememberedObjectIndecesToControllers = [];
  			this.__listening = [];
  			a = a || {};
  			a = i.defaults(a, {
  				autoPlace: true,
  				width: k.DEFAULT_WIDTH
  			});
  			a = i.defaults(a, {
  				resizable: a.autoPlace,
  				hideable: a.autoPlace
  			});
  			if(i.isUndefined(a.load)) a.load = {
  				preset: w
  			};
  			else if(a.preset) a.load.preset = a.preset;
  			i.isUndefined(a.parent) && a.hideable && G.push(this);
  			a.resizable = i.isUndefined(a.parent) && a.resizable;
  			if(a.autoPlace && i.isUndefined(a.scrollable)) a.scrollable =
  				true;
  			var e = u && localStorage.getItem(document.location.href + ".isLocal") === "true";
  			Object.defineProperties(this, {
  				parent: {
  					get: function() {
  						return a.parent
  					}
  				},
  				scrollable: {
  					get: function() {
  						return a.scrollable
  					}
  				},
  				autoPlace: {
  					get: function() {
  						return a.autoPlace
  					}
  				},
  				preset: {
  					get: function() {
  						return d.parent ? d.getRoot().preset : a.load.preset
  					},
  					set: function(b) {
  						d.parent ? d.getRoot().preset = b : a.load.preset = b;
  						for(b = 0; b < this.__preset_select.length; b++)
  							if(this.__preset_select[b].value == this.preset) this.__preset_select.selectedIndex =
  								b;
  						d.revert()
  					}
  				},
  				width: {
  					get: function() {
  						return a.width
  					},
  					set: function(b) {
  						a.width = b;
  						D(d, b)
  					}
  				},
  				name: {
  					get: function() {
  						return a.name
  					},
  					set: function(b) {
  						a.name = b;
  						if(m) m.innerHTML = a.name
  					}
  				},
  				closed: {
  					get: function() {
  						return a.closed
  					},
  					set: function(b) {
  						a.closed = b;
  						a.closed ? g.addClass(d.__ul, k.CLASS_CLOSED) : g.removeClass(d.__ul, k.CLASS_CLOSED);
  						this.onResize();
  						if(d.__closeButton) d.__closeButton.innerHTML = b ? k.TEXT_OPEN : k.TEXT_CLOSED
  					}
  				},
  				load: {
  					get: function() {
  						return a.load
  					}
  				},
  				useLocalStorage: {
  					get: function() {
  						return e
  					},
  					set: function(a) {
  						u &&
  							((e = a) ? g.bind(window, "unload", b) : g.unbind(window, "unload", b), localStorage.setItem(document.location.href + ".isLocal", a))
  					}
  				}
  			});
  			if(i.isUndefined(a.parent)) {
  				a.closed = false;
  				g.addClass(this.domElement, k.CLASS_MAIN);
  				g.makeSelectable(this.domElement, false);
  				if(u && e) {
  					d.useLocalStorage = true;
  					var f = localStorage.getItem(document.location.href + ".gui");
  					if(f) a.load = JSON.parse(f)
  				}
  				this.__closeButton = document.createElement("div");
  				this.__closeButton.innerHTML = k.TEXT_CLOSED;
  				g.addClass(this.__closeButton, k.CLASS_CLOSE_BUTTON);
  				this.domElement.appendChild(this.__closeButton);
  				g.bind(this.__closeButton, "click", function() {
  					d.closed = !d.closed
  				})
  			} else {
  				if(a.closed === void 0) a.closed = true;
  				var m = document.createTextNode(a.name);
  				g.addClass(m, "controller-name");
  				f = s(d, m);
  				g.addClass(this.__ul, k.CLASS_CLOSED);
  				g.addClass(f, "title");
  				g.bind(f, "click", function(a) {
  					a.preventDefault();
  					d.closed = !d.closed;
  					return false
  				});
  				if(!a.closed) this.closed = false
  			}
  			a.autoPlace && (i.isUndefined(a.parent) && (F && (v = document.createElement("div"), g.addClass(v, "dg"), g.addClass(v,
  				k.CLASS_AUTO_PLACE_CONTAINER), document.body.appendChild(v), F = false), v.appendChild(this.domElement), g.addClass(this.domElement, k.CLASS_AUTO_PLACE)), this.parent || D(d, a.width));
  			g.bind(window, "resize", function() {
  				d.onResize()
  			});
  			g.bind(this.__ul, "webkitTransitionEnd", function() {
  				d.onResize()
  			});
  			g.bind(this.__ul, "transitionend", function() {
  				d.onResize()
  			});
  			g.bind(this.__ul, "oTransitionEnd", function() {
  				d.onResize()
  			});
  			this.onResize();
  			a.resizable && J(this);
  			d.getRoot();
  			a.parent || c()
  		};
  	k.toggleHide = function() {
  		A = !A;
  		i.each(G,
  			function(a) {
  				a.domElement.style.zIndex = A ? -999 : 999;
  				a.domElement.style.opacity = A ? 0 : 1
  			})
  	};
  	k.CLASS_AUTO_PLACE = "a";
  	k.CLASS_AUTO_PLACE_CONTAINER = "ac";
  	k.CLASS_MAIN = "main";
  	k.CLASS_CONTROLLER_ROW = "cr";
  	k.CLASS_TOO_TALL = "taller-than-window";
  	k.CLASS_CLOSED = "closed";
  	k.CLASS_CLOSE_BUTTON = "close-button";
  	k.CLASS_DRAG = "drag";
  	k.DEFAULT_WIDTH = 245;
  	k.TEXT_CLOSED = "Close Controls";
  	k.TEXT_OPEN = "Open Controls";
  	g.bind(window, "keydown", function(a) {
  			document.activeElement.type !== "text" && (a.which === 72 || a.keyCode == 72) && k.toggleHide()
  		},
  		false);
  	i.extend(k.prototype, {
  		add: function(a, b) {
  			return q(this, a, b, {
  				factoryArgs: Array.prototype.slice.call(arguments, 2)
  			})
  		},
  		addColor: function(a, b) {
  			return q(this, a, b, {
  				color: true
  			})
  		},
  		remove: function(a) {
  			this.__ul.removeChild(a.__li);
  			this.__controllers.slice(this.__controllers.indexOf(a), 1);
  			var b = this;
  			i.defer(function() {
  				b.onResize()
  			})
  		},
  		destroy: function() {
  			this.autoPlace && v.removeChild(this.domElement)
  		},
  		addFolder: function(a) {
  			if(this.__folders[a] !== void 0) throw Error('You already have a folder in this GUI by the name "' +
  				a + '"');
  			var b = {
  				name: a,
  				parent: this
  			};
  			b.autoPlace = this.autoPlace;
  			if(this.load && this.load.folders && this.load.folders[a]) b.closed = this.load.folders[a].closed, b.load = this.load.folders[a];
  			b = new k(b);
  			this.__folders[a] = b;
  			a = s(this, b.domElement);
  			g.addClass(a, "folder");
  			return b
  		},
  		open: function() {
  			this.closed = false
  		},
  		close: function() {
  			this.closed = true
  		},
  		onResize: function() {
  			var a = this.getRoot();
  			if(a.scrollable) {
  				var b = g.getOffset(a.__ul).top,
  					c = 0;
  				i.each(a.__ul.childNodes, function(b) {
  					a.autoPlace && b === a.__save_row || (c +=
  						g.getHeight(b))
  				});
  				window.innerHeight - b - 20 < c ? (g.addClass(a.domElement, k.CLASS_TOO_TALL), a.__ul.style.height = window.innerHeight - b - 20 + "px") : (g.removeClass(a.domElement, k.CLASS_TOO_TALL), a.__ul.style.height = "auto")
  			}
  			a.__resize_handle && i.defer(function() {
  				a.__resize_handle.style.height = a.__ul.offsetHeight + "px"
  			});
  			if(a.__closeButton) a.__closeButton.style.width = a.width + "px"
  		},
  		remember: function() {
  			if(i.isUndefined(x)) x = new y, x.domElement.innerHTML = a;
  			if(this.parent) throw Error("You can only call remember on a top level GUI.");
  			var b = this;
  			i.each(Array.prototype.slice.call(arguments), function(a) {
  				b.__rememberedObjects.length == 0 && I(b);
  				b.__rememberedObjects.indexOf(a) == -1 && b.__rememberedObjects.push(a)
  			});
  			this.autoPlace && D(this, this.width)
  		},
  		getRoot: function() {
  			for(var a = this; a.parent;) a = a.parent;
  			return a
  		},
  		getSaveObject: function() {
  			var a = this.load;
  			a.closed = this.closed;
  			if(this.__rememberedObjects.length > 0) {
  				a.preset = this.preset;
  				if(!a.remembered) a.remembered = {};
  				a.remembered[this.preset] = z(this)
  			}
  			a.folders = {};
  			i.each(this.__folders, function(b,
  				c) {
  				a.folders[c] = b.getSaveObject()
  			});
  			return a
  		},
  		save: function() {
  			if(!this.load.remembered) this.load.remembered = {};
  			this.load.remembered[this.preset] = z(this);
  			B(this, false)
  		},
  		saveAs: function(a) {
  			if(!this.load.remembered) this.load.remembered = {}, this.load.remembered[w] = z(this, true);
  			this.load.remembered[a] = z(this);
  			this.preset = a;
  			C(this, a, true)
  		},
  		revert: function(a) {
  			i.each(this.__controllers, function(b) {
  				this.getRoot().load.remembered ? t(a || this.getRoot(), b) : b.setValue(b.initialValue)
  			}, this);
  			i.each(this.__folders,
  				function(a) {
  					a.revert(a)
  				});
  			a || B(this.getRoot(), false)
  		},
  		listen: function(a) {
  			var b = this.__listening.length == 0;
  			this.__listening.push(a);
  			b && E(this.__listening)
  		}
  	});
  	return k
  }(dat.utils.css, '<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>',
  	".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",
  	dat.controllers.factory = function(e, a, c, d, f, b, n) {
  		return function(h, j, m, l) {
  			var o = h[j];
  			if(n.isArray(m) || n.isObject(m)) return new e(h, j, m);
  			if(n.isNumber(o)) return n.isNumber(m) && n.isNumber(l) ? new c(h, j, m, l) : new a(h, j, {
  				min: m,
  				max: l
  			});
  			if(n.isString(o)) return new d(h, j);
  			if(n.isFunction(o)) return new f(h, j, "");
  			if(n.isBoolean(o)) return new b(h, j)
  		}
  	}(dat.controllers.OptionController, dat.controllers.NumberControllerBox, dat.controllers.NumberControllerSlider, dat.controllers.StringController = function(e, a, c) {
  		var d =
  			function(c, b) {
  				function e() {
  					h.setValue(h.__input.value)
  				}
  				d.superclass.call(this, c, b);
  				var h = this;
  				this.__input = document.createElement("input");
  				this.__input.setAttribute("type", "text");
  				a.bind(this.__input, "keyup", e);
  				a.bind(this.__input, "change", e);
  				a.bind(this.__input, "blur", function() {
  					h.__onFinishChange && h.__onFinishChange.call(h, h.getValue())
  				});
  				a.bind(this.__input, "keydown", function(a) {
  					a.keyCode === 13 && this.blur()
  				});
  				this.updateDisplay();
  				this.domElement.appendChild(this.__input)
  			};
  		d.superclass = e;
  		c.extend(d.prototype,
  			e.prototype, {
  				updateDisplay: function() {
  					if(!a.isActive(this.__input)) this.__input.value = this.getValue();
  					return d.superclass.prototype.updateDisplay.call(this)
  				}
  			});
  		return d
  	}(dat.controllers.Controller, dat.dom.dom, dat.utils.common), dat.controllers.FunctionController, dat.controllers.BooleanController, dat.utils.common), dat.controllers.Controller, dat.controllers.BooleanController, dat.controllers.FunctionController, dat.controllers.NumberControllerBox, dat.controllers.NumberControllerSlider, dat.controllers.OptionController,
  	dat.controllers.ColorController = function(e, a, c, d, f) {
  		function b(a, b, c, d) {
  			a.style.background = "";
  			f.each(j, function(e) {
  				a.style.cssText += "background: " + e + "linear-gradient(" + b + ", " + c + " 0%, " + d + " 100%); "
  			})
  		}
  
  		function n(a) {
  			a.style.background = "";
  			a.style.cssText += "background: -moz-linear-gradient(top,  #ff0000 0%, #ff00ff 17%, #0000ff 34%, #00ffff 50%, #00ff00 67%, #ffff00 84%, #ff0000 100%);";
  			a.style.cssText += "background: -webkit-linear-gradient(top,  #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);";
  			a.style.cssText += "background: -o-linear-gradient(top,  #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);";
  			a.style.cssText += "background: -ms-linear-gradient(top,  #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);";
  			a.style.cssText += "background: linear-gradient(top,  #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);"
  		}
  		var h = function(e, l) {
  			function o(b) {
  				q(b);
  				a.bind(window, "mousemove", q);
  				a.bind(window,
  					"mouseup", j)
  			}
  
  			function j() {
  				a.unbind(window, "mousemove", q);
  				a.unbind(window, "mouseup", j)
  			}
  
  			function g() {
  				var a = d(this.value);
  				a !== false ? (p.__color.__state = a, p.setValue(p.__color.toOriginal())) : this.value = p.__color.toString()
  			}
  
  			function i() {
  				a.unbind(window, "mousemove", s);
  				a.unbind(window, "mouseup", i)
  			}
  
  			function q(b) {
  				b.preventDefault();
  				var c = a.getWidth(p.__saturation_field),
  					d = a.getOffset(p.__saturation_field),
  					e = (b.clientX - d.left + document.body.scrollLeft) / c,
  					b = 1 - (b.clientY - d.top + document.body.scrollTop) / c;
  				b > 1 ? b =
  					1 : b < 0 && (b = 0);
  				e > 1 ? e = 1 : e < 0 && (e = 0);
  				p.__color.v = b;
  				p.__color.s = e;
  				p.setValue(p.__color.toOriginal());
  				return false
  			}
  
  			function s(b) {
  				b.preventDefault();
  				var c = a.getHeight(p.__hue_field),
  					d = a.getOffset(p.__hue_field),
  					b = 1 - (b.clientY - d.top + document.body.scrollTop) / c;
  				b > 1 ? b = 1 : b < 0 && (b = 0);
  				p.__color.h = b * 360;
  				p.setValue(p.__color.toOriginal());
  				return false
  			}
  			h.superclass.call(this, e, l);
  			this.__color = new c(this.getValue());
  			this.__temp = new c(0);
  			var p = this;
  			this.domElement = document.createElement("div");
  			a.makeSelectable(this.domElement,
  				false);
  			this.__selector = document.createElement("div");
  			this.__selector.className = "selector";
  			this.__saturation_field = document.createElement("div");
  			this.__saturation_field.className = "saturation-field";
  			this.__field_knob = document.createElement("div");
  			this.__field_knob.className = "field-knob";
  			this.__field_knob_border = "2px solid ";
  			this.__hue_knob = document.createElement("div");
  			this.__hue_knob.className = "hue-knob";
  			this.__hue_field = document.createElement("div");
  			this.__hue_field.className = "hue-field";
  			this.__input =
  				document.createElement("input");
  			this.__input.type = "text";
  			this.__input_textShadow = "0 1px 1px ";
  			a.bind(this.__input, "keydown", function(a) {
  				a.keyCode === 13 && g.call(this)
  			});
  			a.bind(this.__input, "blur", g);
  			a.bind(this.__selector, "mousedown", function() {
  				a.addClass(this, "drag").bind(window, "mouseup", function() {
  					a.removeClass(p.__selector, "drag")
  				})
  			});
  			var t = document.createElement("div");
  			f.extend(this.__selector.style, {
  				width: "122px",
  				height: "102px",
  				padding: "3px",
  				backgroundColor: "#222",
  				boxShadow: "0px 1px 3px rgba(0,0,0,0.3)"
  			});
  			f.extend(this.__field_knob.style, {
  				position: "absolute",
  				width: "12px",
  				height: "12px",
  				border: this.__field_knob_border + (this.__color.v < 0.5 ? "#fff" : "#000"),
  				boxShadow: "0px 1px 3px rgba(0,0,0,0.5)",
  				borderRadius: "12px",
  				zIndex: 1
  			});
  			f.extend(this.__hue_knob.style, {
  				position: "absolute",
  				width: "15px",
  				height: "2px",
  				borderRight: "4px solid #fff",
  				zIndex: 1
  			});
  			f.extend(this.__saturation_field.style, {
  				width: "100px",
  				height: "100px",
  				border: "1px solid #555",
  				marginRight: "3px",
  				display: "inline-block",
  				cursor: "pointer"
  			});
  			f.extend(t.style, {
  				width: "100%",
  				height: "100%",
  				background: "none"
  			});
  			b(t, "top", "rgba(0,0,0,0)", "#000");
  			f.extend(this.__hue_field.style, {
  				width: "15px",
  				height: "100px",
  				display: "inline-block",
  				border: "1px solid #555",
  				cursor: "ns-resize"
  			});
  			n(this.__hue_field);
  			f.extend(this.__input.style, {
  				outline: "none",
  				textAlign: "center",
  				color: "#fff",
  				border: 0,
  				fontWeight: "bold",
  				textShadow: this.__input_textShadow + "rgba(0,0,0,0.7)"
  			});
  			a.bind(this.__saturation_field, "mousedown", o);
  			a.bind(this.__field_knob, "mousedown", o);
  			a.bind(this.__hue_field, "mousedown",
  				function(b) {
  					s(b);
  					a.bind(window, "mousemove", s);
  					a.bind(window, "mouseup", i)
  				});
  			this.__saturation_field.appendChild(t);
  			this.__selector.appendChild(this.__field_knob);
  			this.__selector.appendChild(this.__saturation_field);
  			this.__selector.appendChild(this.__hue_field);
  			this.__hue_field.appendChild(this.__hue_knob);
  			this.domElement.appendChild(this.__input);
  			this.domElement.appendChild(this.__selector);
  			this.updateDisplay()
  		};
  		h.superclass = e;
  		f.extend(h.prototype, e.prototype, {
  			updateDisplay: function() {
  				var a = d(this.getValue());
  				if(a !== false) {
  					var e = false;
  					f.each(c.COMPONENTS, function(b) {
  						if(!f.isUndefined(a[b]) && !f.isUndefined(this.__color.__state[b]) && a[b] !== this.__color.__state[b]) return e = true, {}
  					}, this);
  					e && f.extend(this.__color.__state, a)
  				}
  				f.extend(this.__temp.__state, this.__color.__state);
  				this.__temp.a = 1;
  				var h = this.__color.v < 0.5 || this.__color.s > 0.5 ? 255 : 0,
  					j = 255 - h;
  				f.extend(this.__field_knob.style, {
  					marginLeft: 100 * this.__color.s - 7 + "px",
  					marginTop: 100 * (1 - this.__color.v) - 7 + "px",
  					backgroundColor: this.__temp.toString(),
  					border: this.__field_knob_border +
  						"rgb(" + h + "," + h + "," + h + ")"
  				});
  				this.__hue_knob.style.marginTop = (1 - this.__color.h / 360) * 100 + "px";
  				this.__temp.s = 1;
  				this.__temp.v = 1;
  				b(this.__saturation_field, "left", "#fff", this.__temp.toString());
  				f.extend(this.__input.style, {
  					backgroundColor: this.__input.value = this.__color.toString(),
  					color: "rgb(" + h + "," + h + "," + h + ")",
  					textShadow: this.__input_textShadow + "rgba(" + j + "," + j + "," + j + ",.7)"
  				})
  			}
  		});
  		var j = ["-moz-", "-o-", "-webkit-", "-ms-", ""];
  		return h
  	}(dat.controllers.Controller, dat.dom.dom, dat.color.Color = function(e, a, c, d) {
  		function f(a,
  			b, c) {
  			Object.defineProperty(a, b, {
  				get: function() {
  					if(this.__state.space === "RGB") return this.__state[b];
  					n(this, b, c);
  					return this.__state[b]
  				},
  				set: function(a) {
  					if(this.__state.space !== "RGB") n(this, b, c), this.__state.space = "RGB";
  					this.__state[b] = a
  				}
  			})
  		}
  
  		function b(a, b) {
  			Object.defineProperty(a, b, {
  				get: function() {
  					if(this.__state.space === "HSV") return this.__state[b];
  					h(this);
  					return this.__state[b]
  				},
  				set: function(a) {
  					if(this.__state.space !== "HSV") h(this), this.__state.space = "HSV";
  					this.__state[b] = a
  				}
  			})
  		}
  
  		function n(b, c, e) {
  			if(b.__state.space ===
  				"HEX") b.__state[c] = a.component_from_hex(b.__state.hex, e);
  			else if(b.__state.space === "HSV") d.extend(b.__state, a.hsv_to_rgb(b.__state.h, b.__state.s, b.__state.v));
  			else throw "Corrupted color state";
  		}
  
  		function h(b) {
  			var c = a.rgb_to_hsv(b.r, b.g, b.b);
  			d.extend(b.__state, {
  				s: c.s,
  				v: c.v
  			});
  			if(d.isNaN(c.h)) {
  				if(d.isUndefined(b.__state.h)) b.__state.h = 0
  			} else b.__state.h = c.h
  		}
  		var j = function() {
  			this.__state = e.apply(this, arguments);
  			if(this.__state === false) throw "Failed to interpret color arguments";
  			this.__state.a = this.__state.a ||
  				1
  		};
  		j.COMPONENTS = "r,g,b,h,s,v,hex,a".split(",");
  		d.extend(j.prototype, {
  			toString: function() {
  				return c(this)
  			},
  			toOriginal: function() {
  				return this.__state.conversion.write(this)
  			}
  		});
  		f(j.prototype, "r", 2);
  		f(j.prototype, "g", 1);
  		f(j.prototype, "b", 0);
  		b(j.prototype, "h");
  		b(j.prototype, "s");
  		b(j.prototype, "v");
  		Object.defineProperty(j.prototype, "a", {
  			get: function() {
  				return this.__state.a
  			},
  			set: function(a) {
  				this.__state.a = a
  			}
  		});
  		Object.defineProperty(j.prototype, "hex", {
  			get: function() {
  				if(!this.__state.space !== "HEX") this.__state.hex =
  					a.rgb_to_hex(this.r, this.g, this.b);
  				return this.__state.hex
  			},
  			set: function(a) {
  				this.__state.space = "HEX";
  				this.__state.hex = a
  			}
  		});
  		return j
  	}(dat.color.interpret, dat.color.math = function() {
  		var e;
  		return {
  			hsv_to_rgb: function(a, c, d) {
  				var e = a / 60 - Math.floor(a / 60),
  					b = d * (1 - c),
  					n = d * (1 - e * c),
  					c = d * (1 - (1 - e) * c),
  					a = [
  						[d, c, b],
  						[n, d, b],
  						[b, d, c],
  						[b, n, d],
  						[c, b, d],
  						[d, b, n]
  					][Math.floor(a / 60) % 6];
  				return {
  					r: a[0] * 255,
  					g: a[1] * 255,
  					b: a[2] * 255
  				}
  			},
  			rgb_to_hsv: function(a, c, d) {
  				var e = Math.min(a, c, d),
  					b = Math.max(a, c, d),
  					e = b - e;
  				if(b == 0) return {
  					h: NaN,
  					s: 0,
  					v: 0
  				};
  				a = a == b ? (c - d) / e : c == b ? 2 + (d - a) / e : 4 + (a - c) / e;
  				a /= 6;
  				a < 0 && (a += 1);
  				return {
  					h: a * 360,
  					s: e / b,
  					v: b / 255
  				}
  			},
  			rgb_to_hex: function(a, c, d) {
  				a = this.hex_with_component(0, 2, a);
  				a = this.hex_with_component(a, 1, c);
  				return a = this.hex_with_component(a, 0, d)
  			},
  			component_from_hex: function(a, c) {
  				return a >> c * 8 & 255
  			},
  			hex_with_component: function(a, c, d) {
  				return d << (e = c * 8) | a & ~(255 << e)
  			}
  		}
  	}(), dat.color.toString, dat.utils.common), dat.color.interpret, dat.utils.common), dat.utils.requestAnimationFrame = function() {
  		return window.requestAnimationFrame || window.webkitRequestAnimationFrame ||
  			window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(e) {
  				window.setTimeout(e, 1E3 / 60)
  			}
  	}(), dat.dom.CenteredDiv = function(e, a) {
  		var c = function() {
  			this.backgroundElement = document.createElement("div");
  			a.extend(this.backgroundElement.style, {
  				backgroundColor: "rgba(0,0,0,0.8)",
  				top: 0,
  				left: 0,
  				display: "none",
  				zIndex: "1000",
  				opacity: 0,
  				WebkitTransition: "opacity 0.2s linear"
  			});
  			e.makeFullscreen(this.backgroundElement);
  			this.backgroundElement.style.position = "fixed";
  			this.domElement =
  				document.createElement("div");
  			a.extend(this.domElement.style, {
  				position: "fixed",
  				display: "none",
  				zIndex: "1001",
  				opacity: 0,
  				WebkitTransition: "-webkit-transform 0.2s ease-out, opacity 0.2s linear"
  			});
  			document.body.appendChild(this.backgroundElement);
  			document.body.appendChild(this.domElement);
  			var c = this;
  			e.bind(this.backgroundElement, "click", function() {
  				c.hide()
  			})
  		};
  		c.prototype.show = function() {
  			var c = this;
  			this.backgroundElement.style.display = "block";
  			this.domElement.style.display = "block";
  			this.domElement.style.opacity =
  				0;
  			this.domElement.style.webkitTransform = "scale(1.1)";
  			this.layout();
  			a.defer(function() {
  				c.backgroundElement.style.opacity = 1;
  				c.domElement.style.opacity = 1;
  				c.domElement.style.webkitTransform = "scale(1)"
  			})
  		};
  		c.prototype.hide = function() {
  			var a = this,
  				c = function() {
  					a.domElement.style.display = "none";
  					a.backgroundElement.style.display = "none";
  					e.unbind(a.domElement, "webkitTransitionEnd", c);
  					e.unbind(a.domElement, "transitionend", c);
  					e.unbind(a.domElement, "oTransitionEnd", c)
  				};
  			e.bind(this.domElement, "webkitTransitionEnd",
  				c);
  			e.bind(this.domElement, "transitionend", c);
  			e.bind(this.domElement, "oTransitionEnd", c);
  			this.backgroundElement.style.opacity = 0;
  			this.domElement.style.opacity = 0;
  			this.domElement.style.webkitTransform = "scale(1.1)"
  		};
  		c.prototype.layout = function() {
  			this.domElement.style.left = window.innerWidth / 2 - e.getWidth(this.domElement) / 2 + "px";
  			this.domElement.style.top = window.innerHeight / 2 - e.getHeight(this.domElement) / 2 + "px"
  		};
  		return c
  	}(dat.dom.dom, dat.utils.common), dat.dom.dom, dat.utils.common);