[
  {
    "path": ".babelrc",
    "content": "{\n  \"presets\": [\n    [\"env\", {\n      \"modules\": false\n    }]\n  ]\n}\n"
  },
  {
    "path": ".gitignore",
    "content": ".DS_Store\n.sass-cache\n.idea/\nnode_modules/\ntmp/\n"
  },
  {
    "path": "API.md",
    "content": "# dat.GUI API\n\nDetails about the classes, methods, and properties provided by dat.GUI. For more\nhands-on examples, see the dat.GUI [tutorial](http://workshop.chromeexperiments.com/examples/gui).\n\n<!--- API BEGIN --->\n\n## Classes\n\n<dl>\n<dt><a href=\"#GUI\">GUI</a></dt>\n<dd><p>A lightweight controller library for JavaScript. It allows you to easily\nmanipulate variables and fire functions on the fly.</p>\n</dd>\n<dt><a href=\"#Controller\">Controller</a></dt>\n<dd><p>An &quot;abstract&quot; class that represents a given property of an object.</p>\n</dd>\n<dt><a href=\"#NumberController\">NumberController</a> ⇐ <code>dat.controllers.Controller</code></dt>\n<dd><p>Represents a given property of an object that is a number.</p>\n</dd>\n</dl>\n\n<a name=\"GUI\"></a>\n\n## GUI\nA lightweight controller library for JavaScript. It allows you to easily\nmanipulate variables and fire functions on the fly.\n\n**Kind**: global class  \n\n* [GUI](#GUI)\n    * [new GUI([params])](#new_GUI_new)\n    * [.domElement](#GUI+domElement) : <code>DOMElement</code>\n    * [.parent](#GUI+parent) : <code>dat.gui.GUI</code>\n    * [.autoPlace](#GUI+autoPlace) : <code>Boolean</code>\n    * [.closeOnTop](#GUI+closeOnTop) : <code>Boolean</code>\n    * [.preset](#GUI+preset) : <code>String</code>\n    * [.width](#GUI+width) : <code>Number</code>\n    * [.name](#GUI+name) : <code>String</code>\n    * [.closed](#GUI+closed) : <code>Boolean</code>\n    * [.load](#GUI+load) : <code>Object</code>\n    * [.useLocalStorage](#GUI+useLocalStorage) : <code>Boolean</code>\n    * [.add(object, property, [min], [max], [step])](#GUI+add) ⇒ [<code>Controller</code>](#Controller)\n    * [.addColor(object, property)](#GUI+addColor) ⇒ [<code>Controller</code>](#Controller)\n    * [.remove(controller)](#GUI+remove)\n    * [.destroy()](#GUI+destroy)\n    * [.addFolder(name)](#GUI+addFolder) ⇒ <code>dat.gui.GUI</code>\n    * [.removeFolder(folder)](#GUI+removeFolder)\n    * [.open()](#GUI+open)\n    * [.close()](#GUI+close)\n    * [.hide()](#GUI+hide)\n    * [.show()](#GUI+show)\n    * [.getRoot()](#GUI+getRoot) ⇒ <code>dat.gui.GUI</code>\n    * [.getSaveObject()](#GUI+getSaveObject) ⇒ <code>Object</code>\n\n<a name=\"new_GUI_new\"></a>\n\n### new GUI([params])\n\n| Param | Type | Default | Description |\n| --- | --- | --- | --- |\n| [params] | <code>Object</code> |  |  |\n| [params.name] | <code>String</code> |  | The name of this GUI. |\n| [params.load] | <code>Object</code> |  | JSON object representing the saved state of this GUI. |\n| [params.parent] | <code>dat.gui.GUI</code> |  | The GUI I'm nested in. |\n| [params.autoPlace] | <code>Boolean</code> | <code>true</code> |  |\n| [params.hideable] | <code>Boolean</code> | <code>true</code> | If true, GUI is shown/hidden by <kbd>h</kbd> keypress. |\n| [params.closed] | <code>Boolean</code> | <code>false</code> | If true, starts closed |\n| [params.closeOnTop] | <code>Boolean</code> | <code>false</code> | If true, close/open button shows on top of the GUI |\n\n**Example**  \n```js\n// Creating a GUI with options.\nvar gui = new dat.GUI({name: 'My GUI'});\n```\n**Example**  \n```js\n// Creating a GUI and a subfolder.\nvar gui = new dat.GUI();\nvar folder1 = gui.addFolder('Flow Field');\n```\n<a name=\"GUI+domElement\"></a>\n\n### gui.domElement : <code>DOMElement</code>\nOutermost DOM Element\n\n**Kind**: instance property of [<code>GUI</code>](#GUI)  \n<a name=\"GUI+parent\"></a>\n\n### gui.parent : <code>dat.gui.GUI</code>\nThe parent <code>GUI</code>\n\n**Kind**: instance property of [<code>GUI</code>](#GUI)  \n<a name=\"GUI+autoPlace\"></a>\n\n### gui.autoPlace : <code>Boolean</code>\nHandles <code>GUI</code>'s element placement for you\n\n**Kind**: instance property of [<code>GUI</code>](#GUI)  \n<a name=\"GUI+closeOnTop\"></a>\n\n### gui.closeOnTop : <code>Boolean</code>\nHandles <code>GUI</code>'s position of open/close button\n\n**Kind**: instance property of [<code>GUI</code>](#GUI)  \n<a name=\"GUI+preset\"></a>\n\n### gui.preset : <code>String</code>\nThe identifier for a set of saved values\n\n**Kind**: instance property of [<code>GUI</code>](#GUI)  \n<a name=\"GUI+width\"></a>\n\n### gui.width : <code>Number</code>\nThe width of <code>GUI</code> element\n\n**Kind**: instance property of [<code>GUI</code>](#GUI)  \n<a name=\"GUI+name\"></a>\n\n### gui.name : <code>String</code>\nThe name of <code>GUI</code>. Used for folders. i.e\na folder's name\n\n**Kind**: instance property of [<code>GUI</code>](#GUI)  \n<a name=\"GUI+closed\"></a>\n\n### gui.closed : <code>Boolean</code>\nWhether the <code>GUI</code> is collapsed or not\n\n**Kind**: instance property of [<code>GUI</code>](#GUI)  \n<a name=\"GUI+load\"></a>\n\n### gui.load : <code>Object</code>\nContains all presets\n\n**Kind**: instance property of [<code>GUI</code>](#GUI)  \n<a name=\"GUI+useLocalStorage\"></a>\n\n### gui.useLocalStorage : <code>Boolean</code>\nDetermines 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\n**Kind**: instance property of [<code>GUI</code>](#GUI)  \n<a name=\"GUI+add\"></a>\n\n### gui.add(object, property, [min], [max], [step]) ⇒ [<code>Controller</code>](#Controller)\nAdds a new [Controller](#Controller) to the GUI. The type of controller created\nis inferred from the initial value of <code>object[property]</code>. For\ncolor properties, see [addColor](addColor).\n\n**Kind**: instance method of [<code>GUI</code>](#GUI)  \n**Returns**: [<code>Controller</code>](#Controller) - The controller that was added to the GUI.  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| object | <code>Object</code> | The object to be manipulated |\n| property | <code>String</code> | The name of the property to be manipulated |\n| [min] | <code>Number</code> | Minimum allowed value |\n| [max] | <code>Number</code> | Maximum allowed value |\n| [step] | <code>Number</code> | Increment by which to change value |\n\n**Example**  \n```js\n// Add a string controller.\nvar person = {name: 'Sam'};\ngui.add(person, 'name');\n```\n**Example**  \n```js\n// Add a number controller slider.\nvar person = {age: 45};\ngui.add(person, 'age', 0, 100);\n```\n<a name=\"GUI+addColor\"></a>\n\n### gui.addColor(object, property) ⇒ [<code>Controller</code>](#Controller)\nAdds a new color controller to the GUI.\n\n**Kind**: instance method of [<code>GUI</code>](#GUI)  \n**Returns**: [<code>Controller</code>](#Controller) - The controller that was added to the GUI.  \n\n| Param |\n| --- |\n| object | \n| property | \n\n**Example**  \n```js\nvar palette = {\n  color1: '#FF0000', // CSS string\n  color2: [ 0, 128, 255 ], // RGB array\n  color3: [ 0, 128, 255, 0.3 ], // RGB with alpha\n  color4: { h: 350, s: 0.9, v: 0.3 } // Hue, saturation, value\n};\ngui.addColor(palette, 'color1');\ngui.addColor(palette, 'color2');\ngui.addColor(palette, 'color3');\ngui.addColor(palette, 'color4');\n```\n<a name=\"GUI+remove\"></a>\n\n### gui.remove(controller)\nRemoves the given controller from the GUI.\n\n**Kind**: instance method of [<code>GUI</code>](#GUI)  \n\n| Param | Type |\n| --- | --- |\n| controller | [<code>Controller</code>](#Controller) | \n\n<a name=\"GUI+destroy\"></a>\n\n### gui.destroy()\nRemoves the root GUI from the document and unbinds all event listeners.\nFor subfolders, use `gui.removeFolder(folder)` instead.\n\n**Kind**: instance method of [<code>GUI</code>](#GUI)  \n<a name=\"GUI+addFolder\"></a>\n\n### gui.addFolder(name) ⇒ <code>dat.gui.GUI</code>\nCreates a new subfolder GUI instance.\n\n**Kind**: instance method of [<code>GUI</code>](#GUI)  \n**Returns**: <code>dat.gui.GUI</code> - The new folder.  \n**Throws**:\n\n- <code>Error</code> if this GUI already has a folder by the specified\nname\n\n\n| Param |\n| --- |\n| name | \n\n<a name=\"GUI+removeFolder\"></a>\n\n### gui.removeFolder(folder)\nRemoves a subfolder GUI instance.\n\n**Kind**: instance method of [<code>GUI</code>](#GUI)  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| folder | <code>dat.gui.GUI</code> | The folder to remove. |\n\n<a name=\"GUI+open\"></a>\n\n### gui.open()\nOpens the GUI.\n\n**Kind**: instance method of [<code>GUI</code>](#GUI)  \n<a name=\"GUI+close\"></a>\n\n### gui.close()\nCloses the GUI.\n\n**Kind**: instance method of [<code>GUI</code>](#GUI)  \n<a name=\"GUI+hide\"></a>\n\n### gui.hide()\nHides the GUI.\n\n**Kind**: instance method of [<code>GUI</code>](#GUI)  \n<a name=\"GUI+show\"></a>\n\n### gui.show()\nShows the GUI.\n\n**Kind**: instance method of [<code>GUI</code>](#GUI)  \n<a name=\"GUI+getRoot\"></a>\n\n### gui.getRoot() ⇒ <code>dat.gui.GUI</code>\n**Kind**: instance method of [<code>GUI</code>](#GUI)  \n**Returns**: <code>dat.gui.GUI</code> - the topmost parent GUI of a nested GUI.  \n<a name=\"GUI+getSaveObject\"></a>\n\n### gui.getSaveObject() ⇒ <code>Object</code>\n**Kind**: instance method of [<code>GUI</code>](#GUI)  \n**Returns**: <code>Object</code> - a JSON object representing the current state of\nthis GUI as well as its remembered properties.  \n<a name=\"Controller\"></a>\n\n## Controller\nAn \"abstract\" class that represents a given property of an object.\n\n**Kind**: global class  \n\n* [Controller](#Controller)\n    * [new Controller(object, property)](#new_Controller_new)\n    * [.domElement](#Controller+domElement) : <code>DOMElement</code>\n    * [.object](#Controller+object) : <code>Object</code>\n    * [.property](#Controller+property) : <code>String</code>\n    * [.options(options)](#Controller+options) ⇒ [<code>Controller</code>](#Controller)\n    * [.name(name)](#Controller+name) ⇒ [<code>Controller</code>](#Controller)\n    * [.listen()](#Controller+listen) ⇒ [<code>Controller</code>](#Controller)\n    * [.remove()](#Controller+remove) ⇒ [<code>Controller</code>](#Controller)\n    * [.onChange(fnc)](#Controller+onChange) ⇒ [<code>Controller</code>](#Controller)\n    * [.onFinishChange(fnc)](#Controller+onFinishChange) ⇒ [<code>Controller</code>](#Controller)\n    * [.setValue(newValue)](#Controller+setValue)\n    * [.getValue()](#Controller+getValue) ⇒ <code>Object</code>\n    * [.updateDisplay()](#Controller+updateDisplay) ⇒ [<code>Controller</code>](#Controller)\n    * [.isModified()](#Controller+isModified) ⇒ <code>Boolean</code>\n\n<a name=\"new_Controller_new\"></a>\n\n### new Controller(object, property)\n\n| Param | Type | Description |\n| --- | --- | --- |\n| object | <code>Object</code> | The object to be manipulated |\n| property | <code>string</code> | The name of the property to be manipulated |\n\n<a name=\"Controller+domElement\"></a>\n\n### controller.domElement : <code>DOMElement</code>\nThose who extend this class will put their DOM elements in here.\n\n**Kind**: instance property of [<code>Controller</code>](#Controller)  \n<a name=\"Controller+object\"></a>\n\n### controller.object : <code>Object</code>\nThe object to manipulate\n\n**Kind**: instance property of [<code>Controller</code>](#Controller)  \n<a name=\"Controller+property\"></a>\n\n### controller.property : <code>String</code>\nThe name of the property to manipulate\n\n**Kind**: instance property of [<code>Controller</code>](#Controller)  \n<a name=\"Controller+options\"></a>\n\n### controller.options(options) ⇒ [<code>Controller</code>](#Controller)\n**Kind**: instance method of [<code>Controller</code>](#Controller)  \n\n| Param | Type |\n| --- | --- |\n| options | <code>Array</code> \\| <code>Object</code> | \n\n<a name=\"Controller+name\"></a>\n\n### controller.name(name) ⇒ [<code>Controller</code>](#Controller)\nSets the name of the controller.\n\n**Kind**: instance method of [<code>Controller</code>](#Controller)  \n\n| Param | Type |\n| --- | --- |\n| name | <code>string</code> | \n\n<a name=\"Controller+listen\"></a>\n\n### controller.listen() ⇒ [<code>Controller</code>](#Controller)\nSets controller to listen for changes on its underlying object.\n\n**Kind**: instance method of [<code>Controller</code>](#Controller)  \n<a name=\"Controller+remove\"></a>\n\n### controller.remove() ⇒ [<code>Controller</code>](#Controller)\nRemoves the controller from its parent GUI.\n\n**Kind**: instance method of [<code>Controller</code>](#Controller)  \n<a name=\"Controller+onChange\"></a>\n\n### controller.onChange(fnc) ⇒ [<code>Controller</code>](#Controller)\nSpecify that a function fire every time someone changes the value with\nthis Controller.\n\n**Kind**: instance method of [<code>Controller</code>](#Controller)  \n**Returns**: [<code>Controller</code>](#Controller) - this  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| fnc | <code>function</code> | This function will be called whenever the value is modified via this Controller. |\n\n<a name=\"Controller+onFinishChange\"></a>\n\n### controller.onFinishChange(fnc) ⇒ [<code>Controller</code>](#Controller)\nSpecify that a function fire every time someone \"finishes\" changing\nthe value wih this Controller. Useful for values that change\nincrementally like numbers or strings.\n\n**Kind**: instance method of [<code>Controller</code>](#Controller)  \n**Returns**: [<code>Controller</code>](#Controller) - this  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| fnc | <code>function</code> | This function will be called whenever someone \"finishes\" changing the value via this Controller. |\n\n<a name=\"Controller+setValue\"></a>\n\n### controller.setValue(newValue)\nChange the value of <code>object[property]</code>\n\n**Kind**: instance method of [<code>Controller</code>](#Controller)  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| newValue | <code>Object</code> | The new value of <code>object[property]</code> |\n\n<a name=\"Controller+getValue\"></a>\n\n### controller.getValue() ⇒ <code>Object</code>\nGets the value of <code>object[property]</code>\n\n**Kind**: instance method of [<code>Controller</code>](#Controller)  \n**Returns**: <code>Object</code> - The current value of <code>object[property]</code>  \n<a name=\"Controller+updateDisplay\"></a>\n\n### controller.updateDisplay() ⇒ [<code>Controller</code>](#Controller)\nRefreshes the visual display of a Controller in order to keep sync\nwith the object's current value.\n\n**Kind**: instance method of [<code>Controller</code>](#Controller)  \n**Returns**: [<code>Controller</code>](#Controller) - this  \n<a name=\"Controller+isModified\"></a>\n\n### controller.isModified() ⇒ <code>Boolean</code>\n**Kind**: instance method of [<code>Controller</code>](#Controller)  \n**Returns**: <code>Boolean</code> - true if the value has deviated from initialValue  \n<a name=\"NumberController\"></a>\n\n## NumberController ⇐ <code>dat.controllers.Controller</code>\nRepresents a given property of an object that is a number.\n\n**Kind**: global class  \n**Extends**: <code>dat.controllers.Controller</code>  \n\n* [NumberController](#NumberController) ⇐ <code>dat.controllers.Controller</code>\n    * [new NumberController(object, property, [params])](#new_NumberController_new)\n    * [.min(minValue)](#NumberController+min) ⇒ <code>dat.controllers.NumberController</code>\n    * [.max(maxValue)](#NumberController+max) ⇒ <code>dat.controllers.NumberController</code>\n    * [.step(stepValue)](#NumberController+step) ⇒ <code>dat.controllers.NumberController</code>\n\n<a name=\"new_NumberController_new\"></a>\n\n### new NumberController(object, property, [params])\n\n| Param | Type | Description |\n| --- | --- | --- |\n| object | <code>Object</code> | The object to be manipulated |\n| property | <code>string</code> | The name of the property to be manipulated |\n| [params] | <code>Object</code> | Optional parameters |\n| [params.min] | <code>Number</code> | Minimum allowed value |\n| [params.max] | <code>Number</code> | Maximum allowed value |\n| [params.step] | <code>Number</code> | Increment by which to change value |\n\n<a name=\"NumberController+min\"></a>\n\n### numberController.min(minValue) ⇒ <code>dat.controllers.NumberController</code>\nSpecify a minimum value for <code>object[property]</code>.\n\n**Kind**: instance method of [<code>NumberController</code>](#NumberController)  \n**Returns**: <code>dat.controllers.NumberController</code> - this  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| minValue | <code>Number</code> | The minimum value for <code>object[property]</code> |\n\n<a name=\"NumberController+max\"></a>\n\n### numberController.max(maxValue) ⇒ <code>dat.controllers.NumberController</code>\nSpecify a maximum value for <code>object[property]</code>.\n\n**Kind**: instance method of [<code>NumberController</code>](#NumberController)  \n**Returns**: <code>dat.controllers.NumberController</code> - this  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| maxValue | <code>Number</code> | The maximum value for <code>object[property]</code> |\n\n<a name=\"NumberController+step\"></a>\n\n### numberController.step(stepValue) ⇒ <code>dat.controllers.NumberController</code>\nSpecify a step value that dat.controllers.NumberController\nincrements by.\n\n**Kind**: instance method of [<code>NumberController</code>](#NumberController)  \n**Default**: <code>if minimum and maximum specified increment is 1% of the\ndifference otherwise stepValue is 1</code>  \n**Returns**: <code>dat.controllers.NumberController</code> - this  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| stepValue | <code>Number</code> | The step value for dat.controllers.NumberController |\n\n<!--- API END --->\n"
  },
  {
    "path": "LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright 2014, Google Inc.\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   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "README.md",
    "content": "# dat.GUI\nA lightweight graphical user interface for changing variables in JavaScript.\n\nGet started with dat.GUI by reading the [API documentation](API.md).\n\n\n\n## Packaged Builds\nThe easiest way to use dat.GUI in your code is by using the built source at `build/dat.gui.min.js`. These built JavaScript files bundle all the necessary dependencies to run dat.GUI.\n\nIn your `head` tag, include the following code:\n```html\n<script type=\"text/javascript\" src=\"dat.gui.min.js\"></script>\n```\n\n## Installing from npm\n\n```bash\n$ npm install --save dat.gui\n```\n\n```js\n// CommonJS:\nconst dat = require('dat.gui');\n\n// ES6:\nimport * as dat from 'dat.gui';\n\nconst gui = new dat.GUI();\n```\n\n## Directory Contents\n\n```\n├── build - Compiled source code.\n├── src - Source files.\n└── tests - Tests.\n```\n\n## Building your own dat.GUI\n\nIn the terminal, enter the following:\n\n```\n$ npm install\n$ npm run build\n```\n\n## npm scripts\n\n- npm run build - Build development and production version of scripts.\n- npm run dev - Build development version of script and watch for changes.\n\n\n## Working with Content Security Policy\nIf you're using a server with a Content Security Policy in place that blocks 'unsafe-inline', you will have problems when dat.gui.js tries to inject style information. To get around this, load 'build/dat.gui.css' as an external style sheet.\n\n## Changes\nView the [Change Log](https://github.com/dataarts/dat.gui)\n\n## Thanks\nThe following libraries / open-source projects were used in the development of dat.GUI:\n * [Rollup](https://rollupjs.org)\n * [Sass](http://sass-lang.com/)\n * [Node.js](http://nodejs.org/)\n * [QUnit](https://github.com/jquery/qunit) / [jquery](http://jquery.com/)\n"
  },
  {
    "path": "bower.json",
    "content": "{\n  \"name\": \"dat.gui\",\n  \"homepage\": \"https://github.com/dataarts/dat.gui.git\",\n  \"authors\": [\n    \"Google Data Arts Team <dataarts@google.com>\"\n  ],\n  \"description\": \"dat.gui is a lightweight controller library for JavaScript.\",\n  \"main\": \"build/dat.gui.js\",\n  \"keywords\": [\n    \"controller\",\n    \"javascript\",\n    \"gui\",\n    \"slider\"\n  ],\n  \"license\": \"Apache License, Version 2.0\",\n  \"ignore\": [\n    \"**/.*\",\n    \"node_modules\",\n    \"bower_components\",\n    \"app/bower_components\",\n    \"test\",\n    \"tests\"\n  ]\n}\n"
  },
  {
    "path": "build/dat.gui.css",
    "content": ".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 .1s linear;-o-transition:opacity .1s linear;-moz-transition:opacity .1s linear;transition:opacity .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 .1s linear;-o-transition:opacity .1s linear;-moz-transition:opacity .1s linear;transition:opacity .1s linear;border:0;line-height:19px;height:20px;cursor:pointer;text-align:center;background-color:#000}.dg.main .close-button.close-top{position:relative}.dg.main .close-button.close-bottom{position:absolute}.dg.main .close-button:hover{background-color:#111}.dg.a{float:right;margin-right:15px;overflow-y:visible}.dg.a.has-save>ul.close-top{margin-top:0}.dg.a.has-save>ul.close-bottom{margin-top:27px}.dg.a.has-save>ul.closed{margin-top:0}.dg.a .save-row{top:0;z-index:1002}.dg.a .save-row.close-top{position:relative}.dg.a .save-row.close-bottom{position:fixed}.dg li{-webkit-transition:height .1s ease-out;-o-transition:height .1s ease-out;-moz-transition:height .1s ease-out;transition:height .1s ease-out;-webkit-transition:overflow .1s linear;-o-transition:overflow .1s linear;-moz-transition:overflow .1s linear;transition:overflow .1s linear}.dg li:not(.folder){cursor:auto;height:27px;line-height:27px;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;overflow:hidden}.dg .property-name{cursor:default;float:left;clear:left;width:40%;overflow:hidden;text-overflow:ellipsis}.dg .cr.function .property-name{width:100%}.dg .c{float:left;width:60%;position:relative}.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:7px}.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 .cr.color{overflow:visible}.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.color{border-left:3px solid}.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;max-width:100%}.dg .c .slider:hover{background:#3c3c3c}.dg .c .slider:hover .slider-fg{background:#44abda}\n"
  },
  {
    "path": "build/dat.gui.js",
    "content": "/**\n * dat-gui JavaScript Controller Library\n * https://github.com/dataarts/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(function (global, factory) {\n\ttypeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n\ttypeof define === 'function' && define.amd ? define(['exports'], factory) :\n\t(factory((global.dat = {})));\n}(this, (function (exports) { 'use strict';\n\nfunction ___$insertStyle(css) {\n  if (!css) {\n    return;\n  }\n  if (typeof window === 'undefined') {\n    return;\n  }\n\n  var style = document.createElement('style');\n\n  style.setAttribute('type', 'text/css');\n  style.innerHTML = css;\n  document.head.appendChild(style);\n\n  return css;\n}\n\nfunction colorToString (color, forceCSSHex) {\n  var colorFormat = color.__state.conversionName.toString();\n  var r = Math.round(color.r);\n  var g = Math.round(color.g);\n  var b = Math.round(color.b);\n  var a = color.a;\n  var h = Math.round(color.h);\n  var s = color.s.toFixed(1);\n  var v = color.v.toFixed(1);\n  if (forceCSSHex || colorFormat === 'THREE_CHAR_HEX' || colorFormat === 'SIX_CHAR_HEX') {\n    var str = color.hex.toString(16);\n    while (str.length < 6) {\n      str = '0' + str;\n    }\n    return '#' + str;\n  } else if (colorFormat === 'CSS_RGB') {\n    return 'rgb(' + r + ',' + g + ',' + b + ')';\n  } else if (colorFormat === 'CSS_RGBA') {\n    return 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';\n  } else if (colorFormat === 'HEX') {\n    return '0x' + color.hex.toString(16);\n  } else if (colorFormat === 'RGB_ARRAY') {\n    return '[' + r + ',' + g + ',' + b + ']';\n  } else if (colorFormat === 'RGBA_ARRAY') {\n    return '[' + r + ',' + g + ',' + b + ',' + a + ']';\n  } else if (colorFormat === 'RGB_OBJ') {\n    return '{r:' + r + ',g:' + g + ',b:' + b + '}';\n  } else if (colorFormat === 'RGBA_OBJ') {\n    return '{r:' + r + ',g:' + g + ',b:' + b + ',a:' + a + '}';\n  } else if (colorFormat === 'HSV_OBJ') {\n    return '{h:' + h + ',s:' + s + ',v:' + v + '}';\n  } else if (colorFormat === 'HSVA_OBJ') {\n    return '{h:' + h + ',s:' + s + ',v:' + v + ',a:' + a + '}';\n  }\n  return 'unknown format';\n}\n\nvar ARR_EACH = Array.prototype.forEach;\nvar ARR_SLICE = Array.prototype.slice;\nvar Common = {\n  BREAK: {},\n  extend: function extend(target) {\n    this.each(ARR_SLICE.call(arguments, 1), function (obj) {\n      var keys = this.isObject(obj) ? Object.keys(obj) : [];\n      keys.forEach(function (key) {\n        if (!this.isUndefined(obj[key])) {\n          target[key] = obj[key];\n        }\n      }.bind(this));\n    }, this);\n    return target;\n  },\n  defaults: function defaults(target) {\n    this.each(ARR_SLICE.call(arguments, 1), function (obj) {\n      var keys = this.isObject(obj) ? Object.keys(obj) : [];\n      keys.forEach(function (key) {\n        if (this.isUndefined(target[key])) {\n          target[key] = obj[key];\n        }\n      }.bind(this));\n    }, this);\n    return target;\n  },\n  compose: function compose() {\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  each: function each(obj, itr, scope) {\n    if (!obj) {\n      return;\n    }\n    if (ARR_EACH && obj.forEach && obj.forEach === ARR_EACH) {\n      obj.forEach(itr, scope);\n    } else if (obj.length === obj.length + 0) {\n      var key = void 0;\n      var l = void 0;\n      for (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      }\n    } else {\n      for (var _key in obj) {\n        if (itr.call(scope, obj[_key], _key) === this.BREAK) {\n          return;\n        }\n      }\n    }\n  },\n  defer: function defer(fnc) {\n    setTimeout(fnc, 0);\n  },\n  debounce: function debounce(func, threshold, callImmediately) {\n    var timeout = void 0;\n    return function () {\n      var obj = this;\n      var args = arguments;\n      function delayed() {\n        timeout = null;\n        if (!callImmediately) func.apply(obj, args);\n      }\n      var callNow = callImmediately || !timeout;\n      clearTimeout(timeout);\n      timeout = setTimeout(delayed, threshold);\n      if (callNow) {\n        func.apply(obj, args);\n      }\n    };\n  },\n  toArray: function toArray(obj) {\n    if (obj.toArray) return obj.toArray();\n    return ARR_SLICE.call(obj);\n  },\n  isUndefined: function isUndefined(obj) {\n    return obj === undefined;\n  },\n  isNull: function isNull(obj) {\n    return obj === null;\n  },\n  isNaN: function (_isNaN) {\n    function isNaN(_x) {\n      return _isNaN.apply(this, arguments);\n    }\n    isNaN.toString = function () {\n      return _isNaN.toString();\n    };\n    return isNaN;\n  }(function (obj) {\n    return isNaN(obj);\n  }),\n  isArray: Array.isArray || function (obj) {\n    return obj.constructor === Array;\n  },\n  isObject: function isObject(obj) {\n    return obj === Object(obj);\n  },\n  isNumber: function isNumber(obj) {\n    return obj === obj + 0;\n  },\n  isString: function isString(obj) {\n    return obj === obj + '';\n  },\n  isBoolean: function isBoolean(obj) {\n    return obj === false || obj === true;\n  },\n  isFunction: function isFunction(obj) {\n    return obj instanceof Function;\n  }\n};\n\nvar INTERPRETATIONS = [\n{\n  litmus: Common.isString,\n  conversions: {\n    THREE_CHAR_HEX: {\n      read: function read(original) {\n        var test = original.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);\n        if (test === null) {\n          return false;\n        }\n        return {\n          space: 'HEX',\n          hex: parseInt('0x' + test[1].toString() + test[1].toString() + test[2].toString() + test[2].toString() + test[3].toString() + test[3].toString(), 0)\n        };\n      },\n      write: colorToString\n    },\n    SIX_CHAR_HEX: {\n      read: function read(original) {\n        var test = original.match(/^#([A-F0-9]{6})$/i);\n        if (test === null) {\n          return false;\n        }\n        return {\n          space: 'HEX',\n          hex: parseInt('0x' + test[1].toString(), 0)\n        };\n      },\n      write: colorToString\n    },\n    CSS_RGB: {\n      read: function read(original) {\n        var test = original.match(/^rgb\\(\\s*(\\S+)\\s*,\\s*(\\S+)\\s*,\\s*(\\S+)\\s*\\)/);\n        if (test === null) {\n          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      write: colorToString\n    },\n    CSS_RGBA: {\n      read: function read(original) {\n        var test = original.match(/^rgba\\(\\s*(\\S+)\\s*,\\s*(\\S+)\\s*,\\s*(\\S+)\\s*,\\s*(\\S+)\\s*\\)/);\n        if (test === null) {\n          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      write: colorToString\n    }\n  }\n},\n{\n  litmus: Common.isNumber,\n  conversions: {\n    HEX: {\n      read: function read(original) {\n        return {\n          space: 'HEX',\n          hex: original,\n          conversionName: 'HEX'\n        };\n      },\n      write: function write(color) {\n        return color.hex;\n      }\n    }\n  }\n},\n{\n  litmus: Common.isArray,\n  conversions: {\n    RGB_ARRAY: {\n      read: function read(original) {\n        if (original.length !== 3) {\n          return false;\n        }\n        return {\n          space: 'RGB',\n          r: original[0],\n          g: original[1],\n          b: original[2]\n        };\n      },\n      write: function write(color) {\n        return [color.r, color.g, color.b];\n      }\n    },\n    RGBA_ARRAY: {\n      read: function read(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      write: function write(color) {\n        return [color.r, color.g, color.b, color.a];\n      }\n    }\n  }\n},\n{\n  litmus: Common.isObject,\n  conversions: {\n    RGBA_OBJ: {\n      read: function read(original) {\n        if (Common.isNumber(original.r) && Common.isNumber(original.g) && Common.isNumber(original.b) && 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      write: function write(color) {\n        return {\n          r: color.r,\n          g: color.g,\n          b: color.b,\n          a: color.a\n        };\n      }\n    },\n    RGB_OBJ: {\n      read: function read(original) {\n        if (Common.isNumber(original.r) && Common.isNumber(original.g) && 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      write: function write(color) {\n        return {\n          r: color.r,\n          g: color.g,\n          b: color.b\n        };\n      }\n    },\n    HSVA_OBJ: {\n      read: function read(original) {\n        if (Common.isNumber(original.h) && Common.isNumber(original.s) && Common.isNumber(original.v) && 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      write: function write(color) {\n        return {\n          h: color.h,\n          s: color.s,\n          v: color.v,\n          a: color.a\n        };\n      }\n    },\n    HSV_OBJ: {\n      read: function read(original) {\n        if (Common.isNumber(original.h) && Common.isNumber(original.s) && 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      write: function write(color) {\n        return {\n          h: color.h,\n          s: color.s,\n          v: color.v\n        };\n      }\n    }\n  }\n}];\nvar result = void 0;\nvar toReturn = void 0;\nvar interpret = function interpret() {\n  toReturn = false;\n  var original = arguments.length > 1 ? Common.toArray(arguments) : arguments[0];\n  Common.each(INTERPRETATIONS, function (family) {\n    if (family.litmus(original)) {\n      Common.each(family.conversions, function (conversion, conversionName) {\n        result = conversion.read(original);\n        if (toReturn === false && result !== false) {\n          toReturn = result;\n          result.conversionName = conversionName;\n          result.conversion = conversion;\n          return Common.BREAK;\n        }\n      });\n      return Common.BREAK;\n    }\n  });\n  return toReturn;\n};\n\nvar tmpComponent = void 0;\nvar ColorMath = {\n  hsv_to_rgb: function hsv_to_rgb(h, s, v) {\n    var hi = Math.floor(h / 60) % 6;\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 = [[v, t, p], [q, v, p], [p, v, t], [p, q, v], [t, p, v], [v, p, q]][hi];\n    return {\n      r: c[0] * 255,\n      g: c[1] * 255,\n      b: c[2] * 255\n    };\n  },\n  rgb_to_hsv: function rgb_to_hsv(r, g, b) {\n    var min = Math.min(r, g, b);\n    var max = Math.max(r, g, b);\n    var delta = max - min;\n    var h = void 0;\n    var s = void 0;\n    if (max !== 0) {\n      s = delta / max;\n    } else {\n      return {\n        h: NaN,\n        s: 0,\n        v: 0\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    return {\n      h: h * 360,\n      s: s,\n      v: max / 255\n    };\n  },\n  rgb_to_hex: function rgb_to_hex(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  component_from_hex: function component_from_hex(hex, componentIndex) {\n    return hex >> componentIndex * 8 & 0xFF;\n  },\n  hex_with_component: function hex_with_component(hex, componentIndex, value) {\n    return value << (tmpComponent = componentIndex * 8) | hex & ~(0xFF << tmpComponent);\n  }\n};\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) {\n  return typeof obj;\n} : function (obj) {\n  return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj;\n};\n\n\n\n\n\n\n\n\n\n\n\nvar classCallCheck = function (instance, Constructor) {\n  if (!(instance instanceof Constructor)) {\n    throw new TypeError(\"Cannot call a class as a function\");\n  }\n};\n\nvar createClass = function () {\n  function defineProperties(target, props) {\n    for (var i = 0; i < props.length; i++) {\n      var descriptor = props[i];\n      descriptor.enumerable = descriptor.enumerable || false;\n      descriptor.configurable = true;\n      if (\"value\" in descriptor) descriptor.writable = true;\n      Object.defineProperty(target, descriptor.key, descriptor);\n    }\n  }\n\n  return function (Constructor, protoProps, staticProps) {\n    if (protoProps) defineProperties(Constructor.prototype, protoProps);\n    if (staticProps) defineProperties(Constructor, staticProps);\n    return Constructor;\n  };\n}();\n\n\n\n\n\n\n\nvar get = function get(object, property, receiver) {\n  if (object === null) object = Function.prototype;\n  var desc = Object.getOwnPropertyDescriptor(object, property);\n\n  if (desc === undefined) {\n    var parent = Object.getPrototypeOf(object);\n\n    if (parent === null) {\n      return undefined;\n    } else {\n      return get(parent, property, receiver);\n    }\n  } else if (\"value\" in desc) {\n    return desc.value;\n  } else {\n    var getter = desc.get;\n\n    if (getter === undefined) {\n      return undefined;\n    }\n\n    return getter.call(receiver);\n  }\n};\n\nvar inherits = function (subClass, superClass) {\n  if (typeof superClass !== \"function\" && superClass !== null) {\n    throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass);\n  }\n\n  subClass.prototype = Object.create(superClass && superClass.prototype, {\n    constructor: {\n      value: subClass,\n      enumerable: false,\n      writable: true,\n      configurable: true\n    }\n  });\n  if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;\n};\n\n\n\n\n\n\n\n\n\n\n\nvar possibleConstructorReturn = function (self, call) {\n  if (!self) {\n    throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");\n  }\n\n  return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self;\n};\n\nvar Color = function () {\n  function Color() {\n    classCallCheck(this, Color);\n    this.__state = interpret.apply(this, arguments);\n    if (this.__state === false) {\n      throw new Error('Failed to interpret color arguments');\n    }\n    this.__state.a = this.__state.a || 1;\n  }\n  createClass(Color, [{\n    key: 'toString',\n    value: function toString() {\n      return colorToString(this);\n    }\n  }, {\n    key: 'toHexString',\n    value: function toHexString() {\n      return colorToString(this, true);\n    }\n  }, {\n    key: 'toOriginal',\n    value: function toOriginal() {\n      return this.__state.conversion.write(this);\n    }\n  }]);\n  return Color;\n}();\nfunction defineRGBComponent(target, component, componentHexIndex) {\n  Object.defineProperty(target, component, {\n    get: function get$$1() {\n      if (this.__state.space === 'RGB') {\n        return this.__state[component];\n      }\n      Color.recalculateRGB(this, component, componentHexIndex);\n      return this.__state[component];\n    },\n    set: function set$$1(v) {\n      if (this.__state.space !== 'RGB') {\n        Color.recalculateRGB(this, component, componentHexIndex);\n        this.__state.space = 'RGB';\n      }\n      this.__state[component] = v;\n    }\n  });\n}\nfunction defineHSVComponent(target, component) {\n  Object.defineProperty(target, component, {\n    get: function get$$1() {\n      if (this.__state.space === 'HSV') {\n        return this.__state[component];\n      }\n      Color.recalculateHSV(this);\n      return this.__state[component];\n    },\n    set: function set$$1(v) {\n      if (this.__state.space !== 'HSV') {\n        Color.recalculateHSV(this);\n        this.__state.space = 'HSV';\n      }\n      this.__state[component] = v;\n    }\n  });\n}\nColor.recalculateRGB = function (color, component, componentHexIndex) {\n  if (color.__state.space === 'HEX') {\n    color.__state[component] = ColorMath.component_from_hex(color.__state.hex, componentHexIndex);\n  } else if (color.__state.space === 'HSV') {\n    Common.extend(color.__state, ColorMath.hsv_to_rgb(color.__state.h, color.__state.s, color.__state.v));\n  } else {\n    throw new Error('Corrupted color state');\n  }\n};\nColor.recalculateHSV = function (color) {\n  var result = ColorMath.rgb_to_hsv(color.r, color.g, color.b);\n  Common.extend(color.__state, {\n    s: result.s,\n    v: result.v\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};\nColor.COMPONENTS = ['r', 'g', 'b', 'h', 's', 'v', 'hex', 'a'];\ndefineRGBComponent(Color.prototype, 'r', 2);\ndefineRGBComponent(Color.prototype, 'g', 1);\ndefineRGBComponent(Color.prototype, 'b', 0);\ndefineHSVComponent(Color.prototype, 'h');\ndefineHSVComponent(Color.prototype, 's');\ndefineHSVComponent(Color.prototype, 'v');\nObject.defineProperty(Color.prototype, 'a', {\n  get: function get$$1() {\n    return this.__state.a;\n  },\n  set: function set$$1(v) {\n    this.__state.a = v;\n  }\n});\nObject.defineProperty(Color.prototype, 'hex', {\n  get: function get$$1() {\n    if (this.__state.space !== 'HEX') {\n      this.__state.hex = ColorMath.rgb_to_hex(this.r, this.g, this.b);\n      this.__state.space = 'HEX';\n    }\n    return this.__state.hex;\n  },\n  set: function set$$1(v) {\n    this.__state.space = 'HEX';\n    this.__state.hex = v;\n  }\n});\n\nvar Controller = function () {\n  function Controller(object, property) {\n    classCallCheck(this, Controller);\n    this.initialValue = object[property];\n    this.domElement = document.createElement('div');\n    this.object = object;\n    this.property = property;\n    this.__onChange = undefined;\n    this.__onFinishChange = undefined;\n  }\n  createClass(Controller, [{\n    key: 'onChange',\n    value: function onChange(fnc) {\n      this.__onChange = fnc;\n      return this;\n    }\n  }, {\n    key: 'onFinishChange',\n    value: function onFinishChange(fnc) {\n      this.__onFinishChange = fnc;\n      return this;\n    }\n  }, {\n    key: 'setValue',\n    value: function setValue(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    key: 'getValue',\n    value: function getValue() {\n      return this.object[this.property];\n    }\n  }, {\n    key: 'updateDisplay',\n    value: function updateDisplay() {\n      return this;\n    }\n  }, {\n    key: 'isModified',\n    value: function isModified() {\n      return this.initialValue !== this.getValue();\n    }\n  }]);\n  return Controller;\n}();\n\nvar EVENT_MAP = {\n  HTMLEvents: ['change'],\n  MouseEvents: ['click', 'mousemove', 'mousedown', 'mouseup', 'mouseover'],\n  KeyboardEvents: ['keydown']\n};\nvar EVENT_MAP_INV = {};\nCommon.each(EVENT_MAP, function (v, k) {\n  Common.each(v, function (e) {\n    EVENT_MAP_INV[e] = k;\n  });\n});\nvar CSS_VALUE_PIXELS = /(\\d+(\\.\\d+)?)px/;\nfunction cssValueToPixels(val) {\n  if (val === '0' || Common.isUndefined(val)) {\n    return 0;\n  }\n  var match = val.match(CSS_VALUE_PIXELS);\n  if (!Common.isNull(match)) {\n    return parseFloat(match[1]);\n  }\n  return 0;\n}\nvar dom = {\n  makeSelectable: function makeSelectable(elem, selectable) {\n    if (elem === undefined || elem.style === undefined) return;\n    elem.onselectstart = selectable ? function () {\n      return false;\n    } : function () {};\n    elem.style.MozUserSelect = selectable ? 'auto' : 'none';\n    elem.style.KhtmlUserSelect = selectable ? 'auto' : 'none';\n    elem.unselectable = selectable ? 'on' : 'off';\n  },\n  makeFullscreen: function makeFullscreen(elem, hor, vert) {\n    var vertical = vert;\n    var horizontal = hor;\n    if (Common.isUndefined(horizontal)) {\n      horizontal = true;\n    }\n    if (Common.isUndefined(vertical)) {\n      vertical = true;\n    }\n    elem.style.position = 'absolute';\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  fakeEvent: function fakeEvent(elem, eventType, pars, aux) {\n    var params = pars || {};\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        {\n          var clientX = params.x || params.clientX || 0;\n          var clientY = params.y || params.clientY || 0;\n          evt.initMouseEvent(eventType, params.bubbles || false, params.cancelable || true, window, params.clickCount || 1, 0,\n          0,\n          clientX,\n          clientY,\n          false, false, false, false, 0, null);\n          break;\n        }\n      case 'KeyboardEvents':\n        {\n          var init = evt.initKeyboardEvent || evt.initKeyEvent;\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, params.cancelable, window, params.ctrlKey, params.altKey, params.shiftKey, params.metaKey, params.keyCode, params.charCode);\n          break;\n        }\n      default:\n        {\n          evt.initEvent(eventType, params.bubbles || false, params.cancelable || true);\n          break;\n        }\n    }\n    Common.defaults(evt, aux);\n    elem.dispatchEvent(evt);\n  },\n  bind: function bind(elem, event, func, newBool) {\n    var bool = newBool || false;\n    if (elem.addEventListener) {\n      elem.addEventListener(event, func, bool);\n    } else if (elem.attachEvent) {\n      elem.attachEvent('on' + event, func);\n    }\n    return dom;\n  },\n  unbind: function unbind(elem, event, func, newBool) {\n    var bool = newBool || false;\n    if (elem.removeEventListener) {\n      elem.removeEventListener(event, func, bool);\n    } else if (elem.detachEvent) {\n      elem.detachEvent('on' + event, func);\n    }\n    return dom;\n  },\n  addClass: function addClass(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  removeClass: function removeClass(elem, className) {\n    if (className) {\n      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  hasClass: function hasClass(elem, className) {\n    return new RegExp('(?:^|\\\\s+)' + className + '(?:\\\\s+|$)').test(elem.className) || false;\n  },\n  getWidth: function getWidth(elem) {\n    var style = getComputedStyle(elem);\n    return cssValueToPixels(style['border-left-width']) + cssValueToPixels(style['border-right-width']) + cssValueToPixels(style['padding-left']) + cssValueToPixels(style['padding-right']) + cssValueToPixels(style.width);\n  },\n  getHeight: function getHeight(elem) {\n    var style = getComputedStyle(elem);\n    return cssValueToPixels(style['border-top-width']) + cssValueToPixels(style['border-bottom-width']) + cssValueToPixels(style['padding-top']) + cssValueToPixels(style['padding-bottom']) + cssValueToPixels(style.height);\n  },\n  getOffset: function getOffset(el) {\n    var elem = el;\n    var offset = { left: 0, top: 0 };\n    if (elem.offsetParent) {\n      do {\n        offset.left += elem.offsetLeft;\n        offset.top += elem.offsetTop;\n        elem = elem.offsetParent;\n      } while (elem);\n    }\n    return offset;\n  },\n  isActive: function isActive(elem) {\n    return elem === document.activeElement && (elem.type || elem.href);\n  }\n};\n\nvar BooleanController = function (_Controller) {\n  inherits(BooleanController, _Controller);\n  function BooleanController(object, property) {\n    classCallCheck(this, BooleanController);\n    var _this2 = possibleConstructorReturn(this, (BooleanController.__proto__ || Object.getPrototypeOf(BooleanController)).call(this, object, property));\n    var _this = _this2;\n    _this2.__prev = _this2.getValue();\n    _this2.__checkbox = document.createElement('input');\n    _this2.__checkbox.setAttribute('type', 'checkbox');\n    function onChange() {\n      _this.setValue(!_this.__prev);\n    }\n    dom.bind(_this2.__checkbox, 'change', onChange, false);\n    _this2.domElement.appendChild(_this2.__checkbox);\n    _this2.updateDisplay();\n    return _this2;\n  }\n  createClass(BooleanController, [{\n    key: 'setValue',\n    value: function setValue(v) {\n      var toReturn = get(BooleanController.prototype.__proto__ || Object.getPrototypeOf(BooleanController.prototype), 'setValue', this).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    key: 'updateDisplay',\n    value: function updateDisplay() {\n      if (this.getValue() === true) {\n        this.__checkbox.setAttribute('checked', 'checked');\n        this.__checkbox.checked = true;\n        this.__prev = true;\n      } else {\n        this.__checkbox.checked = false;\n        this.__prev = false;\n      }\n      return get(BooleanController.prototype.__proto__ || Object.getPrototypeOf(BooleanController.prototype), 'updateDisplay', this).call(this);\n    }\n  }]);\n  return BooleanController;\n}(Controller);\n\nvar OptionController = function (_Controller) {\n  inherits(OptionController, _Controller);\n  function OptionController(object, property, opts) {\n    classCallCheck(this, OptionController);\n    var _this2 = possibleConstructorReturn(this, (OptionController.__proto__ || Object.getPrototypeOf(OptionController)).call(this, object, property));\n    var options = opts;\n    var _this = _this2;\n    _this2.__select = document.createElement('select');\n    if (Common.isArray(options)) {\n      var map = {};\n      Common.each(options, function (element) {\n        map[element] = element;\n      });\n      options = map;\n    }\n    Common.each(options, function (value, key) {\n      var opt = document.createElement('option');\n      opt.innerHTML = key;\n      opt.setAttribute('value', value);\n      _this.__select.appendChild(opt);\n    });\n    _this2.updateDisplay();\n    dom.bind(_this2.__select, 'change', function () {\n      var desiredValue = this.options[this.selectedIndex].value;\n      _this.setValue(desiredValue);\n    });\n    _this2.domElement.appendChild(_this2.__select);\n    return _this2;\n  }\n  createClass(OptionController, [{\n    key: 'setValue',\n    value: function setValue(v) {\n      var toReturn = get(OptionController.prototype.__proto__ || Object.getPrototypeOf(OptionController.prototype), 'setValue', this).call(this, v);\n      if (this.__onFinishChange) {\n        this.__onFinishChange.call(this, this.getValue());\n      }\n      return toReturn;\n    }\n  }, {\n    key: 'updateDisplay',\n    value: function updateDisplay() {\n      if (dom.isActive(this.__select)) return this;\n      this.__select.value = this.getValue();\n      return get(OptionController.prototype.__proto__ || Object.getPrototypeOf(OptionController.prototype), 'updateDisplay', this).call(this);\n    }\n  }]);\n  return OptionController;\n}(Controller);\n\nvar StringController = function (_Controller) {\n  inherits(StringController, _Controller);\n  function StringController(object, property) {\n    classCallCheck(this, StringController);\n    var _this2 = possibleConstructorReturn(this, (StringController.__proto__ || Object.getPrototypeOf(StringController)).call(this, object, property));\n    var _this = _this2;\n    function onChange() {\n      _this.setValue(_this.__input.value);\n    }\n    function onBlur() {\n      if (_this.__onFinishChange) {\n        _this.__onFinishChange.call(_this, _this.getValue());\n      }\n    }\n    _this2.__input = document.createElement('input');\n    _this2.__input.setAttribute('type', 'text');\n    dom.bind(_this2.__input, 'keyup', onChange);\n    dom.bind(_this2.__input, 'change', onChange);\n    dom.bind(_this2.__input, 'blur', onBlur);\n    dom.bind(_this2.__input, 'keydown', function (e) {\n      if (e.keyCode === 13) {\n        this.blur();\n      }\n    });\n    _this2.updateDisplay();\n    _this2.domElement.appendChild(_this2.__input);\n    return _this2;\n  }\n  createClass(StringController, [{\n    key: 'updateDisplay',\n    value: function updateDisplay() {\n      if (!dom.isActive(this.__input)) {\n        this.__input.value = this.getValue();\n      }\n      return get(StringController.prototype.__proto__ || Object.getPrototypeOf(StringController.prototype), 'updateDisplay', this).call(this);\n    }\n  }]);\n  return StringController;\n}(Controller);\n\nfunction numDecimals(x) {\n  var _x = x.toString();\n  if (_x.indexOf('.') > -1) {\n    return _x.length - _x.indexOf('.') - 1;\n  }\n  return 0;\n}\nvar NumberController = function (_Controller) {\n  inherits(NumberController, _Controller);\n  function NumberController(object, property, params) {\n    classCallCheck(this, NumberController);\n    var _this = possibleConstructorReturn(this, (NumberController.__proto__ || Object.getPrototypeOf(NumberController)).call(this, object, property));\n    var _params = params || {};\n    _this.__min = _params.min;\n    _this.__max = _params.max;\n    _this.__step = _params.step;\n    if (Common.isUndefined(_this.__step)) {\n      if (_this.initialValue === 0) {\n        _this.__impliedStep = 1;\n      } else {\n        _this.__impliedStep = Math.pow(10, Math.floor(Math.log(Math.abs(_this.initialValue)) / Math.LN10)) / 10;\n      }\n    } else {\n      _this.__impliedStep = _this.__step;\n    }\n    _this.__precision = numDecimals(_this.__impliedStep);\n    return _this;\n  }\n  createClass(NumberController, [{\n    key: 'setValue',\n    value: function setValue(v) {\n      var _v = v;\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      if (this.__step !== undefined && _v % this.__step !== 0) {\n        _v = Math.round(_v / this.__step) * this.__step;\n      }\n      return get(NumberController.prototype.__proto__ || Object.getPrototypeOf(NumberController.prototype), 'setValue', this).call(this, _v);\n    }\n  }, {\n    key: 'min',\n    value: function min(minValue) {\n      this.__min = minValue;\n      return this;\n    }\n  }, {\n    key: 'max',\n    value: function max(maxValue) {\n      this.__max = maxValue;\n      return this;\n    }\n  }, {\n    key: 'step',\n    value: function step(stepValue) {\n      this.__step = stepValue;\n      this.__impliedStep = stepValue;\n      this.__precision = numDecimals(stepValue);\n      return this;\n    }\n  }]);\n  return NumberController;\n}(Controller);\n\nfunction roundToDecimal(value, decimals) {\n  var tenTo = Math.pow(10, decimals);\n  return Math.round(value * tenTo) / tenTo;\n}\nvar NumberControllerBox = function (_NumberController) {\n  inherits(NumberControllerBox, _NumberController);\n  function NumberControllerBox(object, property, params) {\n    classCallCheck(this, NumberControllerBox);\n    var _this2 = possibleConstructorReturn(this, (NumberControllerBox.__proto__ || Object.getPrototypeOf(NumberControllerBox)).call(this, object, property, params));\n    _this2.__truncationSuspended = false;\n    var _this = _this2;\n    var prevY = void 0;\n    function onChange() {\n      var attempted = parseFloat(_this.__input.value);\n      if (!Common.isNaN(attempted)) {\n        _this.setValue(attempted);\n      }\n    }\n    function onFinish() {\n      if (_this.__onFinishChange) {\n        _this.__onFinishChange.call(_this, _this.getValue());\n      }\n    }\n    function onBlur() {\n      onFinish();\n    }\n    function onMouseDrag(e) {\n      var diff = prevY - e.clientY;\n      _this.setValue(_this.getValue() + diff * _this.__impliedStep);\n      prevY = e.clientY;\n    }\n    function onMouseUp() {\n      dom.unbind(window, 'mousemove', onMouseDrag);\n      dom.unbind(window, 'mouseup', onMouseUp);\n      onFinish();\n    }\n    function onMouseDown(e) {\n      dom.bind(window, 'mousemove', onMouseDrag);\n      dom.bind(window, 'mouseup', onMouseUp);\n      prevY = e.clientY;\n    }\n    _this2.__input = document.createElement('input');\n    _this2.__input.setAttribute('type', 'text');\n    dom.bind(_this2.__input, 'change', onChange);\n    dom.bind(_this2.__input, 'blur', onBlur);\n    dom.bind(_this2.__input, 'mousedown', onMouseDown);\n    dom.bind(_this2.__input, 'keydown', function (e) {\n      if (e.keyCode === 13) {\n        _this.__truncationSuspended = true;\n        this.blur();\n        _this.__truncationSuspended = false;\n        onFinish();\n      }\n    });\n    _this2.updateDisplay();\n    _this2.domElement.appendChild(_this2.__input);\n    return _this2;\n  }\n  createClass(NumberControllerBox, [{\n    key: 'updateDisplay',\n    value: function updateDisplay() {\n      this.__input.value = this.__truncationSuspended ? this.getValue() : roundToDecimal(this.getValue(), this.__precision);\n      return get(NumberControllerBox.prototype.__proto__ || Object.getPrototypeOf(NumberControllerBox.prototype), 'updateDisplay', this).call(this);\n    }\n  }]);\n  return NumberControllerBox;\n}(NumberController);\n\nfunction map(v, i1, i2, o1, o2) {\n  return o1 + (o2 - o1) * ((v - i1) / (i2 - i1));\n}\nvar NumberControllerSlider = function (_NumberController) {\n  inherits(NumberControllerSlider, _NumberController);\n  function NumberControllerSlider(object, property, min, max, step) {\n    classCallCheck(this, NumberControllerSlider);\n    var _this2 = possibleConstructorReturn(this, (NumberControllerSlider.__proto__ || Object.getPrototypeOf(NumberControllerSlider)).call(this, object, property, { min: min, max: max, step: step }));\n    var _this = _this2;\n    _this2.__background = document.createElement('div');\n    _this2.__foreground = document.createElement('div');\n    dom.bind(_this2.__background, 'mousedown', onMouseDown);\n    dom.bind(_this2.__background, 'touchstart', onTouchStart);\n    dom.addClass(_this2.__background, 'slider');\n    dom.addClass(_this2.__foreground, 'slider-fg');\n    function onMouseDown(e) {\n      document.activeElement.blur();\n      dom.bind(window, 'mousemove', onMouseDrag);\n      dom.bind(window, 'mouseup', onMouseUp);\n      onMouseDrag(e);\n    }\n    function onMouseDrag(e) {\n      e.preventDefault();\n      var bgRect = _this.__background.getBoundingClientRect();\n      _this.setValue(map(e.clientX, bgRect.left, bgRect.right, _this.__min, _this.__max));\n      return false;\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    function onTouchStart(e) {\n      if (e.touches.length !== 1) {\n        return;\n      }\n      dom.bind(window, 'touchmove', onTouchMove);\n      dom.bind(window, 'touchend', onTouchEnd);\n      onTouchMove(e);\n    }\n    function onTouchMove(e) {\n      var clientX = e.touches[0].clientX;\n      var bgRect = _this.__background.getBoundingClientRect();\n      _this.setValue(map(clientX, bgRect.left, bgRect.right, _this.__min, _this.__max));\n    }\n    function onTouchEnd() {\n      dom.unbind(window, 'touchmove', onTouchMove);\n      dom.unbind(window, 'touchend', onTouchEnd);\n      if (_this.__onFinishChange) {\n        _this.__onFinishChange.call(_this, _this.getValue());\n      }\n    }\n    _this2.updateDisplay();\n    _this2.__background.appendChild(_this2.__foreground);\n    _this2.domElement.appendChild(_this2.__background);\n    return _this2;\n  }\n  createClass(NumberControllerSlider, [{\n    key: 'updateDisplay',\n    value: function updateDisplay() {\n      var pct = (this.getValue() - this.__min) / (this.__max - this.__min);\n      this.__foreground.style.width = pct * 100 + '%';\n      return get(NumberControllerSlider.prototype.__proto__ || Object.getPrototypeOf(NumberControllerSlider.prototype), 'updateDisplay', this).call(this);\n    }\n  }]);\n  return NumberControllerSlider;\n}(NumberController);\n\nvar FunctionController = function (_Controller) {\n  inherits(FunctionController, _Controller);\n  function FunctionController(object, property, text) {\n    classCallCheck(this, FunctionController);\n    var _this2 = possibleConstructorReturn(this, (FunctionController.__proto__ || Object.getPrototypeOf(FunctionController)).call(this, object, property));\n    var _this = _this2;\n    _this2.__button = document.createElement('div');\n    _this2.__button.innerHTML = text === undefined ? 'Fire' : text;\n    dom.bind(_this2.__button, 'click', function (e) {\n      e.preventDefault();\n      _this.fire();\n      return false;\n    });\n    dom.addClass(_this2.__button, 'button');\n    _this2.domElement.appendChild(_this2.__button);\n    return _this2;\n  }\n  createClass(FunctionController, [{\n    key: 'fire',\n    value: function fire() {\n      if (this.__onChange) {\n        this.__onChange.call(this);\n      }\n      this.getValue().call(this.object);\n      if (this.__onFinishChange) {\n        this.__onFinishChange.call(this, this.getValue());\n      }\n    }\n  }]);\n  return FunctionController;\n}(Controller);\n\nvar ColorController = function (_Controller) {\n  inherits(ColorController, _Controller);\n  function ColorController(object, property) {\n    classCallCheck(this, ColorController);\n    var _this2 = possibleConstructorReturn(this, (ColorController.__proto__ || Object.getPrototypeOf(ColorController)).call(this, object, property));\n    _this2.__color = new Color(_this2.getValue());\n    _this2.__temp = new Color(0);\n    var _this = _this2;\n    _this2.domElement = document.createElement('div');\n    dom.makeSelectable(_this2.domElement, false);\n    _this2.__selector = document.createElement('div');\n    _this2.__selector.className = 'selector';\n    _this2.__saturation_field = document.createElement('div');\n    _this2.__saturation_field.className = 'saturation-field';\n    _this2.__field_knob = document.createElement('div');\n    _this2.__field_knob.className = 'field-knob';\n    _this2.__field_knob_border = '2px solid ';\n    _this2.__hue_knob = document.createElement('div');\n    _this2.__hue_knob.className = 'hue-knob';\n    _this2.__hue_field = document.createElement('div');\n    _this2.__hue_field.className = 'hue-field';\n    _this2.__input = document.createElement('input');\n    _this2.__input.type = 'text';\n    _this2.__input_textShadow = '0 1px 1px ';\n    dom.bind(_this2.__input, 'keydown', function (e) {\n      if (e.keyCode === 13) {\n        onBlur.call(this);\n      }\n    });\n    dom.bind(_this2.__input, 'blur', onBlur);\n    dom.bind(_this2.__selector, 'mousedown', function () {\n      dom.addClass(this, 'drag').bind(window, 'mouseup', function () {\n        dom.removeClass(_this.__selector, 'drag');\n      });\n    });\n    dom.bind(_this2.__selector, 'touchstart', function () {\n      dom.addClass(this, 'drag').bind(window, 'touchend', function () {\n        dom.removeClass(_this.__selector, 'drag');\n      });\n    });\n    var valueField = document.createElement('div');\n    Common.extend(_this2.__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    Common.extend(_this2.__field_knob.style, {\n      position: 'absolute',\n      width: '12px',\n      height: '12px',\n      border: _this2.__field_knob_border + (_this2.__color.v < 0.5 ? '#fff' : '#000'),\n      boxShadow: '0px 1px 3px rgba(0,0,0,0.5)',\n      borderRadius: '12px',\n      zIndex: 1\n    });\n    Common.extend(_this2.__hue_knob.style, {\n      position: 'absolute',\n      width: '15px',\n      height: '2px',\n      borderRight: '4px solid #fff',\n      zIndex: 1\n    });\n    Common.extend(_this2.__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    Common.extend(valueField.style, {\n      width: '100%',\n      height: '100%',\n      background: 'none'\n    });\n    linearGradient(valueField, 'top', 'rgba(0,0,0,0)', '#000');\n    Common.extend(_this2.__hue_field.style, {\n      width: '15px',\n      height: '100px',\n      border: '1px solid #555',\n      cursor: 'ns-resize',\n      position: 'absolute',\n      top: '3px',\n      right: '3px'\n    });\n    hueGradient(_this2.__hue_field);\n    Common.extend(_this2.__input.style, {\n      outline: 'none',\n      textAlign: 'center',\n      color: '#fff',\n      border: 0,\n      fontWeight: 'bold',\n      textShadow: _this2.__input_textShadow + 'rgba(0,0,0,0.7)'\n    });\n    dom.bind(_this2.__saturation_field, 'mousedown', fieldDown);\n    dom.bind(_this2.__saturation_field, 'touchstart', fieldDown);\n    dom.bind(_this2.__field_knob, 'mousedown', fieldDown);\n    dom.bind(_this2.__field_knob, 'touchstart', fieldDown);\n    dom.bind(_this2.__hue_field, 'mousedown', fieldDownH);\n    dom.bind(_this2.__hue_field, 'touchstart', fieldDownH);\n    function fieldDown(e) {\n      setSV(e);\n      dom.bind(window, 'mousemove', setSV);\n      dom.bind(window, 'touchmove', setSV);\n      dom.bind(window, 'mouseup', fieldUpSV);\n      dom.bind(window, 'touchend', fieldUpSV);\n    }\n    function fieldDownH(e) {\n      setH(e);\n      dom.bind(window, 'mousemove', setH);\n      dom.bind(window, 'touchmove', setH);\n      dom.bind(window, 'mouseup', fieldUpH);\n      dom.bind(window, 'touchend', fieldUpH);\n    }\n    function fieldUpSV() {\n      dom.unbind(window, 'mousemove', setSV);\n      dom.unbind(window, 'touchmove', setSV);\n      dom.unbind(window, 'mouseup', fieldUpSV);\n      dom.unbind(window, 'touchend', fieldUpSV);\n      onFinish();\n    }\n    function fieldUpH() {\n      dom.unbind(window, 'mousemove', setH);\n      dom.unbind(window, 'touchmove', setH);\n      dom.unbind(window, 'mouseup', fieldUpH);\n      dom.unbind(window, 'touchend', fieldUpH);\n      onFinish();\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    function onFinish() {\n      if (_this.__onFinishChange) {\n        _this.__onFinishChange.call(_this, _this.__color.toOriginal());\n      }\n    }\n    _this2.__saturation_field.appendChild(valueField);\n    _this2.__selector.appendChild(_this2.__field_knob);\n    _this2.__selector.appendChild(_this2.__saturation_field);\n    _this2.__selector.appendChild(_this2.__hue_field);\n    _this2.__hue_field.appendChild(_this2.__hue_knob);\n    _this2.domElement.appendChild(_this2.__input);\n    _this2.domElement.appendChild(_this2.__selector);\n    _this2.updateDisplay();\n    function setSV(e) {\n      if (e.type.indexOf('touch') === -1) {\n        e.preventDefault();\n      }\n      var fieldRect = _this.__saturation_field.getBoundingClientRect();\n      var _ref = e.touches && e.touches[0] || e,\n          clientX = _ref.clientX,\n          clientY = _ref.clientY;\n      var s = (clientX - fieldRect.left) / (fieldRect.right - fieldRect.left);\n      var v = 1 - (clientY - fieldRect.top) / (fieldRect.bottom - fieldRect.top);\n      if (v > 1) {\n        v = 1;\n      } else if (v < 0) {\n        v = 0;\n      }\n      if (s > 1) {\n        s = 1;\n      } else if (s < 0) {\n        s = 0;\n      }\n      _this.__color.v = v;\n      _this.__color.s = s;\n      _this.setValue(_this.__color.toOriginal());\n      return false;\n    }\n    function setH(e) {\n      if (e.type.indexOf('touch') === -1) {\n        e.preventDefault();\n      }\n      var fieldRect = _this.__hue_field.getBoundingClientRect();\n      var _ref2 = e.touches && e.touches[0] || e,\n          clientY = _ref2.clientY;\n      var h = 1 - (clientY - fieldRect.top) / (fieldRect.bottom - fieldRect.top);\n      if (h > 1) {\n        h = 1;\n      } else if (h < 0) {\n        h = 0;\n      }\n      _this.__color.h = h * 360;\n      _this.setValue(_this.__color.toOriginal());\n      return false;\n    }\n    return _this2;\n  }\n  createClass(ColorController, [{\n    key: 'updateDisplay',\n    value: function updateDisplay() {\n      var i = interpret(this.getValue());\n      if (i !== false) {\n        var mismatch = false;\n        Common.each(Color.COMPONENTS, function (component) {\n          if (!Common.isUndefined(i[component]) && !Common.isUndefined(this.__color.__state[component]) && i[component] !== this.__color.__state[component]) {\n            mismatch = true;\n            return {};\n          }\n        }, this);\n        if (mismatch) {\n          Common.extend(this.__color.__state, i);\n        }\n      }\n      Common.extend(this.__temp.__state, this.__color.__state);\n      this.__temp.a = 1;\n      var flip = this.__color.v < 0.5 || this.__color.s > 0.5 ? 255 : 0;\n      var _flip = 255 - flip;\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.toHexString(),\n        border: this.__field_knob_border + 'rgb(' + flip + ',' + flip + ',' + flip + ')'\n      });\n      this.__hue_knob.style.marginTop = (1 - this.__color.h / 360) * 100 + 'px';\n      this.__temp.s = 1;\n      this.__temp.v = 1;\n      linearGradient(this.__saturation_field, 'left', '#fff', this.__temp.toHexString());\n      this.__input.value = this.__color.toString();\n      Common.extend(this.__input.style, {\n        backgroundColor: this.__color.toHexString(),\n        color: 'rgb(' + flip + ',' + flip + ',' + flip + ')',\n        textShadow: this.__input_textShadow + 'rgba(' + _flip + ',' + _flip + ',' + _flip + ',.7)'\n      });\n    }\n  }]);\n  return ColorController;\n}(Controller);\nvar vendors = ['-moz-', '-o-', '-webkit-', '-ms-', ''];\nfunction 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}\nfunction 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\nvar css = {\n  load: function load(url, indoc) {\n    var doc = indoc || 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 inject(cssContent, indoc) {\n    var doc = indoc || document;\n    var injected = document.createElement('style');\n    injected.type = 'text/css';\n    injected.innerHTML = cssContent;\n    var head = doc.getElementsByTagName('head')[0];\n    try {\n      head.appendChild(injected);\n    } catch (e) {\n    }\n  }\n};\n\nvar saveDialogContents = \"<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\nvar ControllerFactory = function ControllerFactory(object, property) {\n  var initialValue = object[property];\n  if (Common.isArray(arguments[2]) || Common.isObject(arguments[2])) {\n    return new OptionController(object, property, arguments[2]);\n  }\n  if (Common.isNumber(initialValue)) {\n    if (Common.isNumber(arguments[2]) && Common.isNumber(arguments[3])) {\n      if (Common.isNumber(arguments[4])) {\n        return new NumberControllerSlider(object, property, arguments[2], arguments[3], arguments[4]);\n      }\n      return new NumberControllerSlider(object, property, arguments[2], arguments[3]);\n    }\n    if (Common.isNumber(arguments[4])) {\n      return new NumberControllerBox(object, property, { min: arguments[2], max: arguments[3], step: arguments[4] });\n    }\n    return new NumberControllerBox(object, property, { min: arguments[2], max: arguments[3] });\n  }\n  if (Common.isString(initialValue)) {\n    return new StringController(object, property);\n  }\n  if (Common.isFunction(initialValue)) {\n    return new FunctionController(object, property, '');\n  }\n  if (Common.isBoolean(initialValue)) {\n    return new BooleanController(object, property);\n  }\n  return null;\n};\n\nfunction requestAnimationFrame(callback) {\n  setTimeout(callback, 1000 / 60);\n}\nvar requestAnimationFrame$1 = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || requestAnimationFrame;\n\nvar CenteredDiv = function () {\n  function CenteredDiv() {\n    classCallCheck(this, CenteredDiv);\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      transition: 'opacity 0.2s linear'\n    });\n    dom.makeFullscreen(this.backgroundElement);\n    this.backgroundElement.style.position = 'fixed';\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      transition: 'transform 0.2s ease-out, opacity 0.2s linear'\n    });\n    document.body.appendChild(this.backgroundElement);\n    document.body.appendChild(this.domElement);\n    var _this = this;\n    dom.bind(this.backgroundElement, 'click', function () {\n      _this.hide();\n    });\n  }\n  createClass(CenteredDiv, [{\n    key: 'show',\n    value: function show() {\n      var _this = this;\n      this.backgroundElement.style.display = 'block';\n      this.domElement.style.display = 'block';\n      this.domElement.style.opacity = 0;\n      this.domElement.style.webkitTransform = 'scale(1.1)';\n      this.layout();\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    key: 'hide',\n    value: function hide() {\n      var _this = this;\n      var hide = function hide() {\n        _this.domElement.style.display = 'none';\n        _this.backgroundElement.style.display = 'none';\n        dom.unbind(_this.domElement, 'webkitTransitionEnd', hide);\n        dom.unbind(_this.domElement, 'transitionend', hide);\n        dom.unbind(_this.domElement, 'oTransitionEnd', hide);\n      };\n      dom.bind(this.domElement, 'webkitTransitionEnd', hide);\n      dom.bind(this.domElement, 'transitionend', hide);\n      dom.bind(this.domElement, 'oTransitionEnd', hide);\n      this.backgroundElement.style.opacity = 0;\n      this.domElement.style.opacity = 0;\n      this.domElement.style.webkitTransform = 'scale(1.1)';\n    }\n  }, {\n    key: 'layout',\n    value: function layout() {\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  return CenteredDiv;\n}();\n\nvar styleSheet = ___$insertStyle(\".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 .1s linear;-o-transition:opacity .1s linear;-moz-transition:opacity .1s linear;transition:opacity .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 .1s linear;-o-transition:opacity .1s linear;-moz-transition:opacity .1s linear;transition:opacity .1s linear;border:0;line-height:19px;height:20px;cursor:pointer;text-align:center;background-color:#000}.dg.main .close-button.close-top{position:relative}.dg.main .close-button.close-bottom{position:absolute}.dg.main .close-button:hover{background-color:#111}.dg.a{float:right;margin-right:15px;overflow-y:visible}.dg.a.has-save>ul.close-top{margin-top:0}.dg.a.has-save>ul.close-bottom{margin-top:27px}.dg.a.has-save>ul.closed{margin-top:0}.dg.a .save-row{top:0;z-index:1002}.dg.a .save-row.close-top{position:relative}.dg.a .save-row.close-bottom{position:fixed}.dg li{-webkit-transition:height .1s ease-out;-o-transition:height .1s ease-out;-moz-transition:height .1s ease-out;transition:height .1s ease-out;-webkit-transition:overflow .1s linear;-o-transition:overflow .1s linear;-moz-transition:overflow .1s linear;transition:overflow .1s linear}.dg li:not(.folder){cursor:auto;height:27px;line-height:27px;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;overflow:hidden}.dg .property-name{cursor:default;float:left;clear:left;width:40%;overflow:hidden;text-overflow:ellipsis}.dg .cr.function .property-name{width:100%}.dg .c{float:left;width:60%;position:relative}.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:7px}.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 .cr.color{overflow:visible}.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.color{border-left:3px solid}.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;max-width:100%}.dg .c .slider:hover{background:#3c3c3c}.dg .c .slider:hover .slider-fg{background:#44abda}\\n\");\n\ncss.inject(styleSheet);\nvar CSS_NAMESPACE = 'dg';\nvar HIDE_KEY_CODE = 72;\nvar CLOSE_BUTTON_HEIGHT = 20;\nvar DEFAULT_DEFAULT_PRESET_NAME = 'Default';\nvar SUPPORTS_LOCAL_STORAGE = function () {\n  try {\n    return !!window.localStorage;\n  } catch (e) {\n    return false;\n  }\n}();\nvar SAVE_DIALOGUE = void 0;\nvar autoPlaceVirgin = true;\nvar autoPlaceContainer = void 0;\nvar hide = false;\nvar hideableGuis = [];\nvar GUI = function GUI(pars) {\n  var _this = this;\n  var params = pars || {};\n  this.domElement = document.createElement('div');\n  this.__ul = document.createElement('ul');\n  this.domElement.appendChild(this.__ul);\n  dom.addClass(this.domElement, CSS_NAMESPACE);\n  this.__folders = {};\n  this.__controllers = [];\n  this.__rememberedObjects = [];\n  this.__rememberedObjectIndecesToControllers = [];\n  this.__listening = [];\n  params = Common.defaults(params, {\n    closeOnTop: false,\n    autoPlace: true,\n    width: GUI.DEFAULT_WIDTH\n  });\n  params = Common.defaults(params, {\n    resizable: params.autoPlace,\n    hideable: params.autoPlace\n  });\n  if (!Common.isUndefined(params.load)) {\n    if (params.preset) {\n      params.load.preset = params.preset;\n    }\n  } else {\n    params.load = { preset: DEFAULT_DEFAULT_PRESET_NAME };\n  }\n  if (Common.isUndefined(params.parent) && params.hideable) {\n    hideableGuis.push(this);\n  }\n  params.resizable = Common.isUndefined(params.parent) && params.resizable;\n  if (params.autoPlace && Common.isUndefined(params.scrollable)) {\n    params.scrollable = true;\n  }\n  var useLocalStorage = SUPPORTS_LOCAL_STORAGE && localStorage.getItem(getLocalStorageHash(this, 'isLocal')) === 'true';\n  var saveToLocalStorage = void 0;\n  var titleRow = void 0;\n  Object.defineProperties(this,\n  {\n    parent: {\n      get: function get$$1() {\n        return params.parent;\n      }\n    },\n    scrollable: {\n      get: function get$$1() {\n        return params.scrollable;\n      }\n    },\n    autoPlace: {\n      get: function get$$1() {\n        return params.autoPlace;\n      }\n    },\n    closeOnTop: {\n      get: function get$$1() {\n        return params.closeOnTop;\n      }\n    },\n    preset: {\n      get: function get$$1() {\n        if (_this.parent) {\n          return _this.getRoot().preset;\n        }\n        return params.load.preset;\n      },\n      set: function set$$1(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    width: {\n      get: function get$$1() {\n        return params.width;\n      },\n      set: function set$$1(v) {\n        params.width = v;\n        setWidth(_this, v);\n      }\n    },\n    name: {\n      get: function get$$1() {\n        return params.name;\n      },\n      set: function set$$1(v) {\n        params.name = v;\n        if (titleRow) {\n          titleRow.innerHTML = params.name;\n        }\n      }\n    },\n    closed: {\n      get: function get$$1() {\n        return params.closed;\n      },\n      set: function set$$1(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        this.onResize();\n        if (_this.__closeButton) {\n          _this.__closeButton.innerHTML = v ? GUI.TEXT_OPEN : GUI.TEXT_CLOSED;\n        }\n      }\n    },\n    load: {\n      get: function get$$1() {\n        return params.load;\n      }\n    },\n    useLocalStorage: {\n      get: function get$$1() {\n        return useLocalStorage;\n      },\n      set: function set$$1(bool) {\n        if (SUPPORTS_LOCAL_STORAGE) {\n          useLocalStorage = 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  if (Common.isUndefined(params.parent)) {\n    this.closed = params.closed || false;\n    dom.addClass(this.domElement, GUI.CLASS_MAIN);\n    dom.makeSelectable(this.domElement, false);\n    if (SUPPORTS_LOCAL_STORAGE) {\n      if (useLocalStorage) {\n        _this.useLocalStorage = true;\n        var savedGui = localStorage.getItem(getLocalStorageHash(this, 'gui'));\n        if (savedGui) {\n          params.load = JSON.parse(savedGui);\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    if (params.closeOnTop) {\n      dom.addClass(this.__closeButton, GUI.CLASS_CLOSE_TOP);\n      this.domElement.insertBefore(this.__closeButton, this.domElement.childNodes[0]);\n    } else {\n      dom.addClass(this.__closeButton, GUI.CLASS_CLOSE_BOTTOM);\n      this.domElement.appendChild(this.__closeButton);\n    }\n    dom.bind(this.__closeButton, 'click', function () {\n      _this.closed = !_this.closed;\n    });\n  } else {\n    if (params.closed === undefined) {\n      params.closed = true;\n    }\n    var titleRowName = document.createTextNode(params.name);\n    dom.addClass(titleRowName, 'controller-name');\n    titleRow = addRow(_this, titleRowName);\n    var onClickTitle = function onClickTitle(e) {\n      e.preventDefault();\n      _this.closed = !_this.closed;\n      return false;\n    };\n    dom.addClass(this.__ul, GUI.CLASS_CLOSED);\n    dom.addClass(titleRow, 'title');\n    dom.bind(titleRow, 'click', onClickTitle);\n    if (!params.closed) {\n      this.closed = false;\n    }\n  }\n  if (params.autoPlace) {\n    if (Common.isUndefined(params.parent)) {\n      if (autoPlaceVirgin) {\n        autoPlaceContainer = document.createElement('div');\n        dom.addClass(autoPlaceContainer, CSS_NAMESPACE);\n        dom.addClass(autoPlaceContainer, GUI.CLASS_AUTO_PLACE_CONTAINER);\n        document.body.appendChild(autoPlaceContainer);\n        autoPlaceVirgin = false;\n      }\n      autoPlaceContainer.appendChild(this.domElement);\n      dom.addClass(this.domElement, GUI.CLASS_AUTO_PLACE);\n    }\n    if (!this.parent) {\n      setWidth(_this, params.width);\n    }\n  }\n  this.__resizeHandler = function () {\n    _this.onResizeDebounced();\n  };\n  dom.bind(window, 'resize', this.__resizeHandler);\n  dom.bind(this.__ul, 'webkitTransitionEnd', this.__resizeHandler);\n  dom.bind(this.__ul, 'transitionend', this.__resizeHandler);\n  dom.bind(this.__ul, 'oTransitionEnd', this.__resizeHandler);\n  this.onResize();\n  if (params.resizable) {\n    addResizeHandle(this);\n  }\n  saveToLocalStorage = function saveToLocalStorage() {\n    if (SUPPORTS_LOCAL_STORAGE && localStorage.getItem(getLocalStorageHash(_this, 'isLocal')) === 'true') {\n      localStorage.setItem(getLocalStorageHash(_this, 'gui'), JSON.stringify(_this.getSaveObject()));\n    }\n  };\n  this.saveToLocalStorageIfPossible = saveToLocalStorage;\n  function resetWidth() {\n    var root = _this.getRoot();\n    root.width += 1;\n    Common.defer(function () {\n      root.width -= 1;\n    });\n  }\n  if (!params.parent) {\n    resetWidth();\n  }\n};\nGUI.toggleHide = function () {\n  hide = !hide;\n  Common.each(hideableGuis, function (gui) {\n    gui.domElement.style.display = hide ? 'none' : '';\n  });\n};\nGUI.CLASS_AUTO_PLACE = 'a';\nGUI.CLASS_AUTO_PLACE_CONTAINER = 'ac';\nGUI.CLASS_MAIN = 'main';\nGUI.CLASS_CONTROLLER_ROW = 'cr';\nGUI.CLASS_TOO_TALL = 'taller-than-window';\nGUI.CLASS_CLOSED = 'closed';\nGUI.CLASS_CLOSE_BUTTON = 'close-button';\nGUI.CLASS_CLOSE_TOP = 'close-top';\nGUI.CLASS_CLOSE_BOTTOM = 'close-bottom';\nGUI.CLASS_DRAG = 'drag';\nGUI.DEFAULT_WIDTH = 245;\nGUI.TEXT_CLOSED = 'Close Controls';\nGUI.TEXT_OPEN = 'Open Controls';\nGUI._keydownHandler = function (e) {\n  if (document.activeElement.type !== 'text' && (e.which === HIDE_KEY_CODE || e.keyCode === HIDE_KEY_CODE)) {\n    GUI.toggleHide();\n  }\n};\ndom.bind(window, 'keydown', GUI._keydownHandler, false);\nCommon.extend(GUI.prototype,\n{\n  add: function add(object, property) {\n    return _add(this, object, property, {\n      factoryArgs: Array.prototype.slice.call(arguments, 2)\n    });\n  },\n  addColor: function addColor(object, property) {\n    return _add(this, object, property, {\n      color: true\n    });\n  },\n  remove: function remove(controller) {\n    this.__ul.removeChild(controller.__li);\n    this.__controllers.splice(this.__controllers.indexOf(controller), 1);\n    var _this = this;\n    Common.defer(function () {\n      _this.onResize();\n    });\n  },\n  destroy: function destroy() {\n    if (this.parent) {\n      throw new Error('Only the root GUI should be removed with .destroy(). ' + 'For subfolders, use gui.removeFolder(folder) instead.');\n    }\n    if (this.autoPlace) {\n      autoPlaceContainer.removeChild(this.domElement);\n    }\n    var _this = this;\n    Common.each(this.__folders, function (subfolder) {\n      _this.removeFolder(subfolder);\n    });\n    dom.unbind(window, 'keydown', GUI._keydownHandler, false);\n    removeListeners(this);\n  },\n  addFolder: function addFolder(name) {\n    if (this.__folders[name] !== undefined) {\n      throw new Error('You already have a folder in this GUI by the' + ' name \"' + name + '\"');\n    }\n    var newGuiParams = { name: name, parent: this };\n    newGuiParams.autoPlace = this.autoPlace;\n    if (this.load &&\n    this.load.folders &&\n    this.load.folders[name]) {\n      newGuiParams.closed = this.load.folders[name].closed;\n      newGuiParams.load = this.load.folders[name];\n    }\n    var gui = new GUI(newGuiParams);\n    this.__folders[name] = gui;\n    var li = addRow(this, gui.domElement);\n    dom.addClass(li, 'folder');\n    return gui;\n  },\n  removeFolder: function removeFolder(folder) {\n    this.__ul.removeChild(folder.domElement.parentElement);\n    delete this.__folders[folder.name];\n    if (this.load &&\n    this.load.folders &&\n    this.load.folders[folder.name]) {\n      delete this.load.folders[folder.name];\n    }\n    removeListeners(folder);\n    var _this = this;\n    Common.each(folder.__folders, function (subfolder) {\n      folder.removeFolder(subfolder);\n    });\n    Common.defer(function () {\n      _this.onResize();\n    });\n  },\n  open: function open() {\n    this.closed = false;\n  },\n  close: function close() {\n    this.closed = true;\n  },\n  hide: function hide() {\n    this.domElement.style.display = 'none';\n  },\n  show: function show() {\n    this.domElement.style.display = '';\n  },\n  onResize: function onResize() {\n    var root = this.getRoot();\n    if (root.scrollable) {\n      var top = dom.getOffset(root.__ul).top;\n      var h = 0;\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    if (root.__resize_handle) {\n      Common.defer(function () {\n        root.__resize_handle.style.height = root.__ul.offsetHeight + 'px';\n      });\n    }\n    if (root.__closeButton) {\n      root.__closeButton.style.width = root.width + 'px';\n    }\n  },\n  onResizeDebounced: Common.debounce(function () {\n    this.onResize();\n  }, 50),\n  remember: function remember() {\n    if (Common.isUndefined(SAVE_DIALOGUE)) {\n      SAVE_DIALOGUE = new CenteredDiv();\n      SAVE_DIALOGUE.domElement.innerHTML = saveDialogContents;\n    }\n    if (this.parent) {\n      throw new Error('You can only call remember on a top level GUI.');\n    }\n    var _this = this;\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    if (this.autoPlace) {\n      setWidth(this, this.width);\n    }\n  },\n  getRoot: function getRoot() {\n    var gui = this;\n    while (gui.parent) {\n      gui = gui.parent;\n    }\n    return gui;\n  },\n  getSaveObject: function getSaveObject() {\n    var toReturn = this.load;\n    toReturn.closed = this.closed;\n    if (this.__rememberedObjects.length > 0) {\n      toReturn.preset = this.preset;\n      if (!toReturn.remembered) {\n        toReturn.remembered = {};\n      }\n      toReturn.remembered[this.preset] = getCurrentPreset(this);\n    }\n    toReturn.folders = {};\n    Common.each(this.__folders, function (element, key) {\n      toReturn.folders[key] = element.getSaveObject();\n    });\n    return toReturn;\n  },\n  save: function save() {\n    if (!this.load.remembered) {\n      this.load.remembered = {};\n    }\n    this.load.remembered[this.preset] = getCurrentPreset(this);\n    markPresetModified(this, false);\n    this.saveToLocalStorageIfPossible();\n  },\n  saveAs: function saveAs(presetName) {\n    if (!this.load.remembered) {\n      this.load.remembered = {};\n      this.load.remembered[DEFAULT_DEFAULT_PRESET_NAME] = getCurrentPreset(this, true);\n    }\n    this.load.remembered[presetName] = getCurrentPreset(this);\n    this.preset = presetName;\n    addPresetOption(this, presetName, true);\n    this.saveToLocalStorageIfPossible();\n  },\n  revert: function revert(gui) {\n    Common.each(this.__controllers, function (controller) {\n      if (!this.getRoot().load.remembered) {\n        controller.setValue(controller.initialValue);\n      } else {\n        recallSavedValue(gui || this.getRoot(), controller);\n      }\n      if (controller.__onFinishChange) {\n        controller.__onFinishChange.call(controller, controller.getValue());\n      }\n    }, this);\n    Common.each(this.__folders, function (folder) {\n      folder.revert(folder);\n    });\n    if (!gui) {\n      markPresetModified(this.getRoot(), false);\n    }\n  },\n  listen: function listen(controller) {\n    var init = this.__listening.length === 0;\n    this.__listening.push(controller);\n    if (init) {\n      updateDisplays(this.__listening);\n    }\n  },\n  updateDisplay: function updateDisplay() {\n    Common.each(this.__controllers, function (controller) {\n      controller.updateDisplay();\n    });\n    Common.each(this.__folders, function (folder) {\n      folder.updateDisplay();\n    });\n  }\n});\nfunction addRow(gui, newDom, liBefore) {\n  var li = document.createElement('li');\n  if (newDom) {\n    li.appendChild(newDom);\n  }\n  if (liBefore) {\n    gui.__ul.insertBefore(li, liBefore);\n  } else {\n    gui.__ul.appendChild(li);\n  }\n  gui.onResize();\n  return li;\n}\nfunction removeListeners(gui) {\n  dom.unbind(window, 'resize', gui.__resizeHandler);\n  if (gui.saveToLocalStorageIfPossible) {\n    dom.unbind(window, 'unload', gui.saveToLocalStorageIfPossible);\n  }\n}\nfunction markPresetModified(gui, modified) {\n  var opt = gui.__preset_select[gui.__preset_select.selectedIndex];\n  if (modified) {\n    opt.innerHTML = opt.value + '*';\n  } else {\n    opt.innerHTML = opt.value;\n  }\n}\nfunction augmentController(gui, li, controller) {\n  controller.__li = li;\n  controller.__gui = gui;\n  Common.extend(controller, {\n    options: function options(_options) {\n      if (arguments.length > 1) {\n        var nextSibling = controller.__li.nextElementSibling;\n        controller.remove();\n        return _add(gui, controller.object, controller.property, {\n          before: nextSibling,\n          factoryArgs: [Common.toArray(arguments)]\n        });\n      }\n      if (Common.isArray(_options) || Common.isObject(_options)) {\n        var _nextSibling = controller.__li.nextElementSibling;\n        controller.remove();\n        return _add(gui, controller.object, controller.property, {\n          before: _nextSibling,\n          factoryArgs: [_options]\n        });\n      }\n    },\n    name: function name(_name) {\n      controller.__li.firstElementChild.firstElementChild.innerHTML = _name;\n      return controller;\n    },\n    listen: function listen() {\n      controller.__gui.listen(controller);\n      return controller;\n    },\n    remove: function remove() {\n      controller.__gui.remove(controller);\n      return controller;\n    }\n  });\n  if (controller instanceof NumberControllerSlider) {\n    var box = new NumberControllerBox(controller.object, controller.property, { min: controller.__min, max: controller.__max, step: controller.__step });\n    Common.each(['updateDisplay', 'onChange', 'onFinishChange', 'step', 'min', 'max'], 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        pb.apply(box, args);\n        return pc.apply(controller, args);\n      };\n    });\n    dom.addClass(li, 'has-slider');\n    controller.domElement.insertBefore(box.domElement, controller.domElement.firstElementChild);\n  } else if (controller instanceof NumberControllerBox) {\n    var r = function r(returned) {\n      if (Common.isNumber(controller.__min) && Common.isNumber(controller.__max)) {\n        var oldName = controller.__li.firstElementChild.firstElementChild.innerHTML;\n        var wasListening = controller.__gui.__listening.indexOf(controller) > -1;\n        controller.remove();\n        var newController = _add(gui, controller.object, controller.property, {\n          before: controller.__li.nextElementSibling,\n          factoryArgs: [controller.__min, controller.__max, controller.__step]\n        });\n        newController.name(oldName);\n        if (wasListening) newController.listen();\n        return newController;\n      }\n      return returned;\n    };\n    controller.min = Common.compose(r, controller.min);\n    controller.max = Common.compose(r, controller.max);\n  } else if (controller instanceof BooleanController) {\n    dom.bind(li, 'click', function () {\n      dom.fakeEvent(controller.__checkbox, 'click');\n    });\n    dom.bind(controller.__checkbox, 'click', function (e) {\n      e.stopPropagation();\n    });\n  } else if (controller instanceof FunctionController) {\n    dom.bind(li, 'click', function () {\n      dom.fakeEvent(controller.__button, 'click');\n    });\n    dom.bind(li, 'mouseover', function () {\n      dom.addClass(controller.__button, 'hover');\n    });\n    dom.bind(li, 'mouseout', function () {\n      dom.removeClass(controller.__button, 'hover');\n    });\n  } else if (controller instanceof ColorController) {\n    dom.addClass(li, 'color');\n    controller.updateDisplay = Common.compose(function (val) {\n      li.style.borderLeftColor = controller.__color.toString();\n      return val;\n    }, controller.updateDisplay);\n    controller.updateDisplay();\n  }\n  controller.setValue = Common.compose(function (val) {\n    if (gui.getRoot().__preset_select && controller.isModified()) {\n      markPresetModified(gui.getRoot(), true);\n    }\n    return val;\n  }, controller.setValue);\n}\nfunction recallSavedValue(gui, controller) {\n  var root = gui.getRoot();\n  var matchedIndex = root.__rememberedObjects.indexOf(controller.object);\n  if (matchedIndex !== -1) {\n    var controllerMap = root.__rememberedObjectIndecesToControllers[matchedIndex];\n    if (controllerMap === undefined) {\n      controllerMap = {};\n      root.__rememberedObjectIndecesToControllers[matchedIndex] = controllerMap;\n    }\n    controllerMap[controller.property] = controller;\n    if (root.load && root.load.remembered) {\n      var presetMap = root.load.remembered;\n      var preset = void 0;\n      if (presetMap[gui.preset]) {\n        preset = presetMap[gui.preset];\n      } else if (presetMap[DEFAULT_DEFAULT_PRESET_NAME]) {\n        preset = presetMap[DEFAULT_DEFAULT_PRESET_NAME];\n      } else {\n        return;\n      }\n      if (preset[matchedIndex] && preset[matchedIndex][controller.property] !== undefined) {\n        var value = preset[matchedIndex][controller.property];\n        controller.initialValue = value;\n        controller.setValue(value);\n      }\n    }\n  }\n}\nfunction _add(gui, object, property, params) {\n  if (object[property] === undefined) {\n    throw new Error('Object \"' + object + '\" has no property \"' + property + '\"');\n  }\n  var controller = void 0;\n  if (params.color) {\n    controller = new ColorController(object, property);\n  } else {\n    var factoryArgs = [object, property].concat(params.factoryArgs);\n    controller = ControllerFactory.apply(gui, factoryArgs);\n  }\n  if (params.before instanceof Controller) {\n    params.before = params.before.__li;\n  }\n  recallSavedValue(gui, controller);\n  dom.addClass(controller.domElement, 'c');\n  var name = document.createElement('span');\n  dom.addClass(name, 'property-name');\n  name.innerHTML = controller.property;\n  var container = document.createElement('div');\n  container.appendChild(name);\n  container.appendChild(controller.domElement);\n  var li = addRow(gui, container, params.before);\n  dom.addClass(li, GUI.CLASS_CONTROLLER_ROW);\n  if (controller instanceof ColorController) {\n    dom.addClass(li, 'color');\n  } else {\n    dom.addClass(li, _typeof(controller.getValue()));\n  }\n  augmentController(gui, li, controller);\n  gui.__controllers.push(controller);\n  return controller;\n}\nfunction getLocalStorageHash(gui, key) {\n  return document.location.href + '.' + key;\n}\nfunction 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}\nfunction showHideExplain(gui, explain) {\n  explain.style.display = gui.useLocalStorage ? 'block' : 'none';\n}\nfunction addSaveMenu(gui) {\n  var div = gui.__save_row = document.createElement('li');\n  dom.addClass(gui.domElement, 'has-save');\n  gui.__ul.insertBefore(div, gui.__ul.firstChild);\n  dom.addClass(div, 'save-row');\n  var gears = document.createElement('span');\n  gears.innerHTML = '&nbsp;';\n  dom.addClass(gears, 'button gears');\n  var button = document.createElement('span');\n  button.innerHTML = 'Save';\n  dom.addClass(button, 'button');\n  dom.addClass(button, 'save');\n  var button2 = document.createElement('span');\n  button2.innerHTML = 'New';\n  dom.addClass(button2, 'button');\n  dom.addClass(button2, 'save-as');\n  var button3 = document.createElement('span');\n  button3.innerHTML = 'Revert';\n  dom.addClass(button3, 'button');\n  dom.addClass(button3, 'revert');\n  var select = gui.__preset_select = document.createElement('select');\n  if (gui.load && gui.load.remembered) {\n    Common.each(gui.load.remembered, function (value, key) {\n      addPresetOption(gui, key, key === gui.preset);\n    });\n  } else {\n    addPresetOption(gui, DEFAULT_DEFAULT_PRESET_NAME, false);\n  }\n  dom.bind(select, 'change', function () {\n    for (var index = 0; index < gui.__preset_select.length; index++) {\n      gui.__preset_select[index].innerHTML = gui.__preset_select[index].value;\n    }\n    gui.preset = this.value;\n  });\n  div.appendChild(select);\n  div.appendChild(gears);\n  div.appendChild(button);\n  div.appendChild(button2);\n  div.appendChild(button3);\n  if (SUPPORTS_LOCAL_STORAGE) {\n    var explain = document.getElementById('dg-local-explain');\n    var localStorageCheckBox = document.getElementById('dg-local-storage');\n    var saveLocally = document.getElementById('dg-save-locally');\n    saveLocally.style.display = 'block';\n    if (localStorage.getItem(getLocalStorageHash(gui, 'isLocal')) === 'true') {\n      localStorageCheckBox.setAttribute('checked', 'checked');\n    }\n    showHideExplain(gui, explain);\n    dom.bind(localStorageCheckBox, 'change', function () {\n      gui.useLocalStorage = !gui.useLocalStorage;\n      showHideExplain(gui, explain);\n    });\n  }\n  var newConstructorTextArea = document.getElementById('dg-new-constructor');\n  dom.bind(newConstructorTextArea, 'keydown', function (e) {\n    if (e.metaKey && (e.which === 67 || e.keyCode === 67)) {\n      SAVE_DIALOGUE.hide();\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  dom.bind(button, 'click', function () {\n    gui.save();\n  });\n  dom.bind(button2, 'click', function () {\n    var presetName = prompt('Enter a new preset name.');\n    if (presetName) {\n      gui.saveAs(presetName);\n    }\n  });\n  dom.bind(button3, 'click', function () {\n    gui.revert();\n  });\n}\nfunction addResizeHandle(gui) {\n  var pmouseX = void 0;\n  gui.__resize_handle = document.createElement('div');\n  Common.extend(gui.__resize_handle.style, {\n    width: '6px',\n    marginLeft: '-3px',\n    height: '200px',\n    cursor: 'ew-resize',\n    position: 'absolute'\n  });\n  function drag(e) {\n    e.preventDefault();\n    gui.width += pmouseX - e.clientX;\n    gui.onResize();\n    pmouseX = e.clientX;\n    return false;\n  }\n  function dragStop() {\n    dom.removeClass(gui.__closeButton, GUI.CLASS_DRAG);\n    dom.unbind(window, 'mousemove', drag);\n    dom.unbind(window, 'mouseup', dragStop);\n  }\n  function dragStart(e) {\n    e.preventDefault();\n    pmouseX = e.clientX;\n    dom.addClass(gui.__closeButton, GUI.CLASS_DRAG);\n    dom.bind(window, 'mousemove', drag);\n    dom.bind(window, 'mouseup', dragStop);\n    return false;\n  }\n  dom.bind(gui.__resize_handle, 'mousedown', dragStart);\n  dom.bind(gui.__closeButton, 'mousedown', dragStart);\n  gui.domElement.insertBefore(gui.__resize_handle, gui.domElement.firstElementChild);\n}\nfunction setWidth(gui, w) {\n  gui.domElement.style.width = w + 'px';\n  if (gui.__save_row && gui.autoPlace) {\n    gui.__save_row.style.width = w + 'px';\n  }\n  if (gui.__closeButton) {\n    gui.__closeButton.style.width = w + 'px';\n  }\n}\nfunction getCurrentPreset(gui, useInitialValues) {\n  var toReturn = {};\n  Common.each(gui.__rememberedObjects, function (val, index) {\n    var savedValues = {};\n    var controllerMap = gui.__rememberedObjectIndecesToControllers[index];\n    Common.each(controllerMap, function (controller, property) {\n      savedValues[property] = useInitialValues ? controller.initialValue : controller.getValue();\n    });\n    toReturn[index] = savedValues;\n  });\n  return toReturn;\n}\nfunction 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}\nfunction updateDisplays(controllerArray) {\n  if (controllerArray.length !== 0) {\n    requestAnimationFrame$1.call(window, function () {\n      updateDisplays(controllerArray);\n    });\n  }\n  Common.each(controllerArray, function (c) {\n    c.updateDisplay();\n  });\n}\n\nvar color = {\n  Color: Color,\n  math: ColorMath,\n  interpret: interpret\n};\nvar controllers = {\n  Controller: Controller,\n  BooleanController: BooleanController,\n  OptionController: OptionController,\n  StringController: StringController,\n  NumberController: NumberController,\n  NumberControllerBox: NumberControllerBox,\n  NumberControllerSlider: NumberControllerSlider,\n  FunctionController: FunctionController,\n  ColorController: ColorController\n};\nvar dom$1 = { dom: dom };\nvar gui = { GUI: GUI };\nvar GUI$1 = GUI;\nvar index = {\n  color: color,\n  controllers: controllers,\n  dom: dom$1,\n  gui: gui,\n  GUI: GUI$1\n};\n\nexports.color = color;\nexports.controllers = controllers;\nexports.dom = dom$1;\nexports.gui = gui;\nexports.GUI = GUI$1;\nexports['default'] = index;\n\nObject.defineProperty(exports, '__esModule', { value: true });\n\n})));\n//# sourceMappingURL=dat.gui.js.map\n"
  },
  {
    "path": "build/dat.gui.module.js",
    "content": "/**\n * dat-gui JavaScript Controller Library\n * https://github.com/dataarts/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\nfunction ___$insertStyle(css) {\n  if (!css) {\n    return;\n  }\n  if (typeof window === 'undefined') {\n    return;\n  }\n\n  var style = document.createElement('style');\n\n  style.setAttribute('type', 'text/css');\n  style.innerHTML = css;\n  document.head.appendChild(style);\n\n  return css;\n}\n\nfunction colorToString (color, forceCSSHex) {\n  var colorFormat = color.__state.conversionName.toString();\n  var r = Math.round(color.r);\n  var g = Math.round(color.g);\n  var b = Math.round(color.b);\n  var a = color.a;\n  var h = Math.round(color.h);\n  var s = color.s.toFixed(1);\n  var v = color.v.toFixed(1);\n  if (forceCSSHex || colorFormat === 'THREE_CHAR_HEX' || colorFormat === 'SIX_CHAR_HEX') {\n    var str = color.hex.toString(16);\n    while (str.length < 6) {\n      str = '0' + str;\n    }\n    return '#' + str;\n  } else if (colorFormat === 'CSS_RGB') {\n    return 'rgb(' + r + ',' + g + ',' + b + ')';\n  } else if (colorFormat === 'CSS_RGBA') {\n    return 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';\n  } else if (colorFormat === 'HEX') {\n    return '0x' + color.hex.toString(16);\n  } else if (colorFormat === 'RGB_ARRAY') {\n    return '[' + r + ',' + g + ',' + b + ']';\n  } else if (colorFormat === 'RGBA_ARRAY') {\n    return '[' + r + ',' + g + ',' + b + ',' + a + ']';\n  } else if (colorFormat === 'RGB_OBJ') {\n    return '{r:' + r + ',g:' + g + ',b:' + b + '}';\n  } else if (colorFormat === 'RGBA_OBJ') {\n    return '{r:' + r + ',g:' + g + ',b:' + b + ',a:' + a + '}';\n  } else if (colorFormat === 'HSV_OBJ') {\n    return '{h:' + h + ',s:' + s + ',v:' + v + '}';\n  } else if (colorFormat === 'HSVA_OBJ') {\n    return '{h:' + h + ',s:' + s + ',v:' + v + ',a:' + a + '}';\n  }\n  return 'unknown format';\n}\n\nvar ARR_EACH = Array.prototype.forEach;\nvar ARR_SLICE = Array.prototype.slice;\nvar Common = {\n  BREAK: {},\n  extend: function extend(target) {\n    this.each(ARR_SLICE.call(arguments, 1), function (obj) {\n      var keys = this.isObject(obj) ? Object.keys(obj) : [];\n      keys.forEach(function (key) {\n        if (!this.isUndefined(obj[key])) {\n          target[key] = obj[key];\n        }\n      }.bind(this));\n    }, this);\n    return target;\n  },\n  defaults: function defaults(target) {\n    this.each(ARR_SLICE.call(arguments, 1), function (obj) {\n      var keys = this.isObject(obj) ? Object.keys(obj) : [];\n      keys.forEach(function (key) {\n        if (this.isUndefined(target[key])) {\n          target[key] = obj[key];\n        }\n      }.bind(this));\n    }, this);\n    return target;\n  },\n  compose: function compose() {\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  each: function each(obj, itr, scope) {\n    if (!obj) {\n      return;\n    }\n    if (ARR_EACH && obj.forEach && obj.forEach === ARR_EACH) {\n      obj.forEach(itr, scope);\n    } else if (obj.length === obj.length + 0) {\n      var key = void 0;\n      var l = void 0;\n      for (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      }\n    } else {\n      for (var _key in obj) {\n        if (itr.call(scope, obj[_key], _key) === this.BREAK) {\n          return;\n        }\n      }\n    }\n  },\n  defer: function defer(fnc) {\n    setTimeout(fnc, 0);\n  },\n  debounce: function debounce(func, threshold, callImmediately) {\n    var timeout = void 0;\n    return function () {\n      var obj = this;\n      var args = arguments;\n      function delayed() {\n        timeout = null;\n        if (!callImmediately) func.apply(obj, args);\n      }\n      var callNow = callImmediately || !timeout;\n      clearTimeout(timeout);\n      timeout = setTimeout(delayed, threshold);\n      if (callNow) {\n        func.apply(obj, args);\n      }\n    };\n  },\n  toArray: function toArray(obj) {\n    if (obj.toArray) return obj.toArray();\n    return ARR_SLICE.call(obj);\n  },\n  isUndefined: function isUndefined(obj) {\n    return obj === undefined;\n  },\n  isNull: function isNull(obj) {\n    return obj === null;\n  },\n  isNaN: function (_isNaN) {\n    function isNaN(_x) {\n      return _isNaN.apply(this, arguments);\n    }\n    isNaN.toString = function () {\n      return _isNaN.toString();\n    };\n    return isNaN;\n  }(function (obj) {\n    return isNaN(obj);\n  }),\n  isArray: Array.isArray || function (obj) {\n    return obj.constructor === Array;\n  },\n  isObject: function isObject(obj) {\n    return obj === Object(obj);\n  },\n  isNumber: function isNumber(obj) {\n    return obj === obj + 0;\n  },\n  isString: function isString(obj) {\n    return obj === obj + '';\n  },\n  isBoolean: function isBoolean(obj) {\n    return obj === false || obj === true;\n  },\n  isFunction: function isFunction(obj) {\n    return obj instanceof Function;\n  }\n};\n\nvar INTERPRETATIONS = [\n{\n  litmus: Common.isString,\n  conversions: {\n    THREE_CHAR_HEX: {\n      read: function read(original) {\n        var test = original.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);\n        if (test === null) {\n          return false;\n        }\n        return {\n          space: 'HEX',\n          hex: parseInt('0x' + test[1].toString() + test[1].toString() + test[2].toString() + test[2].toString() + test[3].toString() + test[3].toString(), 0)\n        };\n      },\n      write: colorToString\n    },\n    SIX_CHAR_HEX: {\n      read: function read(original) {\n        var test = original.match(/^#([A-F0-9]{6})$/i);\n        if (test === null) {\n          return false;\n        }\n        return {\n          space: 'HEX',\n          hex: parseInt('0x' + test[1].toString(), 0)\n        };\n      },\n      write: colorToString\n    },\n    CSS_RGB: {\n      read: function read(original) {\n        var test = original.match(/^rgb\\(\\s*(\\S+)\\s*,\\s*(\\S+)\\s*,\\s*(\\S+)\\s*\\)/);\n        if (test === null) {\n          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      write: colorToString\n    },\n    CSS_RGBA: {\n      read: function read(original) {\n        var test = original.match(/^rgba\\(\\s*(\\S+)\\s*,\\s*(\\S+)\\s*,\\s*(\\S+)\\s*,\\s*(\\S+)\\s*\\)/);\n        if (test === null) {\n          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      write: colorToString\n    }\n  }\n},\n{\n  litmus: Common.isNumber,\n  conversions: {\n    HEX: {\n      read: function read(original) {\n        return {\n          space: 'HEX',\n          hex: original,\n          conversionName: 'HEX'\n        };\n      },\n      write: function write(color) {\n        return color.hex;\n      }\n    }\n  }\n},\n{\n  litmus: Common.isArray,\n  conversions: {\n    RGB_ARRAY: {\n      read: function read(original) {\n        if (original.length !== 3) {\n          return false;\n        }\n        return {\n          space: 'RGB',\n          r: original[0],\n          g: original[1],\n          b: original[2]\n        };\n      },\n      write: function write(color) {\n        return [color.r, color.g, color.b];\n      }\n    },\n    RGBA_ARRAY: {\n      read: function read(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      write: function write(color) {\n        return [color.r, color.g, color.b, color.a];\n      }\n    }\n  }\n},\n{\n  litmus: Common.isObject,\n  conversions: {\n    RGBA_OBJ: {\n      read: function read(original) {\n        if (Common.isNumber(original.r) && Common.isNumber(original.g) && Common.isNumber(original.b) && 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      write: function write(color) {\n        return {\n          r: color.r,\n          g: color.g,\n          b: color.b,\n          a: color.a\n        };\n      }\n    },\n    RGB_OBJ: {\n      read: function read(original) {\n        if (Common.isNumber(original.r) && Common.isNumber(original.g) && 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      write: function write(color) {\n        return {\n          r: color.r,\n          g: color.g,\n          b: color.b\n        };\n      }\n    },\n    HSVA_OBJ: {\n      read: function read(original) {\n        if (Common.isNumber(original.h) && Common.isNumber(original.s) && Common.isNumber(original.v) && 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      write: function write(color) {\n        return {\n          h: color.h,\n          s: color.s,\n          v: color.v,\n          a: color.a\n        };\n      }\n    },\n    HSV_OBJ: {\n      read: function read(original) {\n        if (Common.isNumber(original.h) && Common.isNumber(original.s) && 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      write: function write(color) {\n        return {\n          h: color.h,\n          s: color.s,\n          v: color.v\n        };\n      }\n    }\n  }\n}];\nvar result = void 0;\nvar toReturn = void 0;\nvar interpret = function interpret() {\n  toReturn = false;\n  var original = arguments.length > 1 ? Common.toArray(arguments) : arguments[0];\n  Common.each(INTERPRETATIONS, function (family) {\n    if (family.litmus(original)) {\n      Common.each(family.conversions, function (conversion, conversionName) {\n        result = conversion.read(original);\n        if (toReturn === false && result !== false) {\n          toReturn = result;\n          result.conversionName = conversionName;\n          result.conversion = conversion;\n          return Common.BREAK;\n        }\n      });\n      return Common.BREAK;\n    }\n  });\n  return toReturn;\n};\n\nvar tmpComponent = void 0;\nvar ColorMath = {\n  hsv_to_rgb: function hsv_to_rgb(h, s, v) {\n    var hi = Math.floor(h / 60) % 6;\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 = [[v, t, p], [q, v, p], [p, v, t], [p, q, v], [t, p, v], [v, p, q]][hi];\n    return {\n      r: c[0] * 255,\n      g: c[1] * 255,\n      b: c[2] * 255\n    };\n  },\n  rgb_to_hsv: function rgb_to_hsv(r, g, b) {\n    var min = Math.min(r, g, b);\n    var max = Math.max(r, g, b);\n    var delta = max - min;\n    var h = void 0;\n    var s = void 0;\n    if (max !== 0) {\n      s = delta / max;\n    } else {\n      return {\n        h: NaN,\n        s: 0,\n        v: 0\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    return {\n      h: h * 360,\n      s: s,\n      v: max / 255\n    };\n  },\n  rgb_to_hex: function rgb_to_hex(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  component_from_hex: function component_from_hex(hex, componentIndex) {\n    return hex >> componentIndex * 8 & 0xFF;\n  },\n  hex_with_component: function hex_with_component(hex, componentIndex, value) {\n    return value << (tmpComponent = componentIndex * 8) | hex & ~(0xFF << tmpComponent);\n  }\n};\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) {\n  return typeof obj;\n} : function (obj) {\n  return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj;\n};\n\n\n\n\n\n\n\n\n\n\n\nvar classCallCheck = function (instance, Constructor) {\n  if (!(instance instanceof Constructor)) {\n    throw new TypeError(\"Cannot call a class as a function\");\n  }\n};\n\nvar createClass = function () {\n  function defineProperties(target, props) {\n    for (var i = 0; i < props.length; i++) {\n      var descriptor = props[i];\n      descriptor.enumerable = descriptor.enumerable || false;\n      descriptor.configurable = true;\n      if (\"value\" in descriptor) descriptor.writable = true;\n      Object.defineProperty(target, descriptor.key, descriptor);\n    }\n  }\n\n  return function (Constructor, protoProps, staticProps) {\n    if (protoProps) defineProperties(Constructor.prototype, protoProps);\n    if (staticProps) defineProperties(Constructor, staticProps);\n    return Constructor;\n  };\n}();\n\n\n\n\n\n\n\nvar get = function get(object, property, receiver) {\n  if (object === null) object = Function.prototype;\n  var desc = Object.getOwnPropertyDescriptor(object, property);\n\n  if (desc === undefined) {\n    var parent = Object.getPrototypeOf(object);\n\n    if (parent === null) {\n      return undefined;\n    } else {\n      return get(parent, property, receiver);\n    }\n  } else if (\"value\" in desc) {\n    return desc.value;\n  } else {\n    var getter = desc.get;\n\n    if (getter === undefined) {\n      return undefined;\n    }\n\n    return getter.call(receiver);\n  }\n};\n\nvar inherits = function (subClass, superClass) {\n  if (typeof superClass !== \"function\" && superClass !== null) {\n    throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass);\n  }\n\n  subClass.prototype = Object.create(superClass && superClass.prototype, {\n    constructor: {\n      value: subClass,\n      enumerable: false,\n      writable: true,\n      configurable: true\n    }\n  });\n  if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;\n};\n\n\n\n\n\n\n\n\n\n\n\nvar possibleConstructorReturn = function (self, call) {\n  if (!self) {\n    throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");\n  }\n\n  return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self;\n};\n\nvar Color = function () {\n  function Color() {\n    classCallCheck(this, Color);\n    this.__state = interpret.apply(this, arguments);\n    if (this.__state === false) {\n      throw new Error('Failed to interpret color arguments');\n    }\n    this.__state.a = this.__state.a || 1;\n  }\n  createClass(Color, [{\n    key: 'toString',\n    value: function toString() {\n      return colorToString(this);\n    }\n  }, {\n    key: 'toHexString',\n    value: function toHexString() {\n      return colorToString(this, true);\n    }\n  }, {\n    key: 'toOriginal',\n    value: function toOriginal() {\n      return this.__state.conversion.write(this);\n    }\n  }]);\n  return Color;\n}();\nfunction defineRGBComponent(target, component, componentHexIndex) {\n  Object.defineProperty(target, component, {\n    get: function get$$1() {\n      if (this.__state.space === 'RGB') {\n        return this.__state[component];\n      }\n      Color.recalculateRGB(this, component, componentHexIndex);\n      return this.__state[component];\n    },\n    set: function set$$1(v) {\n      if (this.__state.space !== 'RGB') {\n        Color.recalculateRGB(this, component, componentHexIndex);\n        this.__state.space = 'RGB';\n      }\n      this.__state[component] = v;\n    }\n  });\n}\nfunction defineHSVComponent(target, component) {\n  Object.defineProperty(target, component, {\n    get: function get$$1() {\n      if (this.__state.space === 'HSV') {\n        return this.__state[component];\n      }\n      Color.recalculateHSV(this);\n      return this.__state[component];\n    },\n    set: function set$$1(v) {\n      if (this.__state.space !== 'HSV') {\n        Color.recalculateHSV(this);\n        this.__state.space = 'HSV';\n      }\n      this.__state[component] = v;\n    }\n  });\n}\nColor.recalculateRGB = function (color, component, componentHexIndex) {\n  if (color.__state.space === 'HEX') {\n    color.__state[component] = ColorMath.component_from_hex(color.__state.hex, componentHexIndex);\n  } else if (color.__state.space === 'HSV') {\n    Common.extend(color.__state, ColorMath.hsv_to_rgb(color.__state.h, color.__state.s, color.__state.v));\n  } else {\n    throw new Error('Corrupted color state');\n  }\n};\nColor.recalculateHSV = function (color) {\n  var result = ColorMath.rgb_to_hsv(color.r, color.g, color.b);\n  Common.extend(color.__state, {\n    s: result.s,\n    v: result.v\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};\nColor.COMPONENTS = ['r', 'g', 'b', 'h', 's', 'v', 'hex', 'a'];\ndefineRGBComponent(Color.prototype, 'r', 2);\ndefineRGBComponent(Color.prototype, 'g', 1);\ndefineRGBComponent(Color.prototype, 'b', 0);\ndefineHSVComponent(Color.prototype, 'h');\ndefineHSVComponent(Color.prototype, 's');\ndefineHSVComponent(Color.prototype, 'v');\nObject.defineProperty(Color.prototype, 'a', {\n  get: function get$$1() {\n    return this.__state.a;\n  },\n  set: function set$$1(v) {\n    this.__state.a = v;\n  }\n});\nObject.defineProperty(Color.prototype, 'hex', {\n  get: function get$$1() {\n    if (this.__state.space !== 'HEX') {\n      this.__state.hex = ColorMath.rgb_to_hex(this.r, this.g, this.b);\n      this.__state.space = 'HEX';\n    }\n    return this.__state.hex;\n  },\n  set: function set$$1(v) {\n    this.__state.space = 'HEX';\n    this.__state.hex = v;\n  }\n});\n\nvar Controller = function () {\n  function Controller(object, property) {\n    classCallCheck(this, Controller);\n    this.initialValue = object[property];\n    this.domElement = document.createElement('div');\n    this.object = object;\n    this.property = property;\n    this.__onChange = undefined;\n    this.__onFinishChange = undefined;\n  }\n  createClass(Controller, [{\n    key: 'onChange',\n    value: function onChange(fnc) {\n      this.__onChange = fnc;\n      return this;\n    }\n  }, {\n    key: 'onFinishChange',\n    value: function onFinishChange(fnc) {\n      this.__onFinishChange = fnc;\n      return this;\n    }\n  }, {\n    key: 'setValue',\n    value: function setValue(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    key: 'getValue',\n    value: function getValue() {\n      return this.object[this.property];\n    }\n  }, {\n    key: 'updateDisplay',\n    value: function updateDisplay() {\n      return this;\n    }\n  }, {\n    key: 'isModified',\n    value: function isModified() {\n      return this.initialValue !== this.getValue();\n    }\n  }]);\n  return Controller;\n}();\n\nvar EVENT_MAP = {\n  HTMLEvents: ['change'],\n  MouseEvents: ['click', 'mousemove', 'mousedown', 'mouseup', 'mouseover'],\n  KeyboardEvents: ['keydown']\n};\nvar EVENT_MAP_INV = {};\nCommon.each(EVENT_MAP, function (v, k) {\n  Common.each(v, function (e) {\n    EVENT_MAP_INV[e] = k;\n  });\n});\nvar CSS_VALUE_PIXELS = /(\\d+(\\.\\d+)?)px/;\nfunction cssValueToPixels(val) {\n  if (val === '0' || Common.isUndefined(val)) {\n    return 0;\n  }\n  var match = val.match(CSS_VALUE_PIXELS);\n  if (!Common.isNull(match)) {\n    return parseFloat(match[1]);\n  }\n  return 0;\n}\nvar dom = {\n  makeSelectable: function makeSelectable(elem, selectable) {\n    if (elem === undefined || elem.style === undefined) return;\n    elem.onselectstart = selectable ? function () {\n      return false;\n    } : function () {};\n    elem.style.MozUserSelect = selectable ? 'auto' : 'none';\n    elem.style.KhtmlUserSelect = selectable ? 'auto' : 'none';\n    elem.unselectable = selectable ? 'on' : 'off';\n  },\n  makeFullscreen: function makeFullscreen(elem, hor, vert) {\n    var vertical = vert;\n    var horizontal = hor;\n    if (Common.isUndefined(horizontal)) {\n      horizontal = true;\n    }\n    if (Common.isUndefined(vertical)) {\n      vertical = true;\n    }\n    elem.style.position = 'absolute';\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  fakeEvent: function fakeEvent(elem, eventType, pars, aux) {\n    var params = pars || {};\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        {\n          var clientX = params.x || params.clientX || 0;\n          var clientY = params.y || params.clientY || 0;\n          evt.initMouseEvent(eventType, params.bubbles || false, params.cancelable || true, window, params.clickCount || 1, 0,\n          0,\n          clientX,\n          clientY,\n          false, false, false, false, 0, null);\n          break;\n        }\n      case 'KeyboardEvents':\n        {\n          var init = evt.initKeyboardEvent || evt.initKeyEvent;\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, params.cancelable, window, params.ctrlKey, params.altKey, params.shiftKey, params.metaKey, params.keyCode, params.charCode);\n          break;\n        }\n      default:\n        {\n          evt.initEvent(eventType, params.bubbles || false, params.cancelable || true);\n          break;\n        }\n    }\n    Common.defaults(evt, aux);\n    elem.dispatchEvent(evt);\n  },\n  bind: function bind(elem, event, func, newBool) {\n    var bool = newBool || false;\n    if (elem.addEventListener) {\n      elem.addEventListener(event, func, bool);\n    } else if (elem.attachEvent) {\n      elem.attachEvent('on' + event, func);\n    }\n    return dom;\n  },\n  unbind: function unbind(elem, event, func, newBool) {\n    var bool = newBool || false;\n    if (elem.removeEventListener) {\n      elem.removeEventListener(event, func, bool);\n    } else if (elem.detachEvent) {\n      elem.detachEvent('on' + event, func);\n    }\n    return dom;\n  },\n  addClass: function addClass(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  removeClass: function removeClass(elem, className) {\n    if (className) {\n      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  hasClass: function hasClass(elem, className) {\n    return new RegExp('(?:^|\\\\s+)' + className + '(?:\\\\s+|$)').test(elem.className) || false;\n  },\n  getWidth: function getWidth(elem) {\n    var style = getComputedStyle(elem);\n    return cssValueToPixels(style['border-left-width']) + cssValueToPixels(style['border-right-width']) + cssValueToPixels(style['padding-left']) + cssValueToPixels(style['padding-right']) + cssValueToPixels(style.width);\n  },\n  getHeight: function getHeight(elem) {\n    var style = getComputedStyle(elem);\n    return cssValueToPixels(style['border-top-width']) + cssValueToPixels(style['border-bottom-width']) + cssValueToPixels(style['padding-top']) + cssValueToPixels(style['padding-bottom']) + cssValueToPixels(style.height);\n  },\n  getOffset: function getOffset(el) {\n    var elem = el;\n    var offset = { left: 0, top: 0 };\n    if (elem.offsetParent) {\n      do {\n        offset.left += elem.offsetLeft;\n        offset.top += elem.offsetTop;\n        elem = elem.offsetParent;\n      } while (elem);\n    }\n    return offset;\n  },\n  isActive: function isActive(elem) {\n    return elem === document.activeElement && (elem.type || elem.href);\n  }\n};\n\nvar BooleanController = function (_Controller) {\n  inherits(BooleanController, _Controller);\n  function BooleanController(object, property) {\n    classCallCheck(this, BooleanController);\n    var _this2 = possibleConstructorReturn(this, (BooleanController.__proto__ || Object.getPrototypeOf(BooleanController)).call(this, object, property));\n    var _this = _this2;\n    _this2.__prev = _this2.getValue();\n    _this2.__checkbox = document.createElement('input');\n    _this2.__checkbox.setAttribute('type', 'checkbox');\n    function onChange() {\n      _this.setValue(!_this.__prev);\n    }\n    dom.bind(_this2.__checkbox, 'change', onChange, false);\n    _this2.domElement.appendChild(_this2.__checkbox);\n    _this2.updateDisplay();\n    return _this2;\n  }\n  createClass(BooleanController, [{\n    key: 'setValue',\n    value: function setValue(v) {\n      var toReturn = get(BooleanController.prototype.__proto__ || Object.getPrototypeOf(BooleanController.prototype), 'setValue', this).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    key: 'updateDisplay',\n    value: function updateDisplay() {\n      if (this.getValue() === true) {\n        this.__checkbox.setAttribute('checked', 'checked');\n        this.__checkbox.checked = true;\n        this.__prev = true;\n      } else {\n        this.__checkbox.checked = false;\n        this.__prev = false;\n      }\n      return get(BooleanController.prototype.__proto__ || Object.getPrototypeOf(BooleanController.prototype), 'updateDisplay', this).call(this);\n    }\n  }]);\n  return BooleanController;\n}(Controller);\n\nvar OptionController = function (_Controller) {\n  inherits(OptionController, _Controller);\n  function OptionController(object, property, opts) {\n    classCallCheck(this, OptionController);\n    var _this2 = possibleConstructorReturn(this, (OptionController.__proto__ || Object.getPrototypeOf(OptionController)).call(this, object, property));\n    var options = opts;\n    var _this = _this2;\n    _this2.__select = document.createElement('select');\n    if (Common.isArray(options)) {\n      var map = {};\n      Common.each(options, function (element) {\n        map[element] = element;\n      });\n      options = map;\n    }\n    Common.each(options, function (value, key) {\n      var opt = document.createElement('option');\n      opt.innerHTML = key;\n      opt.setAttribute('value', value);\n      _this.__select.appendChild(opt);\n    });\n    _this2.updateDisplay();\n    dom.bind(_this2.__select, 'change', function () {\n      var desiredValue = this.options[this.selectedIndex].value;\n      _this.setValue(desiredValue);\n    });\n    _this2.domElement.appendChild(_this2.__select);\n    return _this2;\n  }\n  createClass(OptionController, [{\n    key: 'setValue',\n    value: function setValue(v) {\n      var toReturn = get(OptionController.prototype.__proto__ || Object.getPrototypeOf(OptionController.prototype), 'setValue', this).call(this, v);\n      if (this.__onFinishChange) {\n        this.__onFinishChange.call(this, this.getValue());\n      }\n      return toReturn;\n    }\n  }, {\n    key: 'updateDisplay',\n    value: function updateDisplay() {\n      if (dom.isActive(this.__select)) return this;\n      this.__select.value = this.getValue();\n      return get(OptionController.prototype.__proto__ || Object.getPrototypeOf(OptionController.prototype), 'updateDisplay', this).call(this);\n    }\n  }]);\n  return OptionController;\n}(Controller);\n\nvar StringController = function (_Controller) {\n  inherits(StringController, _Controller);\n  function StringController(object, property) {\n    classCallCheck(this, StringController);\n    var _this2 = possibleConstructorReturn(this, (StringController.__proto__ || Object.getPrototypeOf(StringController)).call(this, object, property));\n    var _this = _this2;\n    function onChange() {\n      _this.setValue(_this.__input.value);\n    }\n    function onBlur() {\n      if (_this.__onFinishChange) {\n        _this.__onFinishChange.call(_this, _this.getValue());\n      }\n    }\n    _this2.__input = document.createElement('input');\n    _this2.__input.setAttribute('type', 'text');\n    dom.bind(_this2.__input, 'keyup', onChange);\n    dom.bind(_this2.__input, 'change', onChange);\n    dom.bind(_this2.__input, 'blur', onBlur);\n    dom.bind(_this2.__input, 'keydown', function (e) {\n      if (e.keyCode === 13) {\n        this.blur();\n      }\n    });\n    _this2.updateDisplay();\n    _this2.domElement.appendChild(_this2.__input);\n    return _this2;\n  }\n  createClass(StringController, [{\n    key: 'updateDisplay',\n    value: function updateDisplay() {\n      if (!dom.isActive(this.__input)) {\n        this.__input.value = this.getValue();\n      }\n      return get(StringController.prototype.__proto__ || Object.getPrototypeOf(StringController.prototype), 'updateDisplay', this).call(this);\n    }\n  }]);\n  return StringController;\n}(Controller);\n\nfunction numDecimals(x) {\n  var _x = x.toString();\n  if (_x.indexOf('.') > -1) {\n    return _x.length - _x.indexOf('.') - 1;\n  }\n  return 0;\n}\nvar NumberController = function (_Controller) {\n  inherits(NumberController, _Controller);\n  function NumberController(object, property, params) {\n    classCallCheck(this, NumberController);\n    var _this = possibleConstructorReturn(this, (NumberController.__proto__ || Object.getPrototypeOf(NumberController)).call(this, object, property));\n    var _params = params || {};\n    _this.__min = _params.min;\n    _this.__max = _params.max;\n    _this.__step = _params.step;\n    if (Common.isUndefined(_this.__step)) {\n      if (_this.initialValue === 0) {\n        _this.__impliedStep = 1;\n      } else {\n        _this.__impliedStep = Math.pow(10, Math.floor(Math.log(Math.abs(_this.initialValue)) / Math.LN10)) / 10;\n      }\n    } else {\n      _this.__impliedStep = _this.__step;\n    }\n    _this.__precision = numDecimals(_this.__impliedStep);\n    return _this;\n  }\n  createClass(NumberController, [{\n    key: 'setValue',\n    value: function setValue(v) {\n      var _v = v;\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      if (this.__step !== undefined && _v % this.__step !== 0) {\n        _v = Math.round(_v / this.__step) * this.__step;\n      }\n      return get(NumberController.prototype.__proto__ || Object.getPrototypeOf(NumberController.prototype), 'setValue', this).call(this, _v);\n    }\n  }, {\n    key: 'min',\n    value: function min(minValue) {\n      this.__min = minValue;\n      return this;\n    }\n  }, {\n    key: 'max',\n    value: function max(maxValue) {\n      this.__max = maxValue;\n      return this;\n    }\n  }, {\n    key: 'step',\n    value: function step(stepValue) {\n      this.__step = stepValue;\n      this.__impliedStep = stepValue;\n      this.__precision = numDecimals(stepValue);\n      return this;\n    }\n  }]);\n  return NumberController;\n}(Controller);\n\nfunction roundToDecimal(value, decimals) {\n  var tenTo = Math.pow(10, decimals);\n  return Math.round(value * tenTo) / tenTo;\n}\nvar NumberControllerBox = function (_NumberController) {\n  inherits(NumberControllerBox, _NumberController);\n  function NumberControllerBox(object, property, params) {\n    classCallCheck(this, NumberControllerBox);\n    var _this2 = possibleConstructorReturn(this, (NumberControllerBox.__proto__ || Object.getPrototypeOf(NumberControllerBox)).call(this, object, property, params));\n    _this2.__truncationSuspended = false;\n    var _this = _this2;\n    var prevY = void 0;\n    function onChange() {\n      var attempted = parseFloat(_this.__input.value);\n      if (!Common.isNaN(attempted)) {\n        _this.setValue(attempted);\n      }\n    }\n    function onFinish() {\n      if (_this.__onFinishChange) {\n        _this.__onFinishChange.call(_this, _this.getValue());\n      }\n    }\n    function onBlur() {\n      onFinish();\n    }\n    function onMouseDrag(e) {\n      var diff = prevY - e.clientY;\n      _this.setValue(_this.getValue() + diff * _this.__impliedStep);\n      prevY = e.clientY;\n    }\n    function onMouseUp() {\n      dom.unbind(window, 'mousemove', onMouseDrag);\n      dom.unbind(window, 'mouseup', onMouseUp);\n      onFinish();\n    }\n    function onMouseDown(e) {\n      dom.bind(window, 'mousemove', onMouseDrag);\n      dom.bind(window, 'mouseup', onMouseUp);\n      prevY = e.clientY;\n    }\n    _this2.__input = document.createElement('input');\n    _this2.__input.setAttribute('type', 'text');\n    dom.bind(_this2.__input, 'change', onChange);\n    dom.bind(_this2.__input, 'blur', onBlur);\n    dom.bind(_this2.__input, 'mousedown', onMouseDown);\n    dom.bind(_this2.__input, 'keydown', function (e) {\n      if (e.keyCode === 13) {\n        _this.__truncationSuspended = true;\n        this.blur();\n        _this.__truncationSuspended = false;\n        onFinish();\n      }\n    });\n    _this2.updateDisplay();\n    _this2.domElement.appendChild(_this2.__input);\n    return _this2;\n  }\n  createClass(NumberControllerBox, [{\n    key: 'updateDisplay',\n    value: function updateDisplay() {\n      this.__input.value = this.__truncationSuspended ? this.getValue() : roundToDecimal(this.getValue(), this.__precision);\n      return get(NumberControllerBox.prototype.__proto__ || Object.getPrototypeOf(NumberControllerBox.prototype), 'updateDisplay', this).call(this);\n    }\n  }]);\n  return NumberControllerBox;\n}(NumberController);\n\nfunction map(v, i1, i2, o1, o2) {\n  return o1 + (o2 - o1) * ((v - i1) / (i2 - i1));\n}\nvar NumberControllerSlider = function (_NumberController) {\n  inherits(NumberControllerSlider, _NumberController);\n  function NumberControllerSlider(object, property, min, max, step) {\n    classCallCheck(this, NumberControllerSlider);\n    var _this2 = possibleConstructorReturn(this, (NumberControllerSlider.__proto__ || Object.getPrototypeOf(NumberControllerSlider)).call(this, object, property, { min: min, max: max, step: step }));\n    var _this = _this2;\n    _this2.__background = document.createElement('div');\n    _this2.__foreground = document.createElement('div');\n    dom.bind(_this2.__background, 'mousedown', onMouseDown);\n    dom.bind(_this2.__background, 'touchstart', onTouchStart);\n    dom.addClass(_this2.__background, 'slider');\n    dom.addClass(_this2.__foreground, 'slider-fg');\n    function onMouseDown(e) {\n      document.activeElement.blur();\n      dom.bind(window, 'mousemove', onMouseDrag);\n      dom.bind(window, 'mouseup', onMouseUp);\n      onMouseDrag(e);\n    }\n    function onMouseDrag(e) {\n      e.preventDefault();\n      var bgRect = _this.__background.getBoundingClientRect();\n      _this.setValue(map(e.clientX, bgRect.left, bgRect.right, _this.__min, _this.__max));\n      return false;\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    function onTouchStart(e) {\n      if (e.touches.length !== 1) {\n        return;\n      }\n      dom.bind(window, 'touchmove', onTouchMove);\n      dom.bind(window, 'touchend', onTouchEnd);\n      onTouchMove(e);\n    }\n    function onTouchMove(e) {\n      var clientX = e.touches[0].clientX;\n      var bgRect = _this.__background.getBoundingClientRect();\n      _this.setValue(map(clientX, bgRect.left, bgRect.right, _this.__min, _this.__max));\n    }\n    function onTouchEnd() {\n      dom.unbind(window, 'touchmove', onTouchMove);\n      dom.unbind(window, 'touchend', onTouchEnd);\n      if (_this.__onFinishChange) {\n        _this.__onFinishChange.call(_this, _this.getValue());\n      }\n    }\n    _this2.updateDisplay();\n    _this2.__background.appendChild(_this2.__foreground);\n    _this2.domElement.appendChild(_this2.__background);\n    return _this2;\n  }\n  createClass(NumberControllerSlider, [{\n    key: 'updateDisplay',\n    value: function updateDisplay() {\n      var pct = (this.getValue() - this.__min) / (this.__max - this.__min);\n      this.__foreground.style.width = pct * 100 + '%';\n      return get(NumberControllerSlider.prototype.__proto__ || Object.getPrototypeOf(NumberControllerSlider.prototype), 'updateDisplay', this).call(this);\n    }\n  }]);\n  return NumberControllerSlider;\n}(NumberController);\n\nvar FunctionController = function (_Controller) {\n  inherits(FunctionController, _Controller);\n  function FunctionController(object, property, text) {\n    classCallCheck(this, FunctionController);\n    var _this2 = possibleConstructorReturn(this, (FunctionController.__proto__ || Object.getPrototypeOf(FunctionController)).call(this, object, property));\n    var _this = _this2;\n    _this2.__button = document.createElement('div');\n    _this2.__button.innerHTML = text === undefined ? 'Fire' : text;\n    dom.bind(_this2.__button, 'click', function (e) {\n      e.preventDefault();\n      _this.fire();\n      return false;\n    });\n    dom.addClass(_this2.__button, 'button');\n    _this2.domElement.appendChild(_this2.__button);\n    return _this2;\n  }\n  createClass(FunctionController, [{\n    key: 'fire',\n    value: function fire() {\n      if (this.__onChange) {\n        this.__onChange.call(this);\n      }\n      this.getValue().call(this.object);\n      if (this.__onFinishChange) {\n        this.__onFinishChange.call(this, this.getValue());\n      }\n    }\n  }]);\n  return FunctionController;\n}(Controller);\n\nvar ColorController = function (_Controller) {\n  inherits(ColorController, _Controller);\n  function ColorController(object, property) {\n    classCallCheck(this, ColorController);\n    var _this2 = possibleConstructorReturn(this, (ColorController.__proto__ || Object.getPrototypeOf(ColorController)).call(this, object, property));\n    _this2.__color = new Color(_this2.getValue());\n    _this2.__temp = new Color(0);\n    var _this = _this2;\n    _this2.domElement = document.createElement('div');\n    dom.makeSelectable(_this2.domElement, false);\n    _this2.__selector = document.createElement('div');\n    _this2.__selector.className = 'selector';\n    _this2.__saturation_field = document.createElement('div');\n    _this2.__saturation_field.className = 'saturation-field';\n    _this2.__field_knob = document.createElement('div');\n    _this2.__field_knob.className = 'field-knob';\n    _this2.__field_knob_border = '2px solid ';\n    _this2.__hue_knob = document.createElement('div');\n    _this2.__hue_knob.className = 'hue-knob';\n    _this2.__hue_field = document.createElement('div');\n    _this2.__hue_field.className = 'hue-field';\n    _this2.__input = document.createElement('input');\n    _this2.__input.type = 'text';\n    _this2.__input_textShadow = '0 1px 1px ';\n    dom.bind(_this2.__input, 'keydown', function (e) {\n      if (e.keyCode === 13) {\n        onBlur.call(this);\n      }\n    });\n    dom.bind(_this2.__input, 'blur', onBlur);\n    dom.bind(_this2.__selector, 'mousedown', function () {\n      dom.addClass(this, 'drag').bind(window, 'mouseup', function () {\n        dom.removeClass(_this.__selector, 'drag');\n      });\n    });\n    dom.bind(_this2.__selector, 'touchstart', function () {\n      dom.addClass(this, 'drag').bind(window, 'touchend', function () {\n        dom.removeClass(_this.__selector, 'drag');\n      });\n    });\n    var valueField = document.createElement('div');\n    Common.extend(_this2.__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    Common.extend(_this2.__field_knob.style, {\n      position: 'absolute',\n      width: '12px',\n      height: '12px',\n      border: _this2.__field_knob_border + (_this2.__color.v < 0.5 ? '#fff' : '#000'),\n      boxShadow: '0px 1px 3px rgba(0,0,0,0.5)',\n      borderRadius: '12px',\n      zIndex: 1\n    });\n    Common.extend(_this2.__hue_knob.style, {\n      position: 'absolute',\n      width: '15px',\n      height: '2px',\n      borderRight: '4px solid #fff',\n      zIndex: 1\n    });\n    Common.extend(_this2.__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    Common.extend(valueField.style, {\n      width: '100%',\n      height: '100%',\n      background: 'none'\n    });\n    linearGradient(valueField, 'top', 'rgba(0,0,0,0)', '#000');\n    Common.extend(_this2.__hue_field.style, {\n      width: '15px',\n      height: '100px',\n      border: '1px solid #555',\n      cursor: 'ns-resize',\n      position: 'absolute',\n      top: '3px',\n      right: '3px'\n    });\n    hueGradient(_this2.__hue_field);\n    Common.extend(_this2.__input.style, {\n      outline: 'none',\n      textAlign: 'center',\n      color: '#fff',\n      border: 0,\n      fontWeight: 'bold',\n      textShadow: _this2.__input_textShadow + 'rgba(0,0,0,0.7)'\n    });\n    dom.bind(_this2.__saturation_field, 'mousedown', fieldDown);\n    dom.bind(_this2.__saturation_field, 'touchstart', fieldDown);\n    dom.bind(_this2.__field_knob, 'mousedown', fieldDown);\n    dom.bind(_this2.__field_knob, 'touchstart', fieldDown);\n    dom.bind(_this2.__hue_field, 'mousedown', fieldDownH);\n    dom.bind(_this2.__hue_field, 'touchstart', fieldDownH);\n    function fieldDown(e) {\n      setSV(e);\n      dom.bind(window, 'mousemove', setSV);\n      dom.bind(window, 'touchmove', setSV);\n      dom.bind(window, 'mouseup', fieldUpSV);\n      dom.bind(window, 'touchend', fieldUpSV);\n    }\n    function fieldDownH(e) {\n      setH(e);\n      dom.bind(window, 'mousemove', setH);\n      dom.bind(window, 'touchmove', setH);\n      dom.bind(window, 'mouseup', fieldUpH);\n      dom.bind(window, 'touchend', fieldUpH);\n    }\n    function fieldUpSV() {\n      dom.unbind(window, 'mousemove', setSV);\n      dom.unbind(window, 'touchmove', setSV);\n      dom.unbind(window, 'mouseup', fieldUpSV);\n      dom.unbind(window, 'touchend', fieldUpSV);\n      onFinish();\n    }\n    function fieldUpH() {\n      dom.unbind(window, 'mousemove', setH);\n      dom.unbind(window, 'touchmove', setH);\n      dom.unbind(window, 'mouseup', fieldUpH);\n      dom.unbind(window, 'touchend', fieldUpH);\n      onFinish();\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    function onFinish() {\n      if (_this.__onFinishChange) {\n        _this.__onFinishChange.call(_this, _this.__color.toOriginal());\n      }\n    }\n    _this2.__saturation_field.appendChild(valueField);\n    _this2.__selector.appendChild(_this2.__field_knob);\n    _this2.__selector.appendChild(_this2.__saturation_field);\n    _this2.__selector.appendChild(_this2.__hue_field);\n    _this2.__hue_field.appendChild(_this2.__hue_knob);\n    _this2.domElement.appendChild(_this2.__input);\n    _this2.domElement.appendChild(_this2.__selector);\n    _this2.updateDisplay();\n    function setSV(e) {\n      if (e.type.indexOf('touch') === -1) {\n        e.preventDefault();\n      }\n      var fieldRect = _this.__saturation_field.getBoundingClientRect();\n      var _ref = e.touches && e.touches[0] || e,\n          clientX = _ref.clientX,\n          clientY = _ref.clientY;\n      var s = (clientX - fieldRect.left) / (fieldRect.right - fieldRect.left);\n      var v = 1 - (clientY - fieldRect.top) / (fieldRect.bottom - fieldRect.top);\n      if (v > 1) {\n        v = 1;\n      } else if (v < 0) {\n        v = 0;\n      }\n      if (s > 1) {\n        s = 1;\n      } else if (s < 0) {\n        s = 0;\n      }\n      _this.__color.v = v;\n      _this.__color.s = s;\n      _this.setValue(_this.__color.toOriginal());\n      return false;\n    }\n    function setH(e) {\n      if (e.type.indexOf('touch') === -1) {\n        e.preventDefault();\n      }\n      var fieldRect = _this.__hue_field.getBoundingClientRect();\n      var _ref2 = e.touches && e.touches[0] || e,\n          clientY = _ref2.clientY;\n      var h = 1 - (clientY - fieldRect.top) / (fieldRect.bottom - fieldRect.top);\n      if (h > 1) {\n        h = 1;\n      } else if (h < 0) {\n        h = 0;\n      }\n      _this.__color.h = h * 360;\n      _this.setValue(_this.__color.toOriginal());\n      return false;\n    }\n    return _this2;\n  }\n  createClass(ColorController, [{\n    key: 'updateDisplay',\n    value: function updateDisplay() {\n      var i = interpret(this.getValue());\n      if (i !== false) {\n        var mismatch = false;\n        Common.each(Color.COMPONENTS, function (component) {\n          if (!Common.isUndefined(i[component]) && !Common.isUndefined(this.__color.__state[component]) && i[component] !== this.__color.__state[component]) {\n            mismatch = true;\n            return {};\n          }\n        }, this);\n        if (mismatch) {\n          Common.extend(this.__color.__state, i);\n        }\n      }\n      Common.extend(this.__temp.__state, this.__color.__state);\n      this.__temp.a = 1;\n      var flip = this.__color.v < 0.5 || this.__color.s > 0.5 ? 255 : 0;\n      var _flip = 255 - flip;\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.toHexString(),\n        border: this.__field_knob_border + 'rgb(' + flip + ',' + flip + ',' + flip + ')'\n      });\n      this.__hue_knob.style.marginTop = (1 - this.__color.h / 360) * 100 + 'px';\n      this.__temp.s = 1;\n      this.__temp.v = 1;\n      linearGradient(this.__saturation_field, 'left', '#fff', this.__temp.toHexString());\n      this.__input.value = this.__color.toString();\n      Common.extend(this.__input.style, {\n        backgroundColor: this.__color.toHexString(),\n        color: 'rgb(' + flip + ',' + flip + ',' + flip + ')',\n        textShadow: this.__input_textShadow + 'rgba(' + _flip + ',' + _flip + ',' + _flip + ',.7)'\n      });\n    }\n  }]);\n  return ColorController;\n}(Controller);\nvar vendors = ['-moz-', '-o-', '-webkit-', '-ms-', ''];\nfunction 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}\nfunction 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\nvar css = {\n  load: function load(url, indoc) {\n    var doc = indoc || 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 inject(cssContent, indoc) {\n    var doc = indoc || document;\n    var injected = document.createElement('style');\n    injected.type = 'text/css';\n    injected.innerHTML = cssContent;\n    var head = doc.getElementsByTagName('head')[0];\n    try {\n      head.appendChild(injected);\n    } catch (e) {\n    }\n  }\n};\n\nvar saveDialogContents = \"<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\nvar ControllerFactory = function ControllerFactory(object, property) {\n  var initialValue = object[property];\n  if (Common.isArray(arguments[2]) || Common.isObject(arguments[2])) {\n    return new OptionController(object, property, arguments[2]);\n  }\n  if (Common.isNumber(initialValue)) {\n    if (Common.isNumber(arguments[2]) && Common.isNumber(arguments[3])) {\n      if (Common.isNumber(arguments[4])) {\n        return new NumberControllerSlider(object, property, arguments[2], arguments[3], arguments[4]);\n      }\n      return new NumberControllerSlider(object, property, arguments[2], arguments[3]);\n    }\n    if (Common.isNumber(arguments[4])) {\n      return new NumberControllerBox(object, property, { min: arguments[2], max: arguments[3], step: arguments[4] });\n    }\n    return new NumberControllerBox(object, property, { min: arguments[2], max: arguments[3] });\n  }\n  if (Common.isString(initialValue)) {\n    return new StringController(object, property);\n  }\n  if (Common.isFunction(initialValue)) {\n    return new FunctionController(object, property, '');\n  }\n  if (Common.isBoolean(initialValue)) {\n    return new BooleanController(object, property);\n  }\n  return null;\n};\n\nfunction requestAnimationFrame(callback) {\n  setTimeout(callback, 1000 / 60);\n}\nvar requestAnimationFrame$1 = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || requestAnimationFrame;\n\nvar CenteredDiv = function () {\n  function CenteredDiv() {\n    classCallCheck(this, CenteredDiv);\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      transition: 'opacity 0.2s linear'\n    });\n    dom.makeFullscreen(this.backgroundElement);\n    this.backgroundElement.style.position = 'fixed';\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      transition: 'transform 0.2s ease-out, opacity 0.2s linear'\n    });\n    document.body.appendChild(this.backgroundElement);\n    document.body.appendChild(this.domElement);\n    var _this = this;\n    dom.bind(this.backgroundElement, 'click', function () {\n      _this.hide();\n    });\n  }\n  createClass(CenteredDiv, [{\n    key: 'show',\n    value: function show() {\n      var _this = this;\n      this.backgroundElement.style.display = 'block';\n      this.domElement.style.display = 'block';\n      this.domElement.style.opacity = 0;\n      this.domElement.style.webkitTransform = 'scale(1.1)';\n      this.layout();\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    key: 'hide',\n    value: function hide() {\n      var _this = this;\n      var hide = function hide() {\n        _this.domElement.style.display = 'none';\n        _this.backgroundElement.style.display = 'none';\n        dom.unbind(_this.domElement, 'webkitTransitionEnd', hide);\n        dom.unbind(_this.domElement, 'transitionend', hide);\n        dom.unbind(_this.domElement, 'oTransitionEnd', hide);\n      };\n      dom.bind(this.domElement, 'webkitTransitionEnd', hide);\n      dom.bind(this.domElement, 'transitionend', hide);\n      dom.bind(this.domElement, 'oTransitionEnd', hide);\n      this.backgroundElement.style.opacity = 0;\n      this.domElement.style.opacity = 0;\n      this.domElement.style.webkitTransform = 'scale(1.1)';\n    }\n  }, {\n    key: 'layout',\n    value: function layout() {\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  return CenteredDiv;\n}();\n\nvar styleSheet = ___$insertStyle(\".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 .1s linear;-o-transition:opacity .1s linear;-moz-transition:opacity .1s linear;transition:opacity .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 .1s linear;-o-transition:opacity .1s linear;-moz-transition:opacity .1s linear;transition:opacity .1s linear;border:0;line-height:19px;height:20px;cursor:pointer;text-align:center;background-color:#000}.dg.main .close-button.close-top{position:relative}.dg.main .close-button.close-bottom{position:absolute}.dg.main .close-button:hover{background-color:#111}.dg.a{float:right;margin-right:15px;overflow-y:visible}.dg.a.has-save>ul.close-top{margin-top:0}.dg.a.has-save>ul.close-bottom{margin-top:27px}.dg.a.has-save>ul.closed{margin-top:0}.dg.a .save-row{top:0;z-index:1002}.dg.a .save-row.close-top{position:relative}.dg.a .save-row.close-bottom{position:fixed}.dg li{-webkit-transition:height .1s ease-out;-o-transition:height .1s ease-out;-moz-transition:height .1s ease-out;transition:height .1s ease-out;-webkit-transition:overflow .1s linear;-o-transition:overflow .1s linear;-moz-transition:overflow .1s linear;transition:overflow .1s linear}.dg li:not(.folder){cursor:auto;height:27px;line-height:27px;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;overflow:hidden}.dg .property-name{cursor:default;float:left;clear:left;width:40%;overflow:hidden;text-overflow:ellipsis}.dg .cr.function .property-name{width:100%}.dg .c{float:left;width:60%;position:relative}.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:7px}.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 .cr.color{overflow:visible}.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.color{border-left:3px solid}.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;max-width:100%}.dg .c .slider:hover{background:#3c3c3c}.dg .c .slider:hover .slider-fg{background:#44abda}\\n\");\n\ncss.inject(styleSheet);\nvar CSS_NAMESPACE = 'dg';\nvar HIDE_KEY_CODE = 72;\nvar CLOSE_BUTTON_HEIGHT = 20;\nvar DEFAULT_DEFAULT_PRESET_NAME = 'Default';\nvar SUPPORTS_LOCAL_STORAGE = function () {\n  try {\n    return !!window.localStorage;\n  } catch (e) {\n    return false;\n  }\n}();\nvar SAVE_DIALOGUE = void 0;\nvar autoPlaceVirgin = true;\nvar autoPlaceContainer = void 0;\nvar hide = false;\nvar hideableGuis = [];\nvar GUI = function GUI(pars) {\n  var _this = this;\n  var params = pars || {};\n  this.domElement = document.createElement('div');\n  this.__ul = document.createElement('ul');\n  this.domElement.appendChild(this.__ul);\n  dom.addClass(this.domElement, CSS_NAMESPACE);\n  this.__folders = {};\n  this.__controllers = [];\n  this.__rememberedObjects = [];\n  this.__rememberedObjectIndecesToControllers = [];\n  this.__listening = [];\n  params = Common.defaults(params, {\n    closeOnTop: false,\n    autoPlace: true,\n    width: GUI.DEFAULT_WIDTH\n  });\n  params = Common.defaults(params, {\n    resizable: params.autoPlace,\n    hideable: params.autoPlace\n  });\n  if (!Common.isUndefined(params.load)) {\n    if (params.preset) {\n      params.load.preset = params.preset;\n    }\n  } else {\n    params.load = { preset: DEFAULT_DEFAULT_PRESET_NAME };\n  }\n  if (Common.isUndefined(params.parent) && params.hideable) {\n    hideableGuis.push(this);\n  }\n  params.resizable = Common.isUndefined(params.parent) && params.resizable;\n  if (params.autoPlace && Common.isUndefined(params.scrollable)) {\n    params.scrollable = true;\n  }\n  var useLocalStorage = SUPPORTS_LOCAL_STORAGE && localStorage.getItem(getLocalStorageHash(this, 'isLocal')) === 'true';\n  var saveToLocalStorage = void 0;\n  var titleRow = void 0;\n  Object.defineProperties(this,\n  {\n    parent: {\n      get: function get$$1() {\n        return params.parent;\n      }\n    },\n    scrollable: {\n      get: function get$$1() {\n        return params.scrollable;\n      }\n    },\n    autoPlace: {\n      get: function get$$1() {\n        return params.autoPlace;\n      }\n    },\n    closeOnTop: {\n      get: function get$$1() {\n        return params.closeOnTop;\n      }\n    },\n    preset: {\n      get: function get$$1() {\n        if (_this.parent) {\n          return _this.getRoot().preset;\n        }\n        return params.load.preset;\n      },\n      set: function set$$1(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    width: {\n      get: function get$$1() {\n        return params.width;\n      },\n      set: function set$$1(v) {\n        params.width = v;\n        setWidth(_this, v);\n      }\n    },\n    name: {\n      get: function get$$1() {\n        return params.name;\n      },\n      set: function set$$1(v) {\n        params.name = v;\n        if (titleRow) {\n          titleRow.innerHTML = params.name;\n        }\n      }\n    },\n    closed: {\n      get: function get$$1() {\n        return params.closed;\n      },\n      set: function set$$1(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        this.onResize();\n        if (_this.__closeButton) {\n          _this.__closeButton.innerHTML = v ? GUI.TEXT_OPEN : GUI.TEXT_CLOSED;\n        }\n      }\n    },\n    load: {\n      get: function get$$1() {\n        return params.load;\n      }\n    },\n    useLocalStorage: {\n      get: function get$$1() {\n        return useLocalStorage;\n      },\n      set: function set$$1(bool) {\n        if (SUPPORTS_LOCAL_STORAGE) {\n          useLocalStorage = 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  if (Common.isUndefined(params.parent)) {\n    this.closed = params.closed || false;\n    dom.addClass(this.domElement, GUI.CLASS_MAIN);\n    dom.makeSelectable(this.domElement, false);\n    if (SUPPORTS_LOCAL_STORAGE) {\n      if (useLocalStorage) {\n        _this.useLocalStorage = true;\n        var savedGui = localStorage.getItem(getLocalStorageHash(this, 'gui'));\n        if (savedGui) {\n          params.load = JSON.parse(savedGui);\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    if (params.closeOnTop) {\n      dom.addClass(this.__closeButton, GUI.CLASS_CLOSE_TOP);\n      this.domElement.insertBefore(this.__closeButton, this.domElement.childNodes[0]);\n    } else {\n      dom.addClass(this.__closeButton, GUI.CLASS_CLOSE_BOTTOM);\n      this.domElement.appendChild(this.__closeButton);\n    }\n    dom.bind(this.__closeButton, 'click', function () {\n      _this.closed = !_this.closed;\n    });\n  } else {\n    if (params.closed === undefined) {\n      params.closed = true;\n    }\n    var titleRowName = document.createTextNode(params.name);\n    dom.addClass(titleRowName, 'controller-name');\n    titleRow = addRow(_this, titleRowName);\n    var onClickTitle = function onClickTitle(e) {\n      e.preventDefault();\n      _this.closed = !_this.closed;\n      return false;\n    };\n    dom.addClass(this.__ul, GUI.CLASS_CLOSED);\n    dom.addClass(titleRow, 'title');\n    dom.bind(titleRow, 'click', onClickTitle);\n    if (!params.closed) {\n      this.closed = false;\n    }\n  }\n  if (params.autoPlace) {\n    if (Common.isUndefined(params.parent)) {\n      if (autoPlaceVirgin) {\n        autoPlaceContainer = document.createElement('div');\n        dom.addClass(autoPlaceContainer, CSS_NAMESPACE);\n        dom.addClass(autoPlaceContainer, GUI.CLASS_AUTO_PLACE_CONTAINER);\n        document.body.appendChild(autoPlaceContainer);\n        autoPlaceVirgin = false;\n      }\n      autoPlaceContainer.appendChild(this.domElement);\n      dom.addClass(this.domElement, GUI.CLASS_AUTO_PLACE);\n    }\n    if (!this.parent) {\n      setWidth(_this, params.width);\n    }\n  }\n  this.__resizeHandler = function () {\n    _this.onResizeDebounced();\n  };\n  dom.bind(window, 'resize', this.__resizeHandler);\n  dom.bind(this.__ul, 'webkitTransitionEnd', this.__resizeHandler);\n  dom.bind(this.__ul, 'transitionend', this.__resizeHandler);\n  dom.bind(this.__ul, 'oTransitionEnd', this.__resizeHandler);\n  this.onResize();\n  if (params.resizable) {\n    addResizeHandle(this);\n  }\n  saveToLocalStorage = function saveToLocalStorage() {\n    if (SUPPORTS_LOCAL_STORAGE && localStorage.getItem(getLocalStorageHash(_this, 'isLocal')) === 'true') {\n      localStorage.setItem(getLocalStorageHash(_this, 'gui'), JSON.stringify(_this.getSaveObject()));\n    }\n  };\n  this.saveToLocalStorageIfPossible = saveToLocalStorage;\n  function resetWidth() {\n    var root = _this.getRoot();\n    root.width += 1;\n    Common.defer(function () {\n      root.width -= 1;\n    });\n  }\n  if (!params.parent) {\n    resetWidth();\n  }\n};\nGUI.toggleHide = function () {\n  hide = !hide;\n  Common.each(hideableGuis, function (gui) {\n    gui.domElement.style.display = hide ? 'none' : '';\n  });\n};\nGUI.CLASS_AUTO_PLACE = 'a';\nGUI.CLASS_AUTO_PLACE_CONTAINER = 'ac';\nGUI.CLASS_MAIN = 'main';\nGUI.CLASS_CONTROLLER_ROW = 'cr';\nGUI.CLASS_TOO_TALL = 'taller-than-window';\nGUI.CLASS_CLOSED = 'closed';\nGUI.CLASS_CLOSE_BUTTON = 'close-button';\nGUI.CLASS_CLOSE_TOP = 'close-top';\nGUI.CLASS_CLOSE_BOTTOM = 'close-bottom';\nGUI.CLASS_DRAG = 'drag';\nGUI.DEFAULT_WIDTH = 245;\nGUI.TEXT_CLOSED = 'Close Controls';\nGUI.TEXT_OPEN = 'Open Controls';\nGUI._keydownHandler = function (e) {\n  if (document.activeElement.type !== 'text' && (e.which === HIDE_KEY_CODE || e.keyCode === HIDE_KEY_CODE)) {\n    GUI.toggleHide();\n  }\n};\ndom.bind(window, 'keydown', GUI._keydownHandler, false);\nCommon.extend(GUI.prototype,\n{\n  add: function add(object, property) {\n    return _add(this, object, property, {\n      factoryArgs: Array.prototype.slice.call(arguments, 2)\n    });\n  },\n  addColor: function addColor(object, property) {\n    return _add(this, object, property, {\n      color: true\n    });\n  },\n  remove: function remove(controller) {\n    this.__ul.removeChild(controller.__li);\n    this.__controllers.splice(this.__controllers.indexOf(controller), 1);\n    var _this = this;\n    Common.defer(function () {\n      _this.onResize();\n    });\n  },\n  destroy: function destroy() {\n    if (this.parent) {\n      throw new Error('Only the root GUI should be removed with .destroy(). ' + 'For subfolders, use gui.removeFolder(folder) instead.');\n    }\n    if (this.autoPlace) {\n      autoPlaceContainer.removeChild(this.domElement);\n    }\n    var _this = this;\n    Common.each(this.__folders, function (subfolder) {\n      _this.removeFolder(subfolder);\n    });\n    dom.unbind(window, 'keydown', GUI._keydownHandler, false);\n    removeListeners(this);\n  },\n  addFolder: function addFolder(name) {\n    if (this.__folders[name] !== undefined) {\n      throw new Error('You already have a folder in this GUI by the' + ' name \"' + name + '\"');\n    }\n    var newGuiParams = { name: name, parent: this };\n    newGuiParams.autoPlace = this.autoPlace;\n    if (this.load &&\n    this.load.folders &&\n    this.load.folders[name]) {\n      newGuiParams.closed = this.load.folders[name].closed;\n      newGuiParams.load = this.load.folders[name];\n    }\n    var gui = new GUI(newGuiParams);\n    this.__folders[name] = gui;\n    var li = addRow(this, gui.domElement);\n    dom.addClass(li, 'folder');\n    return gui;\n  },\n  removeFolder: function removeFolder(folder) {\n    this.__ul.removeChild(folder.domElement.parentElement);\n    delete this.__folders[folder.name];\n    if (this.load &&\n    this.load.folders &&\n    this.load.folders[folder.name]) {\n      delete this.load.folders[folder.name];\n    }\n    removeListeners(folder);\n    var _this = this;\n    Common.each(folder.__folders, function (subfolder) {\n      folder.removeFolder(subfolder);\n    });\n    Common.defer(function () {\n      _this.onResize();\n    });\n  },\n  open: function open() {\n    this.closed = false;\n  },\n  close: function close() {\n    this.closed = true;\n  },\n  hide: function hide() {\n    this.domElement.style.display = 'none';\n  },\n  show: function show() {\n    this.domElement.style.display = '';\n  },\n  onResize: function onResize() {\n    var root = this.getRoot();\n    if (root.scrollable) {\n      var top = dom.getOffset(root.__ul).top;\n      var h = 0;\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    if (root.__resize_handle) {\n      Common.defer(function () {\n        root.__resize_handle.style.height = root.__ul.offsetHeight + 'px';\n      });\n    }\n    if (root.__closeButton) {\n      root.__closeButton.style.width = root.width + 'px';\n    }\n  },\n  onResizeDebounced: Common.debounce(function () {\n    this.onResize();\n  }, 50),\n  remember: function remember() {\n    if (Common.isUndefined(SAVE_DIALOGUE)) {\n      SAVE_DIALOGUE = new CenteredDiv();\n      SAVE_DIALOGUE.domElement.innerHTML = saveDialogContents;\n    }\n    if (this.parent) {\n      throw new Error('You can only call remember on a top level GUI.');\n    }\n    var _this = this;\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    if (this.autoPlace) {\n      setWidth(this, this.width);\n    }\n  },\n  getRoot: function getRoot() {\n    var gui = this;\n    while (gui.parent) {\n      gui = gui.parent;\n    }\n    return gui;\n  },\n  getSaveObject: function getSaveObject() {\n    var toReturn = this.load;\n    toReturn.closed = this.closed;\n    if (this.__rememberedObjects.length > 0) {\n      toReturn.preset = this.preset;\n      if (!toReturn.remembered) {\n        toReturn.remembered = {};\n      }\n      toReturn.remembered[this.preset] = getCurrentPreset(this);\n    }\n    toReturn.folders = {};\n    Common.each(this.__folders, function (element, key) {\n      toReturn.folders[key] = element.getSaveObject();\n    });\n    return toReturn;\n  },\n  save: function save() {\n    if (!this.load.remembered) {\n      this.load.remembered = {};\n    }\n    this.load.remembered[this.preset] = getCurrentPreset(this);\n    markPresetModified(this, false);\n    this.saveToLocalStorageIfPossible();\n  },\n  saveAs: function saveAs(presetName) {\n    if (!this.load.remembered) {\n      this.load.remembered = {};\n      this.load.remembered[DEFAULT_DEFAULT_PRESET_NAME] = getCurrentPreset(this, true);\n    }\n    this.load.remembered[presetName] = getCurrentPreset(this);\n    this.preset = presetName;\n    addPresetOption(this, presetName, true);\n    this.saveToLocalStorageIfPossible();\n  },\n  revert: function revert(gui) {\n    Common.each(this.__controllers, function (controller) {\n      if (!this.getRoot().load.remembered) {\n        controller.setValue(controller.initialValue);\n      } else {\n        recallSavedValue(gui || this.getRoot(), controller);\n      }\n      if (controller.__onFinishChange) {\n        controller.__onFinishChange.call(controller, controller.getValue());\n      }\n    }, this);\n    Common.each(this.__folders, function (folder) {\n      folder.revert(folder);\n    });\n    if (!gui) {\n      markPresetModified(this.getRoot(), false);\n    }\n  },\n  listen: function listen(controller) {\n    var init = this.__listening.length === 0;\n    this.__listening.push(controller);\n    if (init) {\n      updateDisplays(this.__listening);\n    }\n  },\n  updateDisplay: function updateDisplay() {\n    Common.each(this.__controllers, function (controller) {\n      controller.updateDisplay();\n    });\n    Common.each(this.__folders, function (folder) {\n      folder.updateDisplay();\n    });\n  }\n});\nfunction addRow(gui, newDom, liBefore) {\n  var li = document.createElement('li');\n  if (newDom) {\n    li.appendChild(newDom);\n  }\n  if (liBefore) {\n    gui.__ul.insertBefore(li, liBefore);\n  } else {\n    gui.__ul.appendChild(li);\n  }\n  gui.onResize();\n  return li;\n}\nfunction removeListeners(gui) {\n  dom.unbind(window, 'resize', gui.__resizeHandler);\n  if (gui.saveToLocalStorageIfPossible) {\n    dom.unbind(window, 'unload', gui.saveToLocalStorageIfPossible);\n  }\n}\nfunction markPresetModified(gui, modified) {\n  var opt = gui.__preset_select[gui.__preset_select.selectedIndex];\n  if (modified) {\n    opt.innerHTML = opt.value + '*';\n  } else {\n    opt.innerHTML = opt.value;\n  }\n}\nfunction augmentController(gui, li, controller) {\n  controller.__li = li;\n  controller.__gui = gui;\n  Common.extend(controller, {\n    options: function options(_options) {\n      if (arguments.length > 1) {\n        var nextSibling = controller.__li.nextElementSibling;\n        controller.remove();\n        return _add(gui, controller.object, controller.property, {\n          before: nextSibling,\n          factoryArgs: [Common.toArray(arguments)]\n        });\n      }\n      if (Common.isArray(_options) || Common.isObject(_options)) {\n        var _nextSibling = controller.__li.nextElementSibling;\n        controller.remove();\n        return _add(gui, controller.object, controller.property, {\n          before: _nextSibling,\n          factoryArgs: [_options]\n        });\n      }\n    },\n    name: function name(_name) {\n      controller.__li.firstElementChild.firstElementChild.innerHTML = _name;\n      return controller;\n    },\n    listen: function listen() {\n      controller.__gui.listen(controller);\n      return controller;\n    },\n    remove: function remove() {\n      controller.__gui.remove(controller);\n      return controller;\n    }\n  });\n  if (controller instanceof NumberControllerSlider) {\n    var box = new NumberControllerBox(controller.object, controller.property, { min: controller.__min, max: controller.__max, step: controller.__step });\n    Common.each(['updateDisplay', 'onChange', 'onFinishChange', 'step', 'min', 'max'], 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        pb.apply(box, args);\n        return pc.apply(controller, args);\n      };\n    });\n    dom.addClass(li, 'has-slider');\n    controller.domElement.insertBefore(box.domElement, controller.domElement.firstElementChild);\n  } else if (controller instanceof NumberControllerBox) {\n    var r = function r(returned) {\n      if (Common.isNumber(controller.__min) && Common.isNumber(controller.__max)) {\n        var oldName = controller.__li.firstElementChild.firstElementChild.innerHTML;\n        var wasListening = controller.__gui.__listening.indexOf(controller) > -1;\n        controller.remove();\n        var newController = _add(gui, controller.object, controller.property, {\n          before: controller.__li.nextElementSibling,\n          factoryArgs: [controller.__min, controller.__max, controller.__step]\n        });\n        newController.name(oldName);\n        if (wasListening) newController.listen();\n        return newController;\n      }\n      return returned;\n    };\n    controller.min = Common.compose(r, controller.min);\n    controller.max = Common.compose(r, controller.max);\n  } else if (controller instanceof BooleanController) {\n    dom.bind(li, 'click', function () {\n      dom.fakeEvent(controller.__checkbox, 'click');\n    });\n    dom.bind(controller.__checkbox, 'click', function (e) {\n      e.stopPropagation();\n    });\n  } else if (controller instanceof FunctionController) {\n    dom.bind(li, 'click', function () {\n      dom.fakeEvent(controller.__button, 'click');\n    });\n    dom.bind(li, 'mouseover', function () {\n      dom.addClass(controller.__button, 'hover');\n    });\n    dom.bind(li, 'mouseout', function () {\n      dom.removeClass(controller.__button, 'hover');\n    });\n  } else if (controller instanceof ColorController) {\n    dom.addClass(li, 'color');\n    controller.updateDisplay = Common.compose(function (val) {\n      li.style.borderLeftColor = controller.__color.toString();\n      return val;\n    }, controller.updateDisplay);\n    controller.updateDisplay();\n  }\n  controller.setValue = Common.compose(function (val) {\n    if (gui.getRoot().__preset_select && controller.isModified()) {\n      markPresetModified(gui.getRoot(), true);\n    }\n    return val;\n  }, controller.setValue);\n}\nfunction recallSavedValue(gui, controller) {\n  var root = gui.getRoot();\n  var matchedIndex = root.__rememberedObjects.indexOf(controller.object);\n  if (matchedIndex !== -1) {\n    var controllerMap = root.__rememberedObjectIndecesToControllers[matchedIndex];\n    if (controllerMap === undefined) {\n      controllerMap = {};\n      root.__rememberedObjectIndecesToControllers[matchedIndex] = controllerMap;\n    }\n    controllerMap[controller.property] = controller;\n    if (root.load && root.load.remembered) {\n      var presetMap = root.load.remembered;\n      var preset = void 0;\n      if (presetMap[gui.preset]) {\n        preset = presetMap[gui.preset];\n      } else if (presetMap[DEFAULT_DEFAULT_PRESET_NAME]) {\n        preset = presetMap[DEFAULT_DEFAULT_PRESET_NAME];\n      } else {\n        return;\n      }\n      if (preset[matchedIndex] && preset[matchedIndex][controller.property] !== undefined) {\n        var value = preset[matchedIndex][controller.property];\n        controller.initialValue = value;\n        controller.setValue(value);\n      }\n    }\n  }\n}\nfunction _add(gui, object, property, params) {\n  if (object[property] === undefined) {\n    throw new Error('Object \"' + object + '\" has no property \"' + property + '\"');\n  }\n  var controller = void 0;\n  if (params.color) {\n    controller = new ColorController(object, property);\n  } else {\n    var factoryArgs = [object, property].concat(params.factoryArgs);\n    controller = ControllerFactory.apply(gui, factoryArgs);\n  }\n  if (params.before instanceof Controller) {\n    params.before = params.before.__li;\n  }\n  recallSavedValue(gui, controller);\n  dom.addClass(controller.domElement, 'c');\n  var name = document.createElement('span');\n  dom.addClass(name, 'property-name');\n  name.innerHTML = controller.property;\n  var container = document.createElement('div');\n  container.appendChild(name);\n  container.appendChild(controller.domElement);\n  var li = addRow(gui, container, params.before);\n  dom.addClass(li, GUI.CLASS_CONTROLLER_ROW);\n  if (controller instanceof ColorController) {\n    dom.addClass(li, 'color');\n  } else {\n    dom.addClass(li, _typeof(controller.getValue()));\n  }\n  augmentController(gui, li, controller);\n  gui.__controllers.push(controller);\n  return controller;\n}\nfunction getLocalStorageHash(gui, key) {\n  return document.location.href + '.' + key;\n}\nfunction 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}\nfunction showHideExplain(gui, explain) {\n  explain.style.display = gui.useLocalStorage ? 'block' : 'none';\n}\nfunction addSaveMenu(gui) {\n  var div = gui.__save_row = document.createElement('li');\n  dom.addClass(gui.domElement, 'has-save');\n  gui.__ul.insertBefore(div, gui.__ul.firstChild);\n  dom.addClass(div, 'save-row');\n  var gears = document.createElement('span');\n  gears.innerHTML = '&nbsp;';\n  dom.addClass(gears, 'button gears');\n  var button = document.createElement('span');\n  button.innerHTML = 'Save';\n  dom.addClass(button, 'button');\n  dom.addClass(button, 'save');\n  var button2 = document.createElement('span');\n  button2.innerHTML = 'New';\n  dom.addClass(button2, 'button');\n  dom.addClass(button2, 'save-as');\n  var button3 = document.createElement('span');\n  button3.innerHTML = 'Revert';\n  dom.addClass(button3, 'button');\n  dom.addClass(button3, 'revert');\n  var select = gui.__preset_select = document.createElement('select');\n  if (gui.load && gui.load.remembered) {\n    Common.each(gui.load.remembered, function (value, key) {\n      addPresetOption(gui, key, key === gui.preset);\n    });\n  } else {\n    addPresetOption(gui, DEFAULT_DEFAULT_PRESET_NAME, false);\n  }\n  dom.bind(select, 'change', function () {\n    for (var index = 0; index < gui.__preset_select.length; index++) {\n      gui.__preset_select[index].innerHTML = gui.__preset_select[index].value;\n    }\n    gui.preset = this.value;\n  });\n  div.appendChild(select);\n  div.appendChild(gears);\n  div.appendChild(button);\n  div.appendChild(button2);\n  div.appendChild(button3);\n  if (SUPPORTS_LOCAL_STORAGE) {\n    var explain = document.getElementById('dg-local-explain');\n    var localStorageCheckBox = document.getElementById('dg-local-storage');\n    var saveLocally = document.getElementById('dg-save-locally');\n    saveLocally.style.display = 'block';\n    if (localStorage.getItem(getLocalStorageHash(gui, 'isLocal')) === 'true') {\n      localStorageCheckBox.setAttribute('checked', 'checked');\n    }\n    showHideExplain(gui, explain);\n    dom.bind(localStorageCheckBox, 'change', function () {\n      gui.useLocalStorage = !gui.useLocalStorage;\n      showHideExplain(gui, explain);\n    });\n  }\n  var newConstructorTextArea = document.getElementById('dg-new-constructor');\n  dom.bind(newConstructorTextArea, 'keydown', function (e) {\n    if (e.metaKey && (e.which === 67 || e.keyCode === 67)) {\n      SAVE_DIALOGUE.hide();\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  dom.bind(button, 'click', function () {\n    gui.save();\n  });\n  dom.bind(button2, 'click', function () {\n    var presetName = prompt('Enter a new preset name.');\n    if (presetName) {\n      gui.saveAs(presetName);\n    }\n  });\n  dom.bind(button3, 'click', function () {\n    gui.revert();\n  });\n}\nfunction addResizeHandle(gui) {\n  var pmouseX = void 0;\n  gui.__resize_handle = document.createElement('div');\n  Common.extend(gui.__resize_handle.style, {\n    width: '6px',\n    marginLeft: '-3px',\n    height: '200px',\n    cursor: 'ew-resize',\n    position: 'absolute'\n  });\n  function drag(e) {\n    e.preventDefault();\n    gui.width += pmouseX - e.clientX;\n    gui.onResize();\n    pmouseX = e.clientX;\n    return false;\n  }\n  function dragStop() {\n    dom.removeClass(gui.__closeButton, GUI.CLASS_DRAG);\n    dom.unbind(window, 'mousemove', drag);\n    dom.unbind(window, 'mouseup', dragStop);\n  }\n  function dragStart(e) {\n    e.preventDefault();\n    pmouseX = e.clientX;\n    dom.addClass(gui.__closeButton, GUI.CLASS_DRAG);\n    dom.bind(window, 'mousemove', drag);\n    dom.bind(window, 'mouseup', dragStop);\n    return false;\n  }\n  dom.bind(gui.__resize_handle, 'mousedown', dragStart);\n  dom.bind(gui.__closeButton, 'mousedown', dragStart);\n  gui.domElement.insertBefore(gui.__resize_handle, gui.domElement.firstElementChild);\n}\nfunction setWidth(gui, w) {\n  gui.domElement.style.width = w + 'px';\n  if (gui.__save_row && gui.autoPlace) {\n    gui.__save_row.style.width = w + 'px';\n  }\n  if (gui.__closeButton) {\n    gui.__closeButton.style.width = w + 'px';\n  }\n}\nfunction getCurrentPreset(gui, useInitialValues) {\n  var toReturn = {};\n  Common.each(gui.__rememberedObjects, function (val, index) {\n    var savedValues = {};\n    var controllerMap = gui.__rememberedObjectIndecesToControllers[index];\n    Common.each(controllerMap, function (controller, property) {\n      savedValues[property] = useInitialValues ? controller.initialValue : controller.getValue();\n    });\n    toReturn[index] = savedValues;\n  });\n  return toReturn;\n}\nfunction 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}\nfunction updateDisplays(controllerArray) {\n  if (controllerArray.length !== 0) {\n    requestAnimationFrame$1.call(window, function () {\n      updateDisplays(controllerArray);\n    });\n  }\n  Common.each(controllerArray, function (c) {\n    c.updateDisplay();\n  });\n}\n\nvar color = {\n  Color: Color,\n  math: ColorMath,\n  interpret: interpret\n};\nvar controllers = {\n  Controller: Controller,\n  BooleanController: BooleanController,\n  OptionController: OptionController,\n  StringController: StringController,\n  NumberController: NumberController,\n  NumberControllerBox: NumberControllerBox,\n  NumberControllerSlider: NumberControllerSlider,\n  FunctionController: FunctionController,\n  ColorController: ColorController\n};\nvar dom$1 = { dom: dom };\nvar gui = { GUI: GUI };\nvar GUI$1 = GUI;\nvar index = {\n  color: color,\n  controllers: controllers,\n  dom: dom$1,\n  gui: gui,\n  GUI: GUI$1\n};\n\nexport { color, controllers, dom$1 as dom, gui, GUI$1 as GUI };\nexport default index;\n//# sourceMappingURL=dat.gui.module.js.map\n"
  },
  {
    "path": "example.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no\">\n</head>\n<body>\n  <script type=\"text/javascript\" src=\"build/dat.gui.js\"></script>\n  <script type=\"text/javascript\">\n    var obj = {\n        message: 'Hello World',\n        displayOutline: false,\n\n        maxSize: 6.0,\n        speed: 5,\n\n        height: 10,\n        noiseStrength: 10.2,\n        growthSpeed: 0.2,\n\n        type: 'three',\n\n        explode: function () {\n          alert('Bang!');\n        },\n\n        color0: \"#ffae23\", // CSS string\n        color1: [ 0, 128, 255 ], // RGB array\n        color2: [ 0, 128, 255, 0.3 ], // RGB with alpha\n        color3: { h: 350, s: 0.9, v: 0.3 } // Hue, saturation, value\n    };\n\n    var gui = new dat.gui.GUI();\n\n    gui.remember(obj);\n\n    gui.add(obj, 'message');\n    gui.add(obj, 'displayOutline');\n    gui.add(obj, 'explode');\n\n    gui.add(obj, 'maxSize').min(-10).max(10).step(0.25);\n    gui.add(obj, 'height').step(5); // Increment amount\n\n    // Choose from accepted values\n    gui.add(obj, 'type', [ 'one', 'two', 'three' ] );\n\n    // Choose from named values\n    gui.add(obj, 'speed', { Stopped: 0, Slow: 0.1, Fast: 5 } );\n\n    var f1 = gui.addFolder('Colors');\n    f1.addColor(obj, 'color0');\n    f1.addColor(obj, 'color1');\n    f1.addColor(obj, 'color2');\n    f1.addColor(obj, 'color3');\n\n    var f2 = gui.addFolder('Another Folder');\n    f2.add(obj, 'noiseStrength');\n\n    var f3 = f2.addFolder('Nested Folder');\n    f3.add(obj, 'growthSpeed');\n\n    obj['Button with a long description'] = function () {\n      console.log('Button with a long description pressed');\n    };\n    gui.add(obj, 'Button with a long description');\n\n  </script>\n</body>\n</html>\n"
  },
  {
    "path": "licenseBanner.txt",
    "content": "/**\n * dat-gui JavaScript Controller Library\n * https://github.com/dataarts/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"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"dat.gui\",\n  \"version\": \"0.7.9\",\n  \"description\": \"A lightweight graphical user interface for changing variables in JavaScript.\",\n  \"main\": \"build/dat.gui.js\",\n  \"module\": \"build/dat.gui.module.js\",\n  \"directories\": {\n    \"test\": \"tests\"\n  },\n  \"scripts\": {\n    \"dev\": \"concurrently --names \\\"ROLLUP,HTTP\\\" -c \\\"bgBlue.bold,bgGreen.bold\\\" \\\"rollup -c -w -m inline\\\" \\\"serve --listen 8080\\\"\",\n    \"build\": \"rollup -c && rollup -c rollup.config.min.js\",\n    \"build-docs\": \"jsdoc2md -f src/dat/gui/GUI.js src/dat/controllers/Controller.js src/dat/controllers/NumberController.js | replace-between --target API.md --token API\",\n    \"lint\": \"eslint src\",\n    \"preversion\": \"npm run lint\",\n    \"version\": \"npm run build && git add -A build\",\n    \"postversion\": \"git push && git push --tags && npm publish\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/dataarts/dat.gui.git\"\n  },\n  \"author\": \"Data Arts Team, Google\",\n  \"license\": \"Apache-2.0\",\n  \"bugs\": {\n    \"url\": \"https://github.com/dataarts/dat.gui/issues\"\n  },\n  \"homepage\": \"https://github.com/dataarts/dat.gui#readme\",\n  \"devDependencies\": {\n    \"babel-core\": \"^6.26.3\",\n    \"babel-plugin-external-helpers\": \"^6.22.0\",\n    \"babel-preset-env\": \"^1.7.0\",\n    \"concurrently\": \"^3.5.1\",\n    \"eslint\": \"^6.8.0\",\n    \"eslint-config-airbnb-base\": \"^14.1.0\",\n    \"eslint-loader\": \"^4.0.0\",\n    \"eslint-plugin-import\": \"^2.20.2\",\n    \"extend\": \"^3.0.2\",\n    \"jsdoc-to-markdown\": \"^5.0.3\",\n    \"replace-between\": \"0.0.8\",\n    \"rollup\": \"^0.54.1\",\n    \"rollup-plugin-babel\": \"^3.0.4\",\n    \"rollup-plugin-cleanup\": \"^3.1.1\",\n    \"rollup-plugin-node-resolve\": \"^3.3.0\",\n    \"rollup-plugin-sass\": \"^0.6.1\",\n    \"rollup-plugin-uglify\": \"^2.0.1\",\n    \"serve\": \"^11.3.0\"\n  },\n  \"eslintConfig\": {\n    \"extends\": \"airbnb-base\",\n    \"rules\": {\n      \"comma-dangle\": 0,\n      \"func-names\": 0,\n      \"no-alert\": 0,\n      \"no-console\": 1,\n      \"no-use-before-define\": 0,\n      \"prefer-rest-params\": 0,\n      \"prefer-template\": 0,\n      \"no-mixed-operators\": 0,\n      \"no-undef\": 0,\n      \"no-underscore-dangle\": 0,\n      \"prefer-arrow-callback\": 0,\n      \"space-before-function-paren\": 0,\n      \"global-require\": 0,\n      \"object-shorthand\": 0,\n      \"max-len\": 0,\n      \"no-param-reassign\": 0,\n      \"consistent-return\": 0,\n      \"no-restricted-syntax\": 0,\n      \"no-bitwise\": 0,\n      \"no-plusplus\": 0,\n      \"operator-linebreak\": 0,\n      \"no-else-return\": 0,\n      \"prefer-destructuring\": 0,\n      \"no-multi-assign\": 0,\n      \"no-restricted-properties\": 0,\n      \"no-return-assign\": 0,\n      \"no-restricted-globals\": 0\n    }\n  }\n}\n"
  },
  {
    "path": "rollup.config.js",
    "content": "/**\n * dat-gui JavaScript Controller Library\n * https://github.com/dataarts/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\nimport fs from 'fs';\nimport path from 'path';\nimport resolve from 'rollup-plugin-node-resolve';\nimport cleanup from 'rollup-plugin-cleanup';\nimport babel from 'rollup-plugin-babel';\nimport sass from 'rollup-plugin-sass';\n\nconst banner = fs.readFileSync(path.join(__dirname, 'licenseBanner.txt'));\n\nexport default {\n  input: 'src/dat/index.js',\n  output: [{\n    // TODO: Remove default exports, and this line, in v0.8.0.\n    exports: 'named',\n    file: './build/dat.gui.js',\n    format: 'umd',\n    name: 'dat',\n    sourcemap: true,\n    banner: banner\n  }, {\n    file: './build/dat.gui.module.js',\n    format: 'es',\n    sourcemap: true,\n    banner: banner\n  }],\n  watch: {\n    include: 'src/**'\n  },\n  plugins: [\n    resolve(),\n    sass({\n      insert: true,\n      output: 'build/dat.gui.css',\n      options: {outputStyle: 'compressed'}\n    }),\n    babel({\n      plugins: ['external-helpers'],\n      exclude: 'node_modules/**'\n    }),\n    cleanup()\n  ]\n};\n"
  },
  {
    "path": "src/dat/color/Color.js",
    "content": "/**\n * dat-gui JavaScript Controller Library\n * https://github.com/dataarts/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\nimport interpret from './interpret';\nimport math from './math';\nimport colorToString from './toString';\nimport common from '../utils/common';\n\nclass Color {\n  constructor() {\n    this.__state = interpret.apply(this, arguments);\n\n    if (this.__state === false) {\n      throw new Error('Failed to interpret color arguments');\n    }\n\n    this.__state.a = this.__state.a || 1;\n  }\n\n  toString() {\n    return colorToString(this);\n  }\n\n  toHexString() {\n    return colorToString(this, true);\n  }\n\n  toOriginal() {\n    return this.__state.conversion.write(this);\n  }\n}\n\nfunction defineRGBComponent(target, component, componentHexIndex) {\n  Object.defineProperty(target, component, {\n    get: function() {\n      if (this.__state.space === 'RGB') {\n        return this.__state[component];\n      }\n\n      Color.recalculateRGB(this, component, componentHexIndex);\n\n      return this.__state[component];\n    },\n\n    set: function(v) {\n      if (this.__state.space !== 'RGB') {\n        Color.recalculateRGB(this, component, componentHexIndex);\n        this.__state.space = 'RGB';\n      }\n\n      this.__state[component] = v;\n    }\n  });\n}\n\nfunction defineHSVComponent(target, component) {\n  Object.defineProperty(target, component, {\n    get: function() {\n      if (this.__state.space === 'HSV') {\n        return this.__state[component];\n      }\n\n      Color.recalculateHSV(this);\n\n      return this.__state[component];\n    },\n\n    set: function(v) {\n      if (this.__state.space !== 'HSV') {\n        Color.recalculateHSV(this);\n        this.__state.space = 'HSV';\n      }\n\n      this.__state[component] = v;\n    }\n  });\n}\n\n\nColor.recalculateRGB = function(color, component, componentHexIndex) {\n  if (color.__state.space === 'HEX') {\n    color.__state[component] = math.component_from_hex(color.__state.hex, componentHexIndex);\n  } else if (color.__state.space === 'HSV') {\n    common.extend(color.__state, math.hsv_to_rgb(color.__state.h, color.__state.s, color.__state.v));\n  } else {\n    throw new Error('Corrupted color state');\n  }\n};\n\nColor.recalculateHSV = function(color) {\n  const 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  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\nColor.COMPONENTS = ['r', 'g', 'b', 'h', 's', 'v', 'hex', 'a'];\n\ndefineRGBComponent(Color.prototype, 'r', 2);\ndefineRGBComponent(Color.prototype, 'g', 1);\ndefineRGBComponent(Color.prototype, 'b', 0);\n\ndefineHSVComponent(Color.prototype, 'h');\ndefineHSVComponent(Color.prototype, 's');\ndefineHSVComponent(Color.prototype, 'v');\n\nObject.defineProperty(Color.prototype, 'a', {\n  get: function() {\n    return this.__state.a;\n  },\n\n  set: function(v) {\n    this.__state.a = v;\n  }\n});\n\nObject.defineProperty(Color.prototype, 'hex', {\n  get: function() {\n    if (this.__state.space !== 'HEX') {\n      this.__state.hex = math.rgb_to_hex(this.r, this.g, this.b);\n      this.__state.space = 'HEX';\n    }\n\n    return this.__state.hex;\n  },\n\n  set: function(v) {\n    this.__state.space = 'HEX';\n    this.__state.hex = v;\n  }\n});\n\nexport default Color;\n"
  },
  {
    "path": "src/dat/color/interpret.js",
    "content": "/**\n * dat-gui JavaScript Controller Library\n * https://github.com/dataarts/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\nimport toString from './toString';\nimport common from '../utils/common';\n\nconst INTERPRETATIONS = [\n  // Strings\n  {\n    litmus: common.isString,\n    conversions: {\n      THREE_CHAR_HEX: {\n        read: function(original) {\n          const test = original.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);\n          if (test === null) {\n            return false;\n          }\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(), 0\n            )\n          };\n        },\n\n        write: toString\n      },\n\n      SIX_CHAR_HEX: {\n        read: function(original) {\n          const test = original.match(/^#([A-F0-9]{6})$/i);\n          if (test === null) {\n            return false;\n          }\n\n          return {\n            space: 'HEX',\n            hex: parseInt('0x' + test[1].toString(), 0)\n          };\n        },\n\n        write: toString\n      },\n\n      CSS_RGB: {\n        read: function(original) {\n          const test = original.match(/^rgb\\(\\s*(\\S+)\\s*,\\s*(\\S+)\\s*,\\s*(\\S+)\\s*\\)/);\n          if (test === null) {\n            return false;\n          }\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        write: toString\n      },\n\n      CSS_RGBA: {\n        read: function(original) {\n          const test = original.match(/^rgba\\(\\s*(\\S+)\\s*,\\s*(\\S+)\\s*,\\s*(\\S+)\\s*,\\s*(\\S+)\\s*\\)/);\n          if (test === null) {\n            return false;\n          }\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        write: toString\n      }\n    }\n  },\n\n  // Numbers\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    litmus: common.isArray,\n    conversions: {\n      RGB_ARRAY: {\n        read: function(original) {\n          if (original.length !== 3) {\n            return false;\n          }\n\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      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  // Objects\n  {\n    litmus: common.isObject,\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\nlet result;\nlet toReturn;\n\nconst interpret = function() {\n  toReturn = false;\n\n  const original = arguments.length > 1 ? common.toArray(arguments) : arguments[0];\n  common.each(INTERPRETATIONS, function(family) {\n    if (family.litmus(original)) {\n      common.each(family.conversions, function(conversion, conversionName) {\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      return common.BREAK;\n    }\n  });\n\n  return toReturn;\n};\n\nexport default interpret;\n"
  },
  {
    "path": "src/dat/color/math.js",
    "content": "/**\n * dat-gui JavaScript Controller Library\n * https://github.com/dataarts/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\nlet tmpComponent;\n\nconst ColorMath = {\n  hsv_to_rgb: function(h, s, v) {\n    const hi = Math.floor(h / 60) % 6;\n\n    const f = h / 60 - Math.floor(h / 60);\n    const p = v * (1.0 - s);\n    const q = v * (1.0 - (f * s));\n    const t = v * (1.0 - ((1.0 - f) * s));\n\n    const 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  rgb_to_hsv: function(r, g, b) {\n    const min = Math.min(r, g, b);\n    const max = Math.max(r, g, b);\n    const delta = max - min;\n    let h;\n    let 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    let 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\nexport default ColorMath;\n"
  },
  {
    "path": "src/dat/color/toString.js",
    "content": "/**\n * dat-gui JavaScript Controller Library\n * https://github.com/dataarts/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\nexport default function(color, forceCSSHex) {\n  const colorFormat = color.__state.conversionName.toString();\n\n  const r = Math.round(color.r);\n  const g = Math.round(color.g);\n  const b = Math.round(color.b);\n  const a = color.a;\n  const h = Math.round(color.h);\n  const s = color.s.toFixed(1);\n  const v = color.v.toFixed(1);\n\n  if (forceCSSHex || (colorFormat === 'THREE_CHAR_HEX') || (colorFormat === 'SIX_CHAR_HEX')) {\n    let str = color.hex.toString(16);\n    while (str.length < 6) {\n      str = '0' + str;\n    }\n    return '#' + str;\n  } else if (colorFormat === 'CSS_RGB') {\n    return 'rgb(' + r + ',' + g + ',' + b + ')';\n  } else if (colorFormat === 'CSS_RGBA') {\n    return 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';\n  } else if (colorFormat === 'HEX') {\n    return '0x' + color.hex.toString(16);\n  } else if (colorFormat === 'RGB_ARRAY') {\n    return '[' + r + ',' + g + ',' + b + ']';\n  } else if (colorFormat === 'RGBA_ARRAY') {\n    return '[' + r + ',' + g + ',' + b + ',' + a + ']';\n  } else if (colorFormat === 'RGB_OBJ') {\n    return '{r:' + r + ',g:' + g + ',b:' + b + '}';\n  } else if (colorFormat === 'RGBA_OBJ') {\n    return '{r:' + r + ',g:' + g + ',b:' + b + ',a:' + a + '}';\n  } else if (colorFormat === 'HSV_OBJ') {\n    return '{h:' + h + ',s:' + s + ',v:' + v + '}';\n  } else if (colorFormat === 'HSVA_OBJ') {\n    return '{h:' + h + ',s:' + s + ',v:' + v + ',a:' + a + '}';\n  }\n\n  return 'unknown format';\n}\n"
  },
  {
    "path": "src/dat/controllers/BooleanController.js",
    "content": "/**\n * dat-gui JavaScript Controller Library\n * https://github.com/dataarts/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\nimport Controller from './Controller';\nimport dom from '../dom/dom';\n\n/**\n * @class Provides a checkbox input to alter the boolean 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 */\nclass BooleanController extends Controller {\n  constructor(object, property) {\n    super(object, property);\n\n    const _this = this;\n    this.__prev = this.getValue();\n\n    this.__checkbox = document.createElement('input');\n    this.__checkbox.setAttribute('type', 'checkbox');\n\n    function onChange() {\n      _this.setValue(!_this.__prev);\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\n  setValue(v) {\n    const toReturn = super.setValue(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() {\n    if (this.getValue() === true) {\n      this.__checkbox.setAttribute('checked', 'checked');\n      this.__checkbox.checked = true;\n      this.__prev = true;\n    } else {\n      this.__checkbox.checked = false;\n      this.__prev = false;\n    }\n\n    return super.updateDisplay();\n  }\n}\n\nexport default BooleanController;\n"
  },
  {
    "path": "src/dat/controllers/ColorController.js",
    "content": "/**\n * dat-gui JavaScript Controller Library\n * https://github.com/dataarts/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\nimport Controller from './Controller';\nimport dom from '../dom/dom';\nimport Color from '../color/Color';\nimport interpret from '../color/interpret';\nimport common from '../utils/common';\n\n/**\n * @class Represents a given property of an object that is a color.\n * @param {Object} object\n * @param {string} property\n */\nclass ColorController extends Controller {\n  constructor(object, property) {\n    super(object, property);\n\n    this.__color = new Color(this.getValue());\n    this.__temp = new Color(0);\n\n    const _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      dom\n        .addClass(this, 'drag')\n        .bind(window, 'mouseup', function(/* e */) {\n          dom.removeClass(_this.__selector, 'drag');\n        });\n    });\n\n    dom.bind(this.__selector, 'touchstart', function(/* e */) {\n      dom\n        .addClass(this, 'drag')\n        .bind(window, 'touchend', function(/* e */) {\n          dom.removeClass(_this.__selector, 'drag');\n        });\n    });\n\n    const valueField = 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 < 0.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(valueField.style, {\n      width: '100%',\n      height: '100%',\n      background: 'none'\n    });\n\n    linearGradient(valueField, 'top', 'rgba(0,0,0,0)', '#000');\n\n    common.extend(this.__hue_field.style, {\n      width: '15px',\n      height: '100px',\n      border: '1px solid #555',\n      cursor: 'ns-resize',\n      position: 'absolute',\n      top: '3px',\n      right: '3px'\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.__saturation_field, 'touchstart', fieldDown);\n\n    dom.bind(this.__field_knob, 'mousedown', fieldDown);\n    dom.bind(this.__field_knob, 'touchstart', fieldDown);\n\n    dom.bind(this.__hue_field, 'mousedown', fieldDownH);\n    dom.bind(this.__hue_field, 'touchstart', fieldDownH);\n\n    function fieldDown(e) {\n      setSV(e);\n      dom.bind(window, 'mousemove', setSV);\n      dom.bind(window, 'touchmove', setSV);\n      dom.bind(window, 'mouseup', fieldUpSV);\n      dom.bind(window, 'touchend', fieldUpSV);\n    }\n\n    function fieldDownH(e) {\n      setH(e);\n      dom.bind(window, 'mousemove', setH);\n      dom.bind(window, 'touchmove', setH);\n      dom.bind(window, 'mouseup', fieldUpH);\n      dom.bind(window, 'touchend', fieldUpH);\n    }\n\n    function fieldUpSV() {\n      dom.unbind(window, 'mousemove', setSV);\n      dom.unbind(window, 'touchmove', setSV);\n      dom.unbind(window, 'mouseup', fieldUpSV);\n      dom.unbind(window, 'touchend', fieldUpSV);\n      onFinish();\n    }\n\n    function fieldUpH() {\n      dom.unbind(window, 'mousemove', setH);\n      dom.unbind(window, 'touchmove', setH);\n      dom.unbind(window, 'mouseup', fieldUpH);\n      dom.unbind(window, 'touchend', fieldUpH);\n      onFinish();\n    }\n\n    function onBlur() {\n      const 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 onFinish() {\n      if (_this.__onFinishChange) {\n        _this.__onFinishChange.call(_this, _this.__color.toOriginal());\n      }\n    }\n\n    this.__saturation_field.appendChild(valueField);\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      if (e.type.indexOf('touch') === -1) { e.preventDefault(); }\n\n      const fieldRect = _this.__saturation_field.getBoundingClientRect();\n      const { clientX, clientY } = (e.touches && e.touches[0]) || e;\n      let s = (clientX - fieldRect.left) / (fieldRect.right - fieldRect.left);\n      let v = 1 - (clientY - fieldRect.top) / (fieldRect.bottom - fieldRect.top);\n\n      if (v > 1) {\n        v = 1;\n      } else if (v < 0) {\n        v = 0;\n      }\n\n      if (s > 1) {\n        s = 1;\n      } else if (s < 0) {\n        s = 0;\n      }\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    function setH(e) {\n      if (e.type.indexOf('touch') === -1) { e.preventDefault(); }\n\n      const fieldRect = _this.__hue_field.getBoundingClientRect();\n      const { clientY } = (e.touches && e.touches[0]) || e;\n      let h = 1 - (clientY - fieldRect.top) / (fieldRect.bottom - fieldRect.top);\n\n      if (h > 1) {\n        h = 1;\n      } else if (h < 0) {\n        h = 0;\n      }\n\n      _this.__color.h = h * 360;\n\n      _this.setValue(_this.__color.toOriginal());\n\n      return false;\n    }\n  }\n\n  updateDisplay() {\n    const i = interpret(this.getValue());\n\n    if (i !== false) {\n      let 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]) && !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    common.extend(this.__temp.__state, this.__color.__state);\n\n    this.__temp.a = 1;\n\n    const flip = (this.__color.v < 0.5 || this.__color.s > 0.5) ? 255 : 0;\n    const _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.toHexString(),\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.toHexString());\n\n    this.__input.value = this.__color.toString();\n\n    common.extend(this.__input.style, {\n      backgroundColor: this.__color.toHexString(),\n      color: 'rgb(' + flip + ',' + flip + ',' + flip + ')',\n      textShadow: this.__input_textShadow + 'rgba(' + _flip + ',' + _flip + ',' + _flip + ',.7)'\n    });\n  }\n}\n\nconst vendors = ['-moz-', '-o-', '-webkit-', '-ms-', ''];\n\nfunction 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\nfunction 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\nexport default ColorController;\n"
  },
  {
    "path": "src/dat/controllers/Controller.js",
    "content": "/**\n * dat-gui JavaScript Controller Library\n * https://github.com/dataarts/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/**\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 */\nclass Controller {\n  constructor(object, property) {\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   * 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 {Controller} this\n   */\n  onChange(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 {Controller} this\n   */\n  onFinishChange(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(newValue) {\n    this.object[this.property] = newValue;\n    if (this.__onChange) {\n      this.__onChange.call(this, newValue);\n    }\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() {\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 {Controller} this\n   */\n  updateDisplay() {\n    return this;\n  }\n\n  /**\n   * @returns {boolean} true if the value has deviated from initialValue\n   */\n  isModified() {\n    return this.initialValue !== this.getValue();\n  }\n}\n\nexport default Controller;\n"
  },
  {
    "path": "src/dat/controllers/ControllerFactory.js",
    "content": "/**\n * dat-gui JavaScript Controller Library\n * https://github.com/dataarts/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\nimport OptionController from './OptionController';\nimport NumberControllerBox from './NumberControllerBox';\nimport NumberControllerSlider from './NumberControllerSlider';\nimport StringController from './StringController';\nimport FunctionController from './FunctionController';\nimport BooleanController from './BooleanController';\nimport common from '../utils/common';\n\nconst ControllerFactory = function(object, property) {\n  const 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  if (common.isNumber(initialValue)) {\n    // Has min and max? (slider)\n    if (common.isNumber(arguments[2]) && common.isNumber(arguments[3])) {\n      // has step?\n      if (common.isNumber(arguments[4])) {\n        return new NumberControllerSlider(object, property,\n          arguments[2], arguments[3], arguments[4]);\n      }\n\n      return new NumberControllerSlider(object, property, arguments[2], arguments[3]);\n    }\n\n    // number box\n    if (common.isNumber(arguments[4])) { // has step\n      return new NumberControllerBox(object, property,\n        { min: arguments[2], max: arguments[3], step: arguments[4] });\n    }\n    return new NumberControllerBox(object, property, { min: arguments[2], max: arguments[3] });\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  return null;\n};\n\nexport default ControllerFactory;\n"
  },
  {
    "path": "src/dat/controllers/FunctionController.js",
    "content": "/**\n * dat-gui JavaScript Controller Library\n * https://github.com/dataarts/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\nimport Controller from './Controller';\nimport dom from '../dom/dom';\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 */\nclass FunctionController extends Controller {\n  constructor(object, property, text) {\n    super(object, property);\n\n    const _this = this;\n\n    this.__button = document.createElement('div');\n    this.__button.innerHTML = text === undefined ? 'Fire' : text;\n\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  fire() {\n    if (this.__onChange) {\n      this.__onChange.call(this);\n    }\n    this.getValue().call(this.object);\n    if (this.__onFinishChange) {\n      this.__onFinishChange.call(this, this.getValue());\n    }\n  }\n}\n\nexport default FunctionController;\n"
  },
  {
    "path": "src/dat/controllers/NumberController.js",
    "content": "/**\n * dat-gui JavaScript Controller Library\n * https://github.com/dataarts/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\nimport Controller from './Controller';\nimport common from '../utils/common';\n\nfunction numDecimals(x) {\n  const _x = x.toString();\n  if (_x.indexOf('.') > -1) {\n    return _x.length - _x.indexOf('.') - 1;\n  }\n\n  return 0;\n}\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 */\nclass NumberController extends Controller {\n  constructor(object, property, params) {\n    super(object, property);\n\n    const _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      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(Math.abs(this.initialValue)) / Math.LN10)) / 10;\n      }\n    } else {\n      this.__impliedStep = this.__step;\n    }\n\n    this.__precision = numDecimals(this.__impliedStep);\n  }\n\n  setValue(v) {\n    let _v = 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 super.setValue(_v);\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(minValue) {\n    this.__min = minValue;\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(maxValue) {\n    this.__max = maxValue;\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(stepValue) {\n    this.__step = stepValue;\n    this.__impliedStep = stepValue;\n    this.__precision = numDecimals(stepValue);\n    return this;\n  }\n}\n\nexport default NumberController;\n"
  },
  {
    "path": "src/dat/controllers/NumberControllerBox.js",
    "content": "/**\n * dat-gui JavaScript Controller Library\n * https://github.com/dataarts/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\nimport NumberController from './NumberController';\nimport dom from '../dom/dom';\nimport common from '../utils/common';\n\nfunction roundToDecimal(value, decimals) {\n  const tenTo = Math.pow(10, decimals);\n  return Math.round(value * tenTo) / tenTo;\n}\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 */\nclass NumberControllerBox extends NumberController {\n  constructor(object, property, params) {\n    super(object, property, params);\n\n    this.__truncationSuspended = false;\n\n    const _this = this;\n\n    /**\n     * {Number} Previous mouse y position\n     * @ignore\n     */\n    let prevY;\n\n    function onChange() {\n      const attempted = parseFloat(_this.__input.value);\n      if (!common.isNaN(attempted)) {\n        _this.setValue(attempted);\n      }\n    }\n\n    function onFinish() {\n      if (_this.__onFinishChange) {\n        _this.__onFinishChange.call(_this, _this.getValue());\n      }\n    }\n\n    function onBlur() {\n      onFinish();\n    }\n\n    function onMouseDrag(e) {\n      const diff = prevY - e.clientY;\n      _this.setValue(_this.getValue() + diff * _this.__impliedStep);\n\n      prevY = e.clientY;\n    }\n\n    function onMouseUp() {\n      dom.unbind(window, 'mousemove', onMouseDrag);\n      dom.unbind(window, 'mouseup', onMouseUp);\n      onFinish();\n    }\n\n    function onMouseDown(e) {\n      dom.bind(window, 'mousemove', onMouseDrag);\n      dom.bind(window, 'mouseup', onMouseUp);\n      prevY = e.clientY;\n    }\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      // When pressing enter, 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        onFinish();\n      }\n    });\n\n    this.updateDisplay();\n\n    this.domElement.appendChild(this.__input);\n  }\n\n  updateDisplay() {\n    this.__input.value = this.__truncationSuspended ? this.getValue() : roundToDecimal(this.getValue(), this.__precision);\n    return super.updateDisplay();\n  }\n}\n\nexport default NumberControllerBox;\n"
  },
  {
    "path": "src/dat/controllers/NumberControllerSlider.js",
    "content": "/**\n * dat-gui JavaScript Controller Library\n * https://github.com/dataarts/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\nimport NumberController from './NumberController';\nimport dom from '../dom/dom';\n\nfunction map(v, i1, i2, o1, o2) {\n  return o1 + (o2 - o1) * ((v - i1) / (i2 - i1));\n}\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 */\nclass NumberControllerSlider extends NumberController {\n  constructor(object, property, min, max, step) {\n    super(object, property, { min: min, max: max, step: step });\n\n    const _this = this;\n\n    this.__background = document.createElement('div');\n    this.__foreground = document.createElement('div');\n\n    dom.bind(this.__background, 'mousedown', onMouseDown);\n    dom.bind(this.__background, 'touchstart', onTouchStart);\n\n    dom.addClass(this.__background, 'slider');\n    dom.addClass(this.__foreground, 'slider-fg');\n\n    function onMouseDown(e) {\n      document.activeElement.blur();\n\n      dom.bind(window, 'mousemove', onMouseDrag);\n      dom.bind(window, 'mouseup', onMouseUp);\n\n      onMouseDrag(e);\n    }\n\n    function onMouseDrag(e) {\n      e.preventDefault();\n\n      const bgRect = _this.__background.getBoundingClientRect();\n\n      _this.setValue(\n        map(e.clientX, bgRect.left, bgRect.right, _this.__min, _this.__max)\n      );\n\n      return false;\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    function onTouchStart(e) {\n      if (e.touches.length !== 1) { return; }\n      dom.bind(window, 'touchmove', onTouchMove);\n      dom.bind(window, 'touchend', onTouchEnd);\n      onTouchMove(e);\n    }\n\n    function onTouchMove(e) {\n      const clientX = e.touches[0].clientX;\n      const bgRect = _this.__background.getBoundingClientRect();\n\n      _this.setValue(\n        map(clientX, bgRect.left, bgRect.right, _this.__min, _this.__max)\n      );\n    }\n\n    function onTouchEnd() {\n      dom.unbind(window, 'touchmove', onTouchMove);\n      dom.unbind(window, 'touchend', onTouchEnd);\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  updateDisplay() {\n    const pct = (this.getValue() - this.__min) / (this.__max - this.__min);\n    this.__foreground.style.width = pct * 100 + '%';\n    return super.updateDisplay();\n  }\n}\n\nexport default NumberControllerSlider;\n"
  },
  {
    "path": "src/dat/controllers/OptionController.js",
    "content": "/**\n * dat-gui JavaScript Controller Library\n * https://github.com/dataarts/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\nimport Controller from './Controller';\nimport dom from '../dom/dom';\nimport common from '../utils/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 */\nclass OptionController extends Controller {\n  constructor(object, property, opts) {\n    super(object, property);\n\n    let options = opts;\n\n    const _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      const 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      const opt = document.createElement('option');\n      opt.innerHTML = key;\n      opt.setAttribute('value', value);\n      _this.__select.appendChild(opt);\n    });\n\n    // Acknowledge original value\n    this.updateDisplay();\n\n    dom.bind(this.__select, 'change', function() {\n      const desiredValue = this.options[this.selectedIndex].value;\n      _this.setValue(desiredValue);\n    });\n\n    this.domElement.appendChild(this.__select);\n  }\n\n  setValue(v) {\n    const toReturn = super.setValue(v);\n\n    if (this.__onFinishChange) {\n      this.__onFinishChange.call(this, this.getValue());\n    }\n    return toReturn;\n  }\n\n  updateDisplay() {\n    if (dom.isActive(this.__select)) return this; // prevent number from updating if user is trying to manually update\n    this.__select.value = this.getValue();\n    return super.updateDisplay();\n  }\n}\n\nexport default OptionController;\n"
  },
  {
    "path": "src/dat/controllers/StringController.js",
    "content": "/**\n * dat-gui JavaScript Controller Library\n * https://github.com/dataarts/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\nimport Controller from './Controller';\nimport dom from '../dom/dom';\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 */\nclass StringController extends Controller {\n  constructor(object, property) {\n    super(object, property);\n\n    const _this = this;\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.__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    this.updateDisplay();\n\n    this.domElement.appendChild(this.__input);\n  }\n\n  updateDisplay() {\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 super.updateDisplay();\n  }\n}\n\nexport default StringController;\n"
  },
  {
    "path": "src/dat/dom/CenteredDiv.js",
    "content": "/**\n * dat-gui JavaScript Controller Library\n * https://github.com/dataarts/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\nimport dom from './dom';\nimport common from '../utils/common';\n\nclass CenteredDiv {\n  constructor() {\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      transition: '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      transition: '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    const _this = this;\n    dom.bind(this.backgroundElement, 'click', function() {\n      _this.hide();\n    });\n  }\n\n  show() {\n    const _this = this;\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   * Hide centered div\n   */\n  hide() {\n    const _this = this;\n\n    const hide = function() {\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    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  layout() {\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\nexport default CenteredDiv;\n"
  },
  {
    "path": "src/dat/dom/dom.js",
    "content": "/**\n * dat-gui JavaScript Controller Library\n * https://github.com/dataarts/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\nimport common from '../utils/common';\n\nconst EVENT_MAP = {\n  HTMLEvents: ['change'],\n  MouseEvents: ['click', 'mousemove', 'mousedown', 'mouseup', 'mouseover'],\n  KeyboardEvents: ['keydown']\n};\n\nconst EVENT_MAP_INV = {};\ncommon.each(EVENT_MAP, function(v, k) {\n  common.each(v, function(e) {\n    EVENT_MAP_INV[e] = k;\n  });\n});\n\nconst CSS_VALUE_PIXELS = /(\\d+(\\.\\d+)?)px/;\n\nfunction cssValueToPixels(val) {\n  if (val === '0' || common.isUndefined(val)) {\n    return 0;\n  }\n\n  const 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 * @namespace\n * @member dat.dom\n */\nconst dom = {\n\n  /**\n   *\n   * @param elem\n   * @param selectable\n   */\n  makeSelectable: function(elem, selectable) {\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   * @param elem\n   * @param horizontal\n   * @param vert\n   */\n  makeFullscreen: function(elem, hor, vert) {\n    let vertical = vert;\n    let horizontal = hor;\n\n    if (common.isUndefined(horizontal)) {\n      horizontal = true;\n    }\n\n    if (common.isUndefined(vertical)) {\n      vertical = true;\n    }\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   * @param elem\n   * @param eventType\n   * @param params\n   */\n  fakeEvent: function(elem, eventType, pars, aux) {\n    const params = pars || {};\n    const className = EVENT_MAP_INV[eventType];\n    if (!className) {\n      throw new Error('Event type ' + eventType + ' not supported.');\n    }\n    const evt = document.createEvent(className);\n    switch (className) {\n      case 'MouseEvents':\n      {\n        const clientX = params.x || params.clientX || 0;\n        const 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      }\n      case 'KeyboardEvents':\n      {\n        const 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      }\n      default:\n      {\n        evt.initEvent(eventType, params.bubbles || false, params.cancelable || true);\n        break;\n      }\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, newBool) {\n    const bool = newBool || false;\n    if (elem.addEventListener) {\n      elem.addEventListener(event, func, bool);\n    } else if (elem.attachEvent) {\n      elem.attachEvent('on' + event, func);\n    }\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, newBool) {\n    const bool = newBool || false;\n    if (elem.removeEventListener) {\n      elem.removeEventListener(event, func, bool);\n    } else if (elem.detachEvent) {\n      elem.detachEvent('on' + event, func);\n    }\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      const 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 === className) {\n        elem.removeAttribute('class');\n      } else {\n        const classes = elem.className.split(/ +/);\n        const 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    const 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    const 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 el\n   */\n  getOffset: function(el) {\n    let elem = el;\n    const offset = { left: 0, top: 0 };\n    if (elem.offsetParent) {\n      do {\n        offset.left += elem.offsetLeft;\n        offset.top += elem.offsetTop;\n        elem = elem.offsetParent;\n      } while (elem);\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\nexport default dom;\n"
  },
  {
    "path": "src/dat/gui/GUI.js",
    "content": "/**\n * dat-gui JavaScript Controller Library\n * https://github.com/dataarts/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\nimport css from '../utils/css';\nimport saveDialogueContents from './saveDialogue.html';\nimport ControllerFactory from '../controllers/ControllerFactory';\nimport Controller from '../controllers/Controller';\nimport BooleanController from '../controllers/BooleanController';\nimport FunctionController from '../controllers/FunctionController';\nimport NumberControllerBox from '../controllers/NumberControllerBox';\nimport NumberControllerSlider from '../controllers/NumberControllerSlider';\nimport ColorController from '../controllers/ColorController';\nimport requestAnimationFrame from '../utils/requestAnimationFrame';\nimport CenteredDiv from '../dom/CenteredDiv';\nimport dom from '../dom/dom';\nimport common from '../utils/common';\n\nimport styleSheet from './style.scss'; // CSS to embed in build\n\ncss.inject(styleSheet);\n\n/** @ignore Outer-most className for GUI's */\nconst CSS_NAMESPACE = 'dg';\n\nconst HIDE_KEY_CODE = 72;\n\n/** @ignore The only value shared between the JS and SCSS. Use caution. */\nconst CLOSE_BUTTON_HEIGHT = 20;\n\nconst DEFAULT_DEFAULT_PRESET_NAME = 'Default';\n\nconst SUPPORTS_LOCAL_STORAGE = (function() {\n  try {\n    return !!window.localStorage;\n  } catch (e) {\n    return false;\n  }\n}());\n\nlet SAVE_DIALOGUE;\n\n/** @ignore Have we yet to create an autoPlace GUI? */\nlet autoPlaceVirgin = true;\n\n/** @ignore Fixed position div that auto place GUI's go inside */\nlet autoPlaceContainer;\n\n/** @ignore Are we hiding the GUI's ? */\nlet hide = false;\n\n/** @private GUI's which should be hidden */\nconst hideableGuis = [];\n\n/**\n * @class A lightweight controller library for JavaScript. It allows you to easily\n * manipulate variables and fire functions on the fly.\n *\n * @typicalname gui\n *\n * @example\n * // Creating a GUI with options.\n * var gui = new dat.GUI({name: 'My GUI'});\n *\n * @example\n * // Creating a GUI and a subfolder.\n * var gui = new dat.GUI();\n * var folder1 = gui.addFolder('Flow Field');\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 {dat.gui.GUI} [params.parent] The GUI I'm nested in.\n * @param {Boolean} [params.autoPlace=true]\n * @param {Boolean} [params.hideable=true] If true, GUI is shown/hidden by <kbd>h</kbd> keypress.\n * @param {Boolean} [params.closed=false] If true, starts closed\n * @param {Boolean} [params.closeOnTop=false] If true, close/open button shows on top of the GUI\n */\nconst GUI = function(pars) {\n  const _this = this;\n\n  let params = pars || {};\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  // Default parameters\n  params = common.defaults(params, {\n    closeOnTop: false,\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  if (!common.isUndefined(params.load)) {\n    // Explicit preset\n    if (params.preset) {\n      params.load.preset = params.preset;\n    }\n  } else {\n    params.load = { preset: DEFAULT_DEFAULT_PRESET_NAME };\n  }\n\n  if (common.isUndefined(params.parent) && params.hideable) {\n    hideableGuis.push(this);\n  }\n\n  // Only root level GUI's are resizable.\n  params.resizable = common.isUndefined(params.parent) && params.resizable;\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  let useLocalStorage =\n    SUPPORTS_LOCAL_STORAGE &&\n    localStorage.getItem(getLocalStorageHash(this, 'isLocal')) === 'true';\n\n  let saveToLocalStorage;\n  let titleRow;\n\n  Object.defineProperties(this,\n    /** @lends GUI.prototype */\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       * Handles <code>GUI</code>'s position of open/close button\n       * @type Boolean\n       */\n      closeOnTop: {\n        get: function() {\n          return params.closeOnTop;\n        }\n      },\n\n      /**\n       * The identifier for a set of saved values\n       * @type String\n       */\n      preset: {\n        get: function() {\n          if (_this.parent) {\n            return _this.getRoot().preset;\n          }\n\n          return params.load.preset;\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       * 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 (titleRow) {\n            titleRow.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 useLocalStorage;\n        },\n        set: function(bool) {\n          if (SUPPORTS_LOCAL_STORAGE) {\n            useLocalStorage = 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  // Are we a root level GUI?\n  if (common.isUndefined(params.parent)) {\n    this.closed = 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      if (useLocalStorage) {\n        _this.useLocalStorage = true;\n\n        const savedGui = localStorage.getItem(getLocalStorageHash(this, 'gui'));\n\n        if (savedGui) {\n          params.load = JSON.parse(savedGui);\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    if (params.closeOnTop) {\n      dom.addClass(this.__closeButton, GUI.CLASS_CLOSE_TOP);\n      this.domElement.insertBefore(this.__closeButton, this.domElement.childNodes[0]);\n    } else {\n      dom.addClass(this.__closeButton, GUI.CLASS_CLOSE_BOTTOM);\n      this.domElement.appendChild(this.__closeButton);\n    }\n\n    dom.bind(this.__closeButton, 'click', function() {\n      _this.closed = !_this.closed;\n    });\n    // Oh, you're a nested GUI!\n  } else {\n    if (params.closed === undefined) {\n      params.closed = true;\n    }\n\n    const titleRowName = document.createTextNode(params.name);\n    dom.addClass(titleRowName, 'controller-name');\n\n    titleRow = addRow(_this, titleRowName);\n\n    const onClickTitle = 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(titleRow, 'title');\n    dom.bind(titleRow, 'click', onClickTitle);\n\n    if (!params.closed) {\n      this.closed = false;\n    }\n  }\n\n  if (params.autoPlace) {\n    if (common.isUndefined(params.parent)) {\n      if (autoPlaceVirgin) {\n        autoPlaceContainer = document.createElement('div');\n        dom.addClass(autoPlaceContainer, CSS_NAMESPACE);\n        dom.addClass(autoPlaceContainer, GUI.CLASS_AUTO_PLACE_CONTAINER);\n        document.body.appendChild(autoPlaceContainer);\n        autoPlaceVirgin = false;\n      }\n\n      // Put it in the dom for you.\n      autoPlaceContainer.appendChild(this.domElement);\n\n      // Apply the auto styles\n      dom.addClass(this.domElement, GUI.CLASS_AUTO_PLACE);\n    }\n\n\n    // Make it not elastic.\n    if (!this.parent) {\n      setWidth(_this, params.width);\n    }\n  }\n\n  this.__resizeHandler = function() {\n    _this.onResizeDebounced();\n  };\n\n  dom.bind(window, 'resize', this.__resizeHandler);\n  dom.bind(this.__ul, 'webkitTransitionEnd', this.__resizeHandler);\n  dom.bind(this.__ul, 'transitionend', this.__resizeHandler);\n  dom.bind(this.__ul, 'oTransitionEnd', this.__resizeHandler);\n  this.onResize();\n\n  if (params.resizable) {\n    addResizeHandle(this);\n  }\n\n  saveToLocalStorage = function() {\n    if (SUPPORTS_LOCAL_STORAGE && localStorage.getItem(getLocalStorageHash(_this, 'isLocal')) === 'true') {\n      localStorage.setItem(getLocalStorageHash(_this, 'gui'), JSON.stringify(_this.getSaveObject()));\n    }\n  };\n\n  // expose this method publicly\n  this.saveToLocalStorageIfPossible = saveToLocalStorage;\n\n  function resetWidth() {\n    const 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\nGUI.toggleHide = function() {\n  hide = !hide;\n  common.each(hideableGuis, function(gui) {\n    gui.domElement.style.display = hide ? 'none' : '';\n  });\n};\n\nGUI.CLASS_AUTO_PLACE = 'a';\nGUI.CLASS_AUTO_PLACE_CONTAINER = 'ac';\nGUI.CLASS_MAIN = 'main';\nGUI.CLASS_CONTROLLER_ROW = 'cr';\nGUI.CLASS_TOO_TALL = 'taller-than-window';\nGUI.CLASS_CLOSED = 'closed';\nGUI.CLASS_CLOSE_BUTTON = 'close-button';\nGUI.CLASS_CLOSE_TOP = 'close-top';\nGUI.CLASS_CLOSE_BOTTOM = 'close-bottom';\nGUI.CLASS_DRAG = 'drag';\n\nGUI.DEFAULT_WIDTH = 245;\nGUI.TEXT_CLOSED = 'Close Controls';\nGUI.TEXT_OPEN = 'Open Controls';\n\nGUI._keydownHandler = function(e) {\n  if (document.activeElement.type !== 'text' &&\n    (e.which === HIDE_KEY_CODE || e.keyCode === HIDE_KEY_CODE)) {\n    GUI.toggleHide();\n  }\n};\ndom.bind(window, 'keydown', GUI._keydownHandler, false);\n\ncommon.extend(\n  GUI.prototype,\n\n  /** @lends GUI.prototype */\n  {\n\n    /**\n     * Adds a new {@link Controller} to the GUI. The type of controller created\n     * is inferred from the initial value of <code>object[property]</code>. For\n     * color properties, see {@link addColor}.\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} [min] Minimum allowed value\n     * @param {Number} [max] Maximum allowed value\n     * @param {Number} [step] Increment by which to change value\n     * @returns {Controller} The controller that was added to the GUI.\n     * @instance\n     *\n     * @example\n     * // Add a string controller.\n     * var person = {name: 'Sam'};\n     * gui.add(person, 'name');\n     *\n     * @example\n     * // Add a number controller slider.\n     * var person = {age: 45};\n     * gui.add(person, 'age', 0, 100);\n     */\n    add: function(object, property) {\n      return add(\n        this,\n        object,\n        property,\n        {\n          factoryArgs: Array.prototype.slice.call(arguments, 2)\n        }\n      );\n    },\n\n    /**\n     * Adds a new color controller to the GUI.\n     *\n     * @param object\n     * @param property\n     * @returns {Controller} The controller that was added to the GUI.\n     * @instance\n     *\n     * @example\n     * var palette = {\n     *   color1: '#FF0000', // CSS string\n     *   color2: [ 0, 128, 255 ], // RGB array\n     *   color3: [ 0, 128, 255, 0.3 ], // RGB with alpha\n     *   color4: { h: 350, s: 0.9, v: 0.3 } // Hue, saturation, value\n     * };\n     * gui.addColor(palette, 'color1');\n     * gui.addColor(palette, 'color2');\n     * gui.addColor(palette, 'color3');\n     * gui.addColor(palette, 'color4');\n     */\n    addColor: function(object, property) {\n      return add(\n        this,\n        object,\n        property,\n        {\n          color: true\n        }\n      );\n    },\n\n    /**\n     * Removes the given controller from the GUI.\n     * @param {Controller} controller\n     * @instance\n     */\n    remove: function(controller) {\n      // TODO listening?\n      this.__ul.removeChild(controller.__li);\n      this.__controllers.splice(this.__controllers.indexOf(controller), 1);\n      const _this = this;\n      common.defer(function() {\n        _this.onResize();\n      });\n    },\n\n    /**\n     * Removes the root GUI from the document and unbinds all event listeners.\n     * For subfolders, use `gui.removeFolder(folder)` instead.\n     * @instance\n     */\n    destroy: function() {\n      if (this.parent) {\n        throw new Error(\n          'Only the root GUI should be removed with .destroy(). ' +\n          'For subfolders, use gui.removeFolder(folder) instead.'\n        );\n      }\n\n      if (this.autoPlace) {\n        autoPlaceContainer.removeChild(this.domElement);\n      }\n\n      const _this = this;\n      common.each(this.__folders, function(subfolder) {\n        _this.removeFolder(subfolder);\n      });\n\n      dom.unbind(window, 'keydown', GUI._keydownHandler, false);\n\n      removeListeners(this);\n    },\n\n    /**\n     * Creates a new subfolder GUI instance.\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      // 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      const newGuiParams = { 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      newGuiParams.autoPlace = this.autoPlace;\n\n      // Do we have saved appearance data for this folder?\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        // Start me closed if I was closed\n        newGuiParams.closed = this.load.folders[name].closed;\n\n        // Pass down the loaded data\n        newGuiParams.load = this.load.folders[name];\n      }\n\n      const gui = new GUI(newGuiParams);\n      this.__folders[name] = gui;\n\n      const li = addRow(this, gui.domElement);\n      dom.addClass(li, 'folder');\n      return gui;\n    },\n\n    /**\n     * Removes a subfolder GUI instance.\n     * @param {dat.gui.GUI} folder The folder to remove.\n     * @instance\n     */\n    removeFolder: function(folder) {\n      this.__ul.removeChild(folder.domElement.parentElement);\n\n      delete this.__folders[folder.name];\n\n      // Do we have saved appearance data for this folder?\n      if (this.load && // Anything loaded?\n        this.load.folders && // Was my parent a dead-end?\n        this.load.folders[folder.name]) {\n        delete this.load.folders[folder.name];\n      }\n\n      removeListeners(folder);\n\n      const _this = this;\n\n      common.each(folder.__folders, function(subfolder) {\n        folder.removeFolder(subfolder);\n      });\n\n      common.defer(function() {\n        _this.onResize();\n      });\n    },\n\n    /**\n     * Opens the GUI.\n     */\n    open: function() {\n      this.closed = false;\n    },\n\n    /**\n     * Closes the GUI.\n     */\n    close: function() {\n      this.closed = true;\n    },\n\n    /**\n    * Hides the GUI.\n    */\n    hide: function() {\n      this.domElement.style.display = 'none';\n    },\n\n    /**\n    * Shows the GUI.\n    */\n    show: function() {\n      this.domElement.style.display = '';\n    },\n\n\n    onResize: function() {\n      // we debounce this function to prevent performance issues when rotating on tablet/mobile\n      const root = this.getRoot();\n      if (root.scrollable) {\n        const top = dom.getOffset(root.__ul).top;\n        let 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\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      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    onResizeDebounced: common.debounce(function() { this.onResize(); }, 50),\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     * @ignore\n     */\n    remember: function() {\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      const _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     * @returns {dat.gui.GUI} the topmost parent GUI of a nested GUI.\n     * @instance\n     */\n    getRoot: function() {\n      let 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      const toReturn = this.load;\n      toReturn.closed = this.closed;\n\n      // Am I remembering any values?\n      if (this.__rememberedObjects.length > 0) {\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      toReturn.folders = {};\n      common.each(this.__folders, function(element, key) {\n        toReturn.folders[key] = element.getSaveObject();\n      });\n\n      return toReturn;\n    },\n\n    save: function() {\n      if (!this.load.remembered) {\n        this.load.remembered = {};\n      }\n\n      this.load.remembered[this.preset] = getCurrentPreset(this);\n      markPresetModified(this, false);\n      this.saveToLocalStorageIfPossible();\n    },\n\n    saveAs: function(presetName) {\n      if (!this.load.remembered) {\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      this.load.remembered[presetName] = getCurrentPreset(this);\n      this.preset = presetName;\n      addPresetOption(this, presetName, true);\n      this.saveToLocalStorageIfPossible();\n    },\n\n    revert: function(gui) {\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\n        // fire onFinishChange callback\n        if (controller.__onFinishChange) {\n          controller.__onFinishChange.call(controller, controller.getValue());\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    listen: function(controller) {\n      const init = this.__listening.length === 0;\n      this.__listening.push(controller);\n      if (init) {\n        updateDisplays(this.__listening);\n      }\n    },\n\n    updateDisplay: function() {\n      common.each(this.__controllers, function(controller) {\n        controller.updateDisplay();\n      });\n      common.each(this.__folders, function(folder) {\n        folder.updateDisplay();\n      });\n    }\n  }\n);\n\n/**\n * Add a row to the end of the GUI or before another row.\n *\n * @param gui\n * @param [newDom] If specified, inserts the dom content in the new row\n * @param [liBefore] If specified, places the new row before another row\n *\n * @ignore\n */\nfunction addRow(gui, newDom, liBefore) {\n  const li = document.createElement('li');\n  if (newDom) {\n    li.appendChild(newDom);\n  }\n\n  if (liBefore) {\n    gui.__ul.insertBefore(li, liBefore);\n  } else {\n    gui.__ul.appendChild(li);\n  }\n  gui.onResize();\n  return li;\n}\n\nfunction removeListeners(gui) {\n  dom.unbind(window, 'resize', gui.__resizeHandler);\n\n  if (gui.saveToLocalStorageIfPossible) {\n    dom.unbind(window, 'unload', gui.saveToLocalStorageIfPossible);\n  }\n}\n\nfunction markPresetModified(gui, modified) {\n  const opt = gui.__preset_select[gui.__preset_select.selectedIndex];\n\n  if (modified) {\n    opt.innerHTML = opt.value + '*';\n  } else {\n    opt.innerHTML = opt.value;\n  }\n}\n\nfunction augmentController(gui, li, controller) {\n  controller.__li = li;\n  controller.__gui = gui;\n\n  common.extend(controller, /** @lends Controller.prototype */ {\n    /**\n     * @param  {Array|Object} options\n     * @return {Controller}\n     */\n    options: function(options) {\n      if (arguments.length > 1) {\n        const nextSibling = controller.__li.nextElementSibling;\n        controller.remove();\n\n        return add(\n          gui,\n          controller.object,\n          controller.property,\n          {\n            before: nextSibling,\n            factoryArgs: [common.toArray(arguments)]\n          }\n        );\n      }\n\n      if (common.isArray(options) || common.isObject(options)) {\n        const nextSibling = controller.__li.nextElementSibling;\n        controller.remove();\n\n        return add(\n          gui,\n          controller.object,\n          controller.property,\n          {\n            before: nextSibling,\n            factoryArgs: [options]\n          }\n        );\n      }\n    },\n\n    /**\n     * Sets the name of the controller.\n     * @param  {string} name\n     * @return {Controller}\n     */\n    name: function(name) {\n      controller.__li.firstElementChild.firstElementChild.innerHTML = name;\n      return controller;\n    },\n\n    /**\n     * Sets controller to listen for changes on its underlying object.\n     * @return {Controller}\n     */\n    listen: function() {\n      controller.__gui.listen(controller);\n      return controller;\n    },\n\n    /**\n     * Removes the controller from its parent GUI.\n     * @return {Controller}\n     */\n    remove: function() {\n      controller.__gui.remove(controller);\n      return controller;\n    }\n  });\n\n  // All sliders should be accompanied by a box.\n  if (controller instanceof NumberControllerSlider) {\n    const box = new NumberControllerBox(controller.object, controller.property,\n      { min: controller.__min, max: controller.__max, step: controller.__step });\n\n    common.each(['updateDisplay', 'onChange', 'onFinishChange', 'step', 'min', 'max'], function(method) {\n      const pc = controller[method];\n      const pb = box[method];\n      controller[method] = box[method] = function() {\n        const args = Array.prototype.slice.call(arguments);\n        pb.apply(box, args);\n        return pc.apply(controller, args);\n      };\n    });\n\n    dom.addClass(li, 'has-slider');\n    controller.domElement.insertBefore(box.domElement, controller.domElement.firstElementChild);\n  } else if (controller instanceof NumberControllerBox) {\n    const r = function(returned) {\n      // Have we defined both boundaries?\n      if (common.isNumber(controller.__min) && common.isNumber(controller.__max)) {\n        // Well, then lets just replace this with a slider.\n\n        // lets remember if the old controller had a specific name or was listening\n        const oldName = controller.__li.firstElementChild.firstElementChild.innerHTML;\n        const wasListening = controller.__gui.__listening.indexOf(controller) > -1;\n\n        controller.remove();\n        const newController = 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        newController.name(oldName);\n        if (wasListening) newController.listen();\n\n        return newController;\n      }\n\n      return returned;\n    };\n\n    controller.min = common.compose(r, controller.min);\n    controller.max = common.compose(r, controller.max);\n  } else if (controller instanceof BooleanController) {\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  } else if (controller instanceof FunctionController) {\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  } else if (controller instanceof ColorController) {\n    dom.addClass(li, 'color');\n    controller.updateDisplay = common.compose(function(val) {\n      li.style.borderLeftColor = controller.__color.toString();\n      return val;\n    }, controller.updateDisplay);\n\n    controller.updateDisplay();\n  }\n\n  controller.setValue = common.compose(function(val) {\n    if (gui.getRoot().__preset_select && controller.isModified()) {\n      markPresetModified(gui.getRoot(), true);\n    }\n\n    return val;\n  }, controller.setValue);\n}\n\nfunction recallSavedValue(gui, controller) {\n  // Find the topmost GUI, that's where remembered objects live.\n  const root = gui.getRoot();\n\n  // Does the object we're controlling match anything we've been told to\n  // remember?\n  const matchedIndex = root.__rememberedObjects.indexOf(controller.object);\n\n  // Why yes, it does!\n  if (matchedIndex !== -1) {\n    // Let me fetch a map of controllers for thcommon.isObject.\n    let controllerMap = root.__rememberedObjectIndecesToControllers[matchedIndex];\n\n    // Ohp, I believe this is the first controller we've created for this\n    // object. Lets make the map fresh.\n    if (controllerMap === undefined) {\n      controllerMap = {};\n      root.__rememberedObjectIndecesToControllers[matchedIndex] =\n        controllerMap;\n    }\n\n    // Keep track of this controller\n    controllerMap[controller.property] = controller;\n\n    // Okay, now have we saved any values for this controller?\n    if (root.load && root.load.remembered) {\n      const presetMap = root.load.remembered;\n\n      // Which preset are we trying to load?\n      let preset;\n\n      if (presetMap[gui.preset]) {\n        preset = presetMap[gui.preset];\n      } else if (presetMap[DEFAULT_DEFAULT_PRESET_NAME]) {\n        // Uhh, you can have the default instead?\n        preset = presetMap[DEFAULT_DEFAULT_PRESET_NAME];\n      } else {\n        // Nada.\n        return;\n      }\n\n      // Did the loaded object remember thcommon.isObject? &&  Did we remember this particular property?\n      if (preset[matchedIndex] && preset[matchedIndex][controller.property] !== undefined) {\n        // We did remember something for this guy ...\n        const value = preset[matchedIndex][controller.property];\n\n        // And that's what it is.\n        controller.initialValue = value;\n        controller.setValue(value);\n      }\n    }\n  }\n}\n\nfunction add(gui, object, property, params) {\n  if (object[property] === undefined) {\n    throw new Error(`Object \"${object}\" has no property \"${property}\"`);\n  }\n\n  let controller;\n\n  if (params.color) {\n    controller = new ColorController(object, property);\n  } else {\n    const factoryArgs = [object, property].concat(params.factoryArgs);\n    controller = ControllerFactory.apply(gui, factoryArgs);\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  const name = document.createElement('span');\n  dom.addClass(name, 'property-name');\n  name.innerHTML = controller.property;\n\n  const container = document.createElement('div');\n  container.appendChild(name);\n  container.appendChild(controller.domElement);\n\n  const li = addRow(gui, container, params.before);\n\n  dom.addClass(li, GUI.CLASS_CONTROLLER_ROW);\n  if (controller instanceof ColorController) {\n    dom.addClass(li, 'color');\n  } else {\n    dom.addClass(li, typeof controller.getValue());\n  }\n\n  augmentController(gui, li, controller);\n\n  gui.__controllers.push(controller);\n\n  return controller;\n}\n\nfunction getLocalStorageHash(gui, key) {\n  // TODO how does this deal with multiple GUI's?\n  return document.location.href + '.' + key;\n}\n\nfunction addPresetOption(gui, name, setSelected) {\n  const 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\nfunction showHideExplain(gui, explain) {\n  explain.style.display = gui.useLocalStorage ? 'block' : 'none';\n}\n\nfunction addSaveMenu(gui) {\n  const 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  const gears = document.createElement('span');\n  gears.innerHTML = '&nbsp;';\n  dom.addClass(gears, 'button gears');\n\n  // TODO replace with FunctionController\n  const button = document.createElement('span');\n  button.innerHTML = 'Save';\n  dom.addClass(button, 'button');\n  dom.addClass(button, 'save');\n\n  const button2 = document.createElement('span');\n  button2.innerHTML = 'New';\n  dom.addClass(button2, 'button');\n  dom.addClass(button2, 'save-as');\n\n  const button3 = document.createElement('span');\n  button3.innerHTML = 'Revert';\n  dom.addClass(button3, 'button');\n  dom.addClass(button3, 'revert');\n\n  const select = gui.__preset_select = document.createElement('select');\n\n  if (gui.load && gui.load.remembered) {\n    common.each(gui.load.remembered, function(value, key) {\n      addPresetOption(gui, key, key === gui.preset);\n    });\n  } else {\n    addPresetOption(gui, DEFAULT_DEFAULT_PRESET_NAME, false);\n  }\n\n  dom.bind(select, 'change', function() {\n    for (let 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  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    const explain = document.getElementById('dg-local-explain');\n    const localStorageCheckBox = document.getElementById('dg-local-storage');\n    const saveLocally = document.getElementById('dg-save-locally');\n\n    saveLocally.style.display = 'block';\n\n    if (localStorage.getItem(getLocalStorageHash(gui, 'isLocal')) === 'true') {\n      localStorageCheckBox.setAttribute('checked', 'checked');\n    }\n\n    showHideExplain(gui, explain);\n\n    // TODO: Use a boolean controller, fool!\n    dom.bind(localStorageCheckBox, 'change', function() {\n      gui.useLocalStorage = !gui.useLocalStorage;\n      showHideExplain(gui, explain);\n    });\n  }\n\n  const 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    const presetName = prompt('Enter a new preset name.');\n    if (presetName) {\n      gui.saveAs(presetName);\n    }\n  });\n\n  dom.bind(button3, 'click', function() {\n    gui.revert();\n  });\n\n  // div.appendChild(button2);\n}\n\nfunction addResizeHandle(gui) {\n  let pmouseX;\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  function drag(e) {\n    e.preventDefault();\n\n    gui.width += pmouseX - e.clientX;\n    gui.onResize();\n    pmouseX = e.clientX;\n\n    return false;\n  }\n\n  function dragStop() {\n    dom.removeClass(gui.__closeButton, GUI.CLASS_DRAG);\n    dom.unbind(window, 'mousemove', drag);\n    dom.unbind(window, 'mouseup', dragStop);\n  }\n\n  function dragStart(e) {\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  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\nfunction 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  }\n  if (gui.__closeButton) {\n    gui.__closeButton.style.width = w + 'px';\n  }\n}\n\nfunction getCurrentPreset(gui, useInitialValues) {\n  const toReturn = {};\n\n  // For each object I'm remembering\n  common.each(gui.__rememberedObjects, function(val, index) {\n    const savedValues = {};\n\n    // The controllers I've made for thcommon.isObject by property\n    const controllerMap =\n      gui.__rememberedObjectIndecesToControllers[index];\n\n    // Remember each value for each property\n    common.each(controllerMap, function(controller, property) {\n      savedValues[property] = useInitialValues ? controller.initialValue : controller.getValue();\n    });\n\n    // Save the values for thcommon.isObject\n    toReturn[index] = savedValues;\n  });\n\n  return toReturn;\n}\n\nfunction setPresetSelectIndex(gui) {\n  for (let 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\nfunction updateDisplays(controllerArray) {\n  if (controllerArray.length !== 0) {\n    requestAnimationFrame.call(window, function() {\n      updateDisplays(controllerArray);\n    });\n  }\n\n  common.each(controllerArray, function(c) {\n    c.updateDisplay();\n  });\n}\n\nexport default GUI;\n"
  },
  {
    "path": "src/dat/gui/_structure.scss",
    "content": "$nest-margin: 4px;\n$row-height: 27px;\n\n$button-height: 20px;\n\n.dg {\n\n  /** Clear list styles */\n  ul {\n    list-style: none;\n    margin: 0;\n    padding: 0;\n    width: 100%;\n    clear: both;\n  }\n\n  /* Auto-place container */\n  &.ac {\n    position: fixed;\n    top: 0;\n    left: 0;\n    right: 0;\n    height: 0;\n    z-index: 0;\n  }\n\n  &:not(.ac) .main {\n    /** Exclude mains in ac so that we don't hide close button */\n    overflow: hidden;\n  }\n\n  &.main {\n\n    @include transition(opacity, 0.1s, linear);\n\n    &.taller-than-window {\n\n      overflow-y: auto;\n\n      .close-button {\n\n        opacity: 1;\n\n        /* TODO, these are style notes */\n        margin-top: -1px;\n        border-top: 1px solid $border-color;\n\n      }\n\n    }\n\n    ul.closed .close-button {\n      opacity: 1 !important;\n    }\n\n    &:hover .close-button,\n    .close-button.drag {\n      opacity: 1;\n    }\n\n    .close-button {\n      /*opacity: 0;*/\n      @include transition(opacity, 0.1s, linear);\n      border: 0;\n\n      line-height: $button-height - 1;\n      height: $button-height;\n\n      /* TODO, these are style notes */\n      cursor: pointer;\n      text-align: center;\n      background-color: #000;\n      &.close-top {\n        position: relative;\n      }\n      &.close-bottom {\n        position: absolute;\n      }\n      &:hover {\n        background-color: #111;\n      }\n\n    }\n\n  }\n\n  /* Auto-placed GUI's */\n  &.a {\n\n    float: right;\n    margin-right: 15px;\n    overflow-y:visible;\n\n    &.has-save > ul {\n\n      &.close-top {\n        margin-top: 0;\n      }\n      &.close-bottom {\n        margin-top: $row-height;\n      }\n\n      &.closed {\n        margin-top: 0;\n      }\n    }\n\n    .save-row {\n      top: 0;\n      z-index: 1002;\n\n      &.close-top {\n        position: relative;\n      }\n      &.close-bottom {\n        position: fixed;\n      }\n\n    }\n\n  }\n\n  li {\n    @include transition(height, 0.1s, ease-out);\n    @include transition(overflow, 0.1s, linear);\n  }\n\n  /* Line items that don't contain folders. */\n  li:not(.folder) {\n    cursor: auto;\n    height: $row-height;\n    line-height: $row-height;\n    padding: 0 4px 0 5px;\n  }\n\n  li.folder {\n    padding: 0;\n    border-left: $nest-margin solid rgba(0, 0, 0, 0);\n\n  }\n\n  /** Folder names */\n  li.title {\n    cursor: pointer;\n    margin-left: -$nest-margin;\n  }\n\n  /** Hides closed items */\n  .closed li:not(.title),\n  .closed ul li,\n  .closed ul li > * {\n    height: 0;\n    overflow: hidden;\n    border: 0;\n  }\n\n  /** Controller row */\n  .cr {\n    clear: both;\n    padding-left: 3px;\n    height: $row-height;\n    overflow: hidden;\n  }\n\n  /** Name-half (left) */\n  .property-name {\n    cursor: default;\n    float: left;\n    clear: left;\n    width: 40%;\n    overflow: hidden;\n    text-overflow: ellipsis;\n  }\n\n  /** Function controllers can use the entire width */\n  .cr.function .property-name {\n    width: 100%;\n  }\n\n  /** Controller-half (right) */\n  .c {\n    float: left;\n    width: 60%;\n    position: relative;\n  }\n\n  /** Controller placement */\n  .c input[type=text] {\n    border: 0;\n    margin-top: 4px;\n    padding: 3px;\n    width: 100%;\n    float: right;\n  }\n\n  /** Shorter number boxes when slider is present. */\n  .has-slider input[type=text] {\n    width: 30%;\n    /*display: none;*/\n    margin-left: 0;\n  }\n\n  .slider {\n    float: left;\n    width: 66%;\n    margin-left: -5px;\n    margin-right: 0;\n    height: 19px;\n    margin-top: 4px;\n  }\n\n  .slider-fg {\n    height: 100%;\n  }\n\n  .c input[type=checkbox] {\n    margin-top: 7px;\n  }\n\n  .c select {\n    margin-top: 5px;\n  }\n\n  /** Ensure the entire boolean and function row shows a hand */\n  .cr.function,\n  .cr.function .property-name, /* Don't know why I need to be this explicit */\n  .cr.function *,\n  .cr.boolean,\n  .cr.boolean * {\n    cursor: pointer;\n  }\n\n  /** allow overflow for color selector */\n  .cr.color {\n    overflow: visible;\n  }\n\n  .selector {\n    display: none;\n    position: absolute;\n    margin-left: -9px;\n    margin-top: 23px;\n    z-index: 10;\n  }\n\n  .c:hover .selector,\n  .selector.drag {\n    display: block;\n  }\n\n  li.save-row {\n\n    padding: 0;\n\n    .button {\n      display: inline-block;\n      padding: 0px 6px;\n    }\n\n  }\n\n  &.dialogue {\n    background-color: #222;\n    width: 460px;\n    padding: 15px;\n    font-size: 13px;\n    line-height: 15px;\n  }\n\n}\n\n/* TODO Separate style and structure */\n#dg-new-constructor {\n  padding: 10px;\n  color: #222;\n  font-family: Monaco, monospace;\n  font-size: 10px;\n  border: 0;\n  resize: none;\n  box-shadow: inset 1px 1px 1px #888;\n  word-wrap: break-word;\n  margin: 12px 0;\n  display: block;\n  width: 440px;\n  overflow-y: scroll;\n  height: 100px;\n  position: relative;\n}\n\n#dg-local-explain {\n  display: none;\n  font-size: 11px;\n  line-height: 17px;\n  border-radius: 3px;\n  background-color: #333;\n  padding: 8px;\n  margin-top: 10px;\n  code {\n    font-size: 10px;\n  }\n}\n\n#dat-gui-save-locally {\n  display: none;\n}\n"
  },
  {
    "path": "src/dat/gui/saveDialogue.html.js",
    "content": "const saveDialogContents = `<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\nexport default saveDialogContents;\n"
  },
  {
    "path": "src/dat/gui/style.scss",
    "content": "$background-color: #1a1a1a;\n\n$hover-lighten: 5%;\n$border-lighten: 7%;\n$active-lighten: 10%;\n\n$number-color: #2FA1D6;\n$boolean-color: #806787;\n$string-color: #1ed36f;\n$function-color: #e61d5f;\n$save-row-color: #dad5cb;\n$button-color: darken($save-row-color, 10%);\n$border-color: lighten($background-color, $border-lighten);\n$input-color: lighten($background-color, 8.5%);\n\n@mixin transition($prop, $time, $curve) {\n  -webkit-transition: $prop $time $curve;\n  -o-transition: $prop $time $curve;\n  -moz-transition: $prop $time $curve;\n  transition: $prop $time $curve;\n}\n\n@mixin gradient($a, $b) {\n  background: -webkit-gradient(linear, 0% 0%, 0% 100%, from($a), to($b));\n  background: -o-gradient(linear, 0% 0%, 0% 100%, from($a), to($b));\n  background: -moz-gradient(linear, 0% 0%, 0% 100%, from($a), to($b));\n}\n\n@mixin button() {\n  margin-left: 5px;\n  margin-top: 1px;\n  border-radius: 2px;\n  font-size: 9px;\n  line-height: 7px;\n  padding: 4px 4px 5px 4px;\n  background: $button-color;\n  color: #fff;\n  text-shadow: 0 1px 0 darken($button-color, 10%);\n  box-shadow: 0 -1px 0 darken($button-color, 10%);\n  cursor: pointer;\n}\n\n@mixin gears() {\n  background: $button-color 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;\n  height: 7px;\n  width: 8px;\n}\n\n@import \"structure\";\n\n/** Main type */\n.dg {\n\n  color: #eee;\n  font: 11px 'Lucida Grande', sans-serif;\n  text-shadow: 0 -1px 0 #111;\n\n  /** Auto place */\n  &.main {\n\n    /** Scrollbar */\n    &::-webkit-scrollbar {\n      width: 5px;\n      background: $background-color;\n    }\n    &::-webkit-scrollbar-corner {\n      height: 0;\n      display: none;\n    }\n    &::-webkit-scrollbar-thumb {\n      border-radius: 5px;\n      background: lighten($background-color, 30%);\n    }\n\n  }\n\n  li {\n\n    &:not(.folder) {\n      background: $background-color;\n      border-bottom: 1px solid $border-color;\n    }\n\n    &.save-row {\n\n      line-height: 25px;\n      background: $save-row-color;\n      border: 0;\n\n      select {\n        margin-left: 5px;\n        width: 108px;\n\n      }\n\n      .button {\n\n        &.gears {\n          @include gears;\n        }\n\n        @include button;\n\n        &:hover {\n          background-color: darken($button-color, 5%);\n          box-shadow: 0 -1px 0 darken($button-color, 10%);\n        }\n\n      }\n\n    }\n\n    &.folder {\n      border-bottom: 0;\n    }\n\n    &.title {\n      padding-left: 16px;\n      background: #000 url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat;\n      cursor: pointer;\n      border-bottom: 1px solid rgba(255, 255, 255, 0.2);\n    }\n\n  }\n\n  .closed li.title {\n    background-image: url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlGIWqMCbWAEAOw==);\n  }\n\n  /* Controller row, <li> */\n  .cr {\n\n    &.boolean {\n      border-left: 3px solid $boolean-color;\n    }\n\n    &.color {\n      border-left: 3px solid;\n    }\n\n    &.function {\n      border-left: 3px solid $function-color;\n    }\n\n    &.number {\n      border-left: 3px solid $number-color;\n      input[type=text] {\n        color: $number-color;\n      }\n    }\n\n    &.string {\n      border-left: 3px solid $string-color;\n      input[type=text] {\n        color: $string-color;\n      }\n    }\n\n    &.function:hover,\n    &.boolean:hover {\n      background: #111;\n    }\n\n  }\n\n  /** Controllers */\n  .c {\n\n    input[type=text] {\n\n      background: $input-color;\n      outline: none;\n      &:hover {\n        background: lighten($input-color, $hover-lighten);\n      }\n      &:focus {\n        background: lighten($input-color, $active-lighten);\n        color: #fff;\n      }\n\n    }\n\n    .slider {\n      background: $input-color;\n      cursor: ew-resize;\n    }\n\n    .slider-fg {\n      background: $number-color;\n      max-width: 100%;\n    }\n\n    .slider:hover {\n      background: lighten($input-color, $hover-lighten);\n      .slider-fg {\n        background: lighten($number-color, $hover-lighten);\n      }\n    }\n\n  }\n\n}\n"
  },
  {
    "path": "src/dat/index.js",
    "content": "/**\n * dat-gui JavaScript Controller Library\n * https://github.com/dataarts/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\nimport Color from './color/Color';\nimport math from './color/math';\nimport interpret from './color/interpret';\n\nimport Controller from './controllers/Controller';\nimport BooleanController from './controllers/BooleanController';\nimport OptionController from './controllers/OptionController';\nimport StringController from './controllers/StringController';\nimport NumberController from './controllers/NumberController';\nimport NumberControllerBox from './controllers/NumberControllerBox';\nimport NumberControllerSlider from './controllers/NumberControllerSlider';\nimport FunctionController from './controllers/FunctionController';\nimport ColorController from './controllers/ColorController';\n\nimport domImport from './dom/dom';\nimport GUIImport from './gui/GUI';\n\nexport const color = {\n  Color: Color,\n  math: math,\n  interpret: interpret\n};\n\nexport const controllers = {\n  Controller: Controller,\n  BooleanController: BooleanController,\n  OptionController: OptionController,\n  StringController: StringController,\n  NumberController: NumberController,\n  NumberControllerBox: NumberControllerBox,\n  NumberControllerSlider: NumberControllerSlider,\n  FunctionController: FunctionController,\n  ColorController: ColorController\n};\n\nexport const dom = { dom: domImport };\n\nexport const gui = { GUI: GUIImport };\n\nexport const GUI = GUIImport;\n\nexport default {\n  color,\n  controllers,\n  dom,\n  gui,\n  GUI\n};\n"
  },
  {
    "path": "src/dat/utils/common.js",
    "content": "/**\n * dat-gui JavaScript Controller Library\n * https://github.com/dataarts/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\nconst ARR_EACH = Array.prototype.forEach;\nconst 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\nconst Common = {\n  BREAK: {},\n\n  extend: function(target) {\n    this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n      const keys = this.isObject(obj) ? Object.keys(obj) : [];\n      keys.forEach(function(key) {\n        if (!this.isUndefined(obj[key])) {\n          target[key] = obj[key];\n        }\n      }.bind(this));\n    }, this);\n\n    return target;\n  },\n\n  defaults: function(target) {\n    this.each(ARR_SLICE.call(arguments, 1), function(obj) {\n      const keys = this.isObject(obj) ? Object.keys(obj) : [];\n      keys.forEach(function(key) {\n        if (this.isUndefined(target[key])) {\n          target[key] = obj[key];\n        }\n      }.bind(this));\n    }, this);\n\n    return target;\n  },\n\n  compose: function() {\n    const toCall = ARR_SLICE.call(arguments);\n    return function() {\n      let args = ARR_SLICE.call(arguments);\n      for (let 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    if (!obj) {\n      return;\n    }\n\n    if (ARR_EACH && obj.forEach && obj.forEach === ARR_EACH) {\n      obj.forEach(itr, scope);\n    } else if (obj.length === obj.length + 0) { // Is number but not NaN\n      let key;\n      let l;\n      for (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      }\n    } else {\n      for (const 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  // if the function is called repeatedly, wait until threshold passes until we execute the function\n  debounce: function(func, threshold, callImmediately) {\n    let timeout;\n\n    return function() {\n      const obj = this;\n      const args = arguments;\n      function delayed() {\n        timeout = null;\n        if (!callImmediately) func.apply(obj, args);\n      }\n\n      const callNow = callImmediately || !timeout;\n\n      clearTimeout(timeout);\n      timeout = setTimeout(delayed, threshold);\n\n      if (callNow) {\n        func.apply(obj, args);\n      }\n    };\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 isNaN(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 obj instanceof Function;\n  }\n\n};\n\nexport default Common;\n"
  },
  {
    "path": "src/dat/utils/css.js",
    "content": "/**\n * dat-gui JavaScript Controller Library\n * https://github.com/dataarts/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\nconst css = {\n  load: function(url, indoc) {\n    const doc = indoc || document;\n    const 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\n  inject: function(cssContent, indoc) {\n    const doc = indoc || document;\n    const injected = document.createElement('style');\n    injected.type = 'text/css';\n    injected.innerHTML = cssContent;\n    const head = doc.getElementsByTagName('head')[0];\n    try {\n      head.appendChild(injected);\n    } catch (e) { // Unable to inject CSS, probably because of a Content Security Policy\n    }\n  }\n};\n\nexport default css;\n"
  },
  {
    "path": "src/dat/utils/requestAnimationFrame.js",
    "content": "/**\n * dat-gui JavaScript Controller Library\n * https://github.com/dataarts/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\nfunction requestAnimationFrame(callback) {\n  setTimeout(callback, 1000 / 60);\n}\n\nexport default window.requestAnimationFrame ||\n    window.webkitRequestAnimationFrame ||\n    window.mozRequestAnimationFrame ||\n    window.oRequestAnimationFrame ||\n    window.msRequestAnimationFrame ||\n    requestAnimationFrame;\n"
  },
  {
    "path": "tests/index.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\n    \"http://www.w3.org/TR/html4/loose.dtd\">\n<html>\n<head>\n\n  <link rel=\"stylesheet\" href=\"qunit.css\" type=\"text/css\" media=\"screen\"/>\n  <script type=\"text/javascript\" src=\"qunit.js\"></script>\n  <script type=\"text/javascript\" src=\"jquery.js\"></script>\n\n  <script type=\"text/javascript\" src=\"../build/dat.gui.js\"></script>\n  <script type=\"text/javascript\">\n\n  $.noConflict();\n  jQuery(document).ready(function($) {\n    var math = dat.color.math;\n    var interpret = dat.color.interpret;\n    var Color = dat.color.Color;\n    var dom = dat.dom.dom;\n    var Controller = dat.controllers.Controller;\n    var BooleanController = dat.controllers.BooleanController;\n    var OptionController = dat.controllers.OptionController;\n    var StringController = dat.controllers.StringController;\n    var NumberController = dat.controllers.NumberController;\n    var NumberControllerBox = dat.controllers.NumberControllerBox;\n    var NumberControllerSlider = dat.controllers.NumberControllerSlider;\n    var FunctionController = dat.controllers.FunctionController;\n    var ColorController = dat.controllers.ColorController;\n    var GUI = dat.gui.GUI;\n\n\n    module(\"Color Math\");\n\n    test(\"rgb_to_hex\", function() {\n\n      equal(\n          math.rgb_to_hex(100, 255, 20),\n          0x64ff14\n      );\n\n    });\n\n    test(\"component_from_hex\", function() {\n\n      equal(\n          math.component_from_hex(0xff3366, 0),\n          0x66,\n          'get blue'\n      );\n\n      equal(\n          math.component_from_hex(0xff3366, 1),\n          0x33,\n          'get green'\n      );\n\n      equal(\n          math.component_from_hex(0xff3366, 2),\n          0xff,\n          'get red'\n      );\n\n    });\n\n    test(\"hex_with_component\", function() {\n\n      equal(\n          math.hex_with_component(0x002203, 0, 0x32),\n          0x002232,\n          'replace blue'\n      );\n\n      equal(\n          math.hex_with_component(0x002203, 1, 0x32),\n          0x003203,\n          'replace green'\n      );\n\n      equal(\n          math.hex_with_component(0x002203, 2, 0x32),\n          0x322203,\n          'replace red'\n      );\n\n    });\n\n    test(\"rgb_to_hsv\", function() {\n\n      match(\n          math.rgb_to_hsv(173, 52, 141),\n          {\n            h: 315.86776859504135,\n            s: 0.6994219653179191,\n            v: 0.6784313725490196\n          });\n\n      match(\n          math.rgb_to_hsv(10, 10, 10),\n          {\n            h: NaN,\n            s: 0,\n            v: 0.0392156862745098\n          }, 'grayscale');\n\n      match(\n          math.rgb_to_hsv(0, 0, 0),\n          {\n            h: NaN,\n            s: 0,\n            v: 0\n          }, 'black');\n\n    });\n\n    test(\"hsv_to_rgb\", function() {\n\n      match(\n          math.hsv_to_rgb(255, 0.85, 0.46),\n          {\n            r: 42.52125000000001,\n            g: 17.595000000000006,\n            b: 117.30000000000001\n          });\n\n      match(\n          math.hsv_to_rgb(0, 0, 0.46),\n          {\n            r: 117.30000000000001,\n            g: 117.30000000000001,\n            b: 117.30000000000001\n          }, 'grayscale');\n\n    });\n\n    module(\"Color Interpretations\");\n\n    test(\"CSS Strings\", function() {\n\n      match(\n          interpret('#ccc'),\n          {\n            hex: 0xcccccc,\n            space: 'HEX',\n            conversionName: 'THREE_CHAR_HEX'\n          },\n          'THREE_CHAR_HEX'\n      );\n\n      match(\n          interpret('#f09'),\n          {\n            hex: 0xff0099,\n            space: 'HEX',\n            conversionName: 'THREE_CHAR_HEX'\n          },\n          'THREE_CHAR_HEX'\n      );\n\n      match(\n          interpret('#0f93cd'),\n          {\n            hex: 0x0f93cd,\n            space: 'HEX',\n            conversionName: 'SIX_CHAR_HEX'\n          },\n          'SIX_CHAR_HEX'\n      );\n\n      match(\n          interpret('rgba(255,10,200,0.3)'),\n          {\n            r: 255,\n            g: 10,\n            b: 200,\n            a: 0.3,\n            space: 'RGB',\n            conversionName: 'CSS_RGBA'\n          },\n          'CSS_RGBA'\n      );\n\n      match(\n          interpret('rgb(255,10,200)'),\n          {\n            r: 255,\n            g: 10,\n            b: 200,\n            space: 'RGB',\n            conversionName: 'CSS_RGB'\n          },\n          'CSS_RGB'\n      );\n\n    });\n\n    test(\"Other\", function() {\n\n      match(\n          interpret(0xff3322),\n          {\n            hex: 0xff3322,\n            space: 'HEX',\n            conversionName: 'HEX'\n          },\n          'HEX'\n      );\n\n      match(\n          interpret([255, 255, 0]),\n          {\n            r: 255,\n            g: 255,\n            b: 0,\n            space: 'RGB',\n            conversionName: 'RGB_ARRAY'\n          },\n          'RGB_ARRAY'\n      );\n\n\n      match(\n          interpret([0, 110, 255, 0.3]),\n          {\n            r: 0,\n            g: 110,\n            b: 255,\n            a: 0.3,\n            space: 'RGB',\n            conversionName: 'RGBA_ARRAY'\n          },\n          'RGBA_ARRAY'\n      );\n\n      match(\n          interpret({\n                r: 255,\n                g: 255,\n                b: 200\n              }),\n          {\n            r: 255,\n            g: 255,\n            b: 200,\n            space: 'RGB',\n            conversionName: 'RGB_OBJ'\n          },\n          'RGB_OBJ'\n      );\n\n      match(\n          interpret({\n                r: 255,\n                g: 255,\n                b: 200,\n                a: 0.2\n              }),\n          {\n            r: 255,\n            g: 255,\n            b: 200,\n            a: 0.2,\n            space: 'RGB',\n            conversionName: 'RGBA_OBJ'\n          },\n          'RGBA_OBJ'\n      );\n\n      match(\n          interpret({\n                h: 360,\n                s: 1,\n                v: 0.5\n              }),\n          {\n            h: 360,\n            s: 1,\n            v: 0.5,\n            space: 'HSV',\n            conversionName: 'HSV_OBJ'\n          },\n          'HSV_OBJ'\n      );\n\n      match(\n          interpret({\n                h: 360,\n                s: 1,\n                v: 0.5,\n                a: 0.8\n              }),\n          {\n            h: 360,\n            s: 1,\n            v: 0.5,\n            a: 0.8,\n            space: 'HSV',\n            conversionName: 'HSVA_OBJ'\n          },\n          'HSVA_OBJ'\n      );\n\n      match(\n          interpret('Failuuureeee'),\n          false,\n          'FAIL'\n      );\n\n    });\n\n    module(\"Color Objects\");\n\n    test(\"Creation\", function() {\n\n      var c = new Color(255, 100, 20, 0.3);\n\n      equal(c.r, 255, 'red');\n      equal(c.g, 100, 'green');\n      equal(c.b, 20, 'blue');\n      equal(c.a, 0.3, 'alpha');\n\n      equal(c.hex, 0xff6414, 'hex');\n\n      equal(Math.round(c.h), 20, 'hue');\n      equal(Math.round(c.s * 100), 92, 'saturation');\n      equal(Math.round(c.v * 100), 100, 'value');\n\n    });\n\n    test(\"RGB Modification\", function() {\n\n      var c = new Color(255, 100, 20, 0.3);\n\n      c.r -= 100;\n\n      equal(c.r, 155, 'green');\n      equal(c.g, 100, 'green');\n      equal(c.b, 20, 'blue');\n      equal(c.a, 0.3, 'alpha');\n\n      equal(c.hex, 0x9b6414, 'hex');\n\n      equal(Math.round(c.h), 36, 'hue');\n      equal(Math.round(c.s * 100), 87, 'saturation');\n      equal(Math.round(c.v * 100), 61, 'value');\n\n    });\n\n    test(\"RGB Modification\", function() {\n\n      var c = new Color(255, 100, 20, 0.3);\n\n      c.r -= 100;\n\n      equal(c.r, 155, 'green');\n      equal(c.g, 100, 'green');\n      equal(c.b, 20, 'blue');\n      equal(c.a, 0.3, 'alpha');\n\n      equal(c.hex, 0x9b6414, 'hex');\n\n      equal(Math.round(c.h), 36, 'hue');\n      equal(Math.round(c.s * 100), 87, 'saturation');\n      equal(Math.round(c.v * 100), 61, 'value');\n\n    });\n\n    test(\"Setting RGB, Modifying HSV\", function() {\n\n      var c = new Color(255, 0, 100);\n\n      c.s = 1;\n\n      equal(c.r, 255);\n      equal(c.g, 0);\n      equalish(c.b, 100, 0.00001);\n      equal(c.a, 1);\n\n    });\n\n\n    test(\"Setting HSV, Modifying RGB\", function() {\n\n      var c = new Color({ h: 340, s: 0.3, v: 0.9 });\n\n      c.g = 0;\n\n      equal(c.h, 312);\n      equal(c.s, 1);\n      equal(c.v, 0.9);\n      equal(c.a, 1);\n\n    });\n\n    test(\"Grayscale Hue\", function() {\n\n      var c = new Color(120, 100, 20, 0.3);\n\n      var prevHue = c.h;\n\n      equal(typeof c.h, 'number');\n\n      // Make graysale\n      c.g = c.b = c.r;\n\n      equal(c.h, prevHue, 'grayscale, hue intact');\n\n    });\n\n    test(\"Black Hue\", function() {\n\n      var c = new Color(120, 100, 20, 0.3);\n\n      var prevHue = c.h;\n      console.log('heh?');\n\n      c.r = 0;\n      c.b = 0;\n      c.g = 0;\n\n      equal(c.h, prevHue, 'black, hue intact');\n\n    });\n\n\t\tfunction match(a, b, msg) {\n\n\t\t\tfor (var i in b) {\n\t\t\t\tif (b[i] !== b[i]) {\n\t\t\t\t\tok(a[i] !== a[i], msg)\n\t\t\t\t} else {\n\t\t\t\t\tequal(b[i], a[i], msg);\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\n\t\tfunction equalish(a, b, tolerance, label) {\n\t\t\treturn ok(Math.abs(a - b) < tolerance, label);\n\t\t}\n\n\n\n\n    function initObject() {\n      return {\n        numberProperty: 10,\n        stringProperty: 'foo',\n        booleanProperty: false,\n        functionProperty: function() {\n          // do something\n        },\n        anotherBooleanProperty: true,\n        colorProperty: \"#ffffff\"\n      };\n    }\n\n    var hidden = document.createElement('div');\n    hidden.style.display = 'none';\n    document.body.appendChild(hidden);\n\n    module(\"Controller\");\n\n    test(\"Retrieves values\", function() {\n\n      var object = initObject();\n\n      var c1 = new Controller(object, 'numberProperty');\n      var c2 = new Controller(object, 'stringProperty');\n      var c3 = new Controller(object, 'booleanProperty');\n      var c4 = new Controller(object, 'functionProperty');\n\n      equal(c1.getValue(), object.numberProperty, \"Number property\");\n      equal(c2.getValue(), object.stringProperty, \"String property\");\n      equal(c3.getValue(), object.booleanProperty, \"Boolean property\");\n      equal(c4.getValue(), object.functionProperty, \"Function property\");\n\n    });\n\n    test(\"Sets values\", function() {\n      var object = initObject();\n\n      var c1 = new Controller(object, 'numberProperty');\n      c1.setValue(40);\n\n      equal(40, object.numberProperty);\n\n    });\n\n    module(\"BooleanController\");\n\n    test(\"Acknowledges original values\", function() {\n\n      var object = initObject();\n      var c1 = new BooleanController(object, 'booleanProperty');\n      var c2 = new BooleanController(object, 'anotherBooleanProperty');\n\n      equal(c1.__checkbox.checked,\n          object.booleanProperty);\n\nconsole.log(c2.__checkbox.getAttribute('checked'));\n\n      equal(c2.__checkbox.getAttribute('checked') === 'checked',\n          object.anotherBooleanProperty);\n\n    });\n\n    test(\"Modifies values (starting true)\", function() {\n\n      var object = { booleanProperty: true };\n\n      var c1 = new BooleanController(object, 'booleanProperty');\n\n      // Must append this to body for click to work\n      hidden.appendChild(c1.domElement);\n\n      dom.fakeEvent(c1.__checkbox, 'click');\n      equal(false, object.booleanProperty, 'changes');\n      equal(false, c1.__checkbox.checked, 'checkbox valid');\n\n      dom.fakeEvent(c1.__checkbox, 'click');\n      equal(true, object.booleanProperty, 'changes back');\n\n      equal(true, c1.__checkbox.checked, 'checkbox valid');\n\n\n\n      object.booleanProperty = false;\n      dom.fakeEvent(c1.__checkbox, 'click');\n      equal(false, object.booleanProperty, 'maintains sync');\n      equal(false, c1.__checkbox.checked, 'checkbox valid');\n\n    });\n\n    test(\"Modifies values (starting false)\", function() {\n\n      var object = { booleanProperty: false };\n\n      var c1 = new BooleanController(object, 'booleanProperty');\n\n      // Must append this to body for click to work\n      hidden.appendChild(c1.domElement);\n\n      dom.fakeEvent(c1.__checkbox, 'click');\n      equal(true, object.booleanProperty, 'changes');\n      equal(true, c1.__checkbox.checked, 'checkbox valid');\n\n      dom.fakeEvent(c1.__checkbox, 'click');\n      equal(false, object.booleanProperty, 'changes back');\n      equal(false, c1.__checkbox.checked, 'checkbox valid');\n\n      object.booleanProperty = true;\n      dom.fakeEvent(c1.__checkbox, 'click');\n      equal(true, object.booleanProperty, 'maintains sync');\n      equal(true, c1.__checkbox.checked, 'checkbox valid');\n\n\n    });\n\n    module(\"OptionController\");\n\n    test(\"Populates with string array\", function() {\n      var object = initObject();\n      var options = ['Jono', 'Doug', 'George'];\n\n      var c1 = new OptionController(object, 'stringProperty',\n          options);\n\n//        hidden.appendChild(c1.domElement);\n\n      $(c1.__select).children().each(function(index) {\n        equal(options[index], this.innerHTML);\n        equal(options[index], $(this).attr('value'));\n      });\n\n    });\n\n    test(\"Populates with map\", function() {\n      var object = initObject();\n      var options = {\n        'Small': 0,\n        'Medium': 2,\n        'Large': 10\n      };\n\n      var c1 = new OptionController(object, 'stringProperty',\n          options);\n\n//        hidden.appendChild(c1.domElement);\n\n      $(c1.__select).children().each(function(index) {\n        equal(options[this.innerHTML], $(this).attr('value'));\n      });\n\n    });\n\n    test(\"Acknowledges original value\", function() {\n      var object = initObject();\n      var options = {\n        'Small': 0,\n        'Medium': 2,\n        'Large': object.numberProperty\n      };\n\n      var c1 = new OptionController(object, 'numberProperty',\n          options);\n\n//        hidden.appendChild(c1.domElement);\n\n      equal($(c1.__select).val(), object.numberProperty);\n\n    });\n\n    test(\"Modifies values\", function() {\n      var object = initObject();\n      var options = {\n        'Small': 0,\n        'Medium': 2,\n        'Large': 10\n      };\n\n      var c1 = new OptionController(object, 'numberProperty',\n          options);\n\n      var c2 = new OptionController(object, 'stringProperty', ['a', 'b', 'c']);\n\n//        hidden.appendChild(c1.domElement);\n\n      var elem = $(c1.__select).val(options['Medium'])[0];\n      dom.fakeEvent(elem, 'change');\n\n      equal(options['Medium'], object.numberProperty, 'Number property');\n\n      elem = $(c2.__select).val('b')[0];\n      dom.fakeEvent(elem, 'change');\n\n      equal('b', object.stringProperty, 'String property');\n\n    });\n\n    module(\"StringController\");\n\n    test(\"Acknowledges original value\", function() {\n      var object = initObject();\n      var c1 = new StringController(object, 'stringProperty');\n\n      equal($(c1.__input).val(), object.stringProperty);\n\n    });\n\n    test(\"Modifies values\", function() {\n      var object = initObject();\n      var c1 = new StringController(object, 'stringProperty');\n\n      var newVal = (new Date()).toJSON();\n\n      var elem = $(c1.__input).val(newVal)[0];\n      dom.fakeEvent(elem, 'change');\n\n      equal(newVal, object.stringProperty);\n\n    });\n\n    module(\"NumberController\");\n\n    test(\"Constraints\", function() {\n      var object = initObject();\n      var params = { min: 0, max: 10, step: 2 };\n\n      var c1 = new NumberController(object,\n          'numberProperty', params);\n\n      c1.setValue(12);\n      equal(object.numberProperty, params.max, \"Maximum values\");\n\n      c1.setValue(-20);\n      equal(object.numberProperty, params.min, \"Minimum values\");\n\n      c1.setValue(1);\n      equal(object.numberProperty, 2, \"Steps\");\n\n    });\n\n    module(\"NumberControllerBox\");\n\n    test(\"Acknowledges original value\", function() {\n      var object = initObject();\n      var c1 = new NumberControllerBox(object,\n          'numberProperty');\n\n//        var newVal = Date.now();\n//\n//        $(c1.__input).val(newVal).trigger('change');\n//\n      equal($(c1.__input).val(), object.numberProperty.toString());\n\n    });\n\n    test(\"Modifies value\", function() {\n      var object = initObject();\n      var c1 = new NumberControllerBox(object,\n          'numberProperty');\n\n      var newVal = Date.now();\n\n      var elem = $(c1.__input).val(newVal)[0];\n      dom.fakeEvent(elem, 'change');\n\n      equal(typeof object.numberProperty, 'number');\n      equal(object.numberProperty, newVal);\n\n    });\n\n\n    test(\"Handles invalid input\", function() {\n      var object = initObject();\n      var c1 = new NumberControllerBox(object,\n          'numberProperty');\n\n      var newVal = '~! I98* omg this is not a N&^&*^umber.e-083.9';\n      var prevVal = object.numberProperty;\n\n      var elem = $(c1.__input).val(newVal)[0];\n      dom.fakeEvent(elem, 'change');\n\n      equal(typeof object.numberProperty, 'number');\n      equal(object.numberProperty, prevVal);\n\n    });\n\n\n    test(\"Handles drag\", function() {\n\n      var object = { numberProperty: 0 };\n      var params = { step: Math.random() * 21 };\n\n      var c1 = new NumberControllerBox(object,\n          'numberProperty', params);\n\n      var prevVal = object.numberProperty;\n      var disp = Math.round(Math.random() * 100);\n\n      var elem = c1.__input;\n\n      dom.fakeEvent(elem, 'mousedown', {\n        x: 0,\n        y: 0\n      });\n      dom.fakeEvent(window, 'mousemove', {\n        x: 0,\n        y: disp\n      });\n      dom.fakeEvent(window, 'mouseup');\n\n      equal(object.numberProperty, prevVal + params.step * -disp);\n\n    });\n\n    module(\"NumberControllerSlider\");\n\n    test(\"Acknowledges original value\", function() {\n\n      var object = initObject();\n\n      var min = 0, max = 50;\n\n      var c1 = new NumberControllerSlider(object, 'numberProperty', min, max);\n\n      document.body.appendChild(c1.domElement);\n\n      var bw = dom.getWidth(c1.__background);\n      var fw = dom.getWidth(c1.__foreground);\n\n      document.body.removeChild(c1.domElement);\n\n      equalish(fw/bw, (object.numberProperty - min) / (max - min), 0.01, 'Slider width indicative of value.');\n\n    });\n\n    test(\"Modifies values\", function() {\n\n      var object = initObject();\n\n      var min = 0, max = 50;\n\n      var c1 = new NumberControllerSlider(object, 'numberProperty', min, max, 1);\n\n      document.body.appendChild(c1.domElement);\n\n      var o = dom.getOffset(c1.domElement);\n      var w = dom.getWidth(c1.domElement);\n\n      dom.fakeEvent(c1.__background, 'mousedown', {\n        x: o.left + w/2,\n        y: o.top\n      });\n\n      var bw = dom.getWidth(c1.__background);\n      var fw = dom.getWidth(c1.__foreground);\n\n      equal(object.numberProperty, (min+max)/2, 'Mouse down');\n\n      equalish(fw/bw, (object.numberProperty - min) / (max - min), 0.01, 'Slider width still indicative of value.');\n\n      dom.fakeEvent(window, 'mousemove', {\n        x: o.left,\n        y: o.top\n      });\n\n      fw = dom.getWidth(c1.__foreground);\n\n\n      equal(object.numberProperty, min, 'Mouse move');\n\n      equal(fw/bw, (object.numberProperty - min) / (max - min), 'Slider width still indicative of value.');\n\n\n      dom.fakeEvent(window, 'mouseup');\n\n      dom.fakeEvent(window, 'mousemove', {\n        x: o.left+w,\n        y: o.top\n      });\n\n      equal(object.numberProperty, min, 'Mouse releases drag');\n\n      document.body.removeChild(c1.domElement);\n\n\n    });\n\n    module(\"ColorController\");\n\n    test(\"Get Color\", function() {\n      var object = initObject();\n      var c1 = new ColorController(object, 'colorProperty');\n      document.body.appendChild(c1.domElement);\n\n      var input = c1.domElement.getElementsByTagName(\"input\")[0];\n      equal(input.value, object.colorProperty, \"Input value is the same as the colorProperty\");\n\n      document.body.removeChild(c1.domElement);\n    });\n\n/*\n    test(\"Set Color\", function() {\n      // get from click, get from hover\n      var object = initObject();\n      var c1 = new ColorController(object, 'colorProperty');\n\n      document.body.appendChild(c1.domElement);\n      var input = c1.domElement.getElementsByTagName(\"input\")[0];\n\n      // type in color\n      input.value = \"#ff0\";\n\n      // TODO fake events for keys not working\n      dom.fakeEvent(input, 'keydown', { keyCode: 13 });\n\n      // click sv field\n\n      // click hue slider\n\n      equal(1,0, \"TODO: add set color tests.\");\n\n      document.body.removeChild(c1.domElement);\n    });\n*/\n    module(\"Controller Events\");\n\n    test(\"onChange\", function() {\n\n      var object = initObject();\n\n      var c0 = new NumberControllerSlider(object, 'numberProperty');\n      var c1 = new NumberControllerBox(object, 'numberProperty');\n      var c2 = new StringController(object, 'stringProperty');\n      var c3 = new BooleanController(object, 'booleanProperty');\n      var c4 = new FunctionController(object, 'functionProperty');\n      var c5 = new OptionController(object, 'stringProperty', [0,1,2]);\n\n      var c0_changed = false;\n      var c1_changed = false;\n      var c2_changed = false;\n      var c3_changed = false;\n      var c4_changed = false;\n      var c5_changed = false;\n\n      c0.onChange(function() {\n        c0_changed = true;\n      });\n\n      c1.onChange(function() {\n        c1_changed = true;\n      });\n\n      c2.onChange(function() {\n        c2_changed = true;\n      });\n\n      c3.onChange(function() {\n        c3_changed = true;\n      });\n\n      c4.onChange(function() {\n        c4_changed = true;\n      });\n\n      c5.onChange(function() {\n        c5_changed = true;\n      });\n\n      hidden.appendChild(c3.domElement);\n\n      c0.setValue(0.5);\n      c1.setValue(10);\n      c2.setValue('hey');\n      c3.setValue(false);\n      c4.fire();\n      c5.setValue('yo');\n\n      ok(c1_changed, 'NumberControllerSlider');\n      ok(c1_changed, 'NumberControllerBox');\n      ok(c2_changed, 'StringController');\n      ok(c3_changed, 'BooleanController');\n      ok(c4_changed, 'FunctionController');\n      ok(c5_changed, 'OptionController');\n\n    });\n\n    test(\"onFinishChange\", function() {\n\n      var object = initObject();\n\n      var min = 0, max = 100;\n\n      var c0 = new NumberControllerSlider(object, 'numberProperty', min, max);\n      var c1 = new NumberControllerBox(object, 'numberProperty');\n      var c2 = new StringController(object, 'stringProperty');\n\n      var c0_changed = false;\n      var c1_changed = false;\n      var c2_changed = false;\n\n      c0.onFinishChange(function() {\n        c0_changed = true;\n      });\n\n      document.body.appendChild(c0.domElement);\n\n      var o = dom.getOffset(c0.domElement);\n      var w = dom.getWidth(c0.domElement);\n\n      dom.fakeEvent(c0.__background, 'mousedown', {\n        x: o.left + w/2,\n        y: o.top\n      });\n\n      ok(!c0_changed, 'NumberControllerSlider didn\\'t jump the gun ...');\n\n      dom.fakeEvent(window, 'mousemove', {\n        x: o.left,\n        y: o.top\n      });\n      dom.fakeEvent(window, 'mouseup', {\n        x: o.left,\n        y: o.top\n      });\n\n      ok(c0_changed, 'NumberControllerSlider fires when needed.');\n\n      document.body.removeChild(c0.domElement);\n\n      c1.onFinishChange(function() {\n        c1_changed = true;\n      });\n\n      document.body.appendChild(c1.domElement);\n\n      c1.__input.focus();\n      c1.__input.value = '1';\n      ok(!c1_changed, 'NumberControllerBox didn\\'t jump the gun ...');\n      c1.__input.value += '2';\n      c1.__input.blur();\n\n      document.body.removeChild(c1.domElement);\n\n      ok(c1_changed, 'NumberControllerBox fires when needed.');\n\n      c2.onFinishChange(function() {\n        c2_changed = true;\n      });\n\n      document.body.appendChild(c2.domElement);\n\n      c2.__input.focus();\n      c2.__input.value = 'friendBudd';\n      ok(!c2_changed, 'StringController didn\\'t jump the gun ...');\n      c2.__input.value += 'y';\n      c2.__input.blur();\n\n      document.body.removeChild(c2.domElement);\n\n      ok(c2_changed, 'StringController fires when needed.');\n\n    });\n\n\t\tfunction equalish(a, b, tolerance, label) {\n\t\t\treturn ok(Math.abs(a - b) < tolerance, label);\n\t\t}\n\n\n\n    module('GUI Appearance');\n\n    test('Auto placement', function() {\n\n      var gui = new GUI();\n      gui.add({ x: 0 }, 'x');\n\n      var gui2 = new GUI();\n      gui2.add({ x: 0 }, 'x');\n\n      equal($('.dg.ac').length, 1, 'A single auto-place container created');\n      equal($('.dg.ac').children().length, 2, 'Containing two GUI\\'s');\n\n      equal(gui.parent, undefined);\n      equal(gui2.parent, undefined);\n\n      $('.dg.ac').children().each(function(key, value) {\n        ok($(value).hasClass(GUI.CLASS_AUTO_PLACE), 'GUI has auto-place class');\n        ok($(value).hasClass(GUI.CLASS_MAIN), 'GUI has main class');\n\n      });\n\n      gui.destroy();\n      gui2.destroy();\n\n    });\n\n    test('Auto placement scroll', function() {\n\n      var gui = new GUI();\n\n      // Add a lot of controllers. This will fail if you have some freakishly tall monitor.\n      for (var i = 0; i < 100; i++) {\n        gui.add({ x: 0 }, 'x');\n      }\n\n\n      setTimeout(function() {\n        ok($(gui.domElement).hasClass(GUI.CLASS_TOO_TALL), 'GUI has too tall class');\n        notEqual($(gui.domElement).children('ul')[0].style.height, 'auto');\n\n        gui.destroy();\n      }, 0);\n    });\n\n    test('close/open button position', function() {\n\n      var gui = new GUI({closeOnTop:true});\n      var gui2 = new GUI({closeOnTop:false});\n      var gui3 = new GUI();\n\n      ok($(gui.domElement).find('ul').prev().hasClass(GUI.CLASS_CLOSE_BUTTON) && $(gui.domElement).find('ul').prev().hasClass(GUI.CLASS_CLOSE_TOP), 'GUI has close/open button on top');\n      ok($(gui2.domElement).find('ul').next().hasClass(GUI.CLASS_CLOSE_BUTTON) && $(gui2.domElement).find('ul').next().hasClass(GUI.CLASS_CLOSE_BOTTOM), 'GUI has close/open button on bottom');\n      ok($(gui3.domElement).find('ul').next().hasClass(GUI.CLASS_CLOSE_BUTTON) && $(gui3.domElement).find('ul').next().hasClass(GUI.CLASS_CLOSE_BOTTOM), 'GUI has close/open button on bottom by default');\n\n      gui.destroy();\n      gui2.destroy();\n      gui3.destroy();\n\n    });\n\n    test('Folders', function() {\n\n      var gui = new GUI();\n      gui.add({x:0}, 'x');\n\n      var name1 = 'name';\n      var f1 = gui.addFolder(name1);\n\n      f1.add({ x: 0 }, 'x');\n\n      equal(f1.name, name1, \"Accepts name\");\n      equal($(f1.domElement).find('li.title').html(), name1, \"Displays name\");\n\n      equal(f1.closed, true, \"Closed by default\");\n      ok($(f1.domElement).find('ul').hasClass(GUI.CLASS_CLOSED), \"Has closed class\");\n\n      var title = $(f1.domElement).find('li.title')[0];\n\n      dom.fakeEvent(title, 'click');\n\n      equal(f1.closed, false, \"Opens on click\");\n      ok(!$(f1.domElement).find('ul').hasClass(GUI.CLASS_CLOSED), \"Opens on click\");\n\n      dom.fakeEvent(title, 'click');\n\n      equal(f1.closed, true, \"Closes back up\");\n      ok($(f1.domElement).find('ul').hasClass(GUI.CLASS_CLOSED), \"Closes back up\");\n\n      gui.destroy();\n\n    });\n\n\n    module(\"GUI Controller Methods\");\n\n    test('options', function() {\n\n      var gui = new GUI();\n\n      var controller = gui.add({ x: 0 }, 'x').options(0, 1, 2, 3, 4);\n\n      $(controller.__select).children().each(function(key, value) {\n        equals(value.innerHTML, key, 'By array name okay');\n        equals(value.value, key, 'By array value okay');\n      });\n\n      controller = gui.add({ x: 0 }, 'x').options(\n          {\n            0: '0',\n            1: '1',\n            2: '2',\n            3: '3',\n            4: '4'\n          }\n      );\n\n      $(controller.__select).children().each(function(key, value) {\n        equals(value.innerHTML, key, 'By array name okay');\n        equals(value.value, key, 'By array value okay');\n      });\n\n      gui.destroy();\n\n    });\n\n    test('name', function() {\n\n      var gui = new GUI();\n\n      var name = 'hey man';\n      var name2 = 'yoyoo';\n\n      var controller = gui.add({ x: 0 }, 'x').name(name);\n\n      equals($(controller.__li).find('.property-name').html(), name);\n\n      controller.name(name2);\n      equals($(controller.__li).find('.property-name').html(), name2);\n\n      gui.destroy();\n\n    });\n\n    test('listen', function() {\n\n      var gui = new GUI();\n\n      var obj = { x: 0 };\n\n      var returned1 = gui.add(obj, 'x');\n      var returned2 = returned1.listen();\n\n      obj.x = 10;\n\n      setTimeout(function() {\n        ok(returned1 === returned2, 'Returns self');\n\n        equal(returned1.__input.value, obj.x, 'Updates display');\n        gui.destroy();\n      }, 0);\n\n    });\n\n    test('remove', function() {\n\n      var gui = new GUI();\n\n      var c = gui.add({x:0}, 'x');\n\n      ok($.contains(gui.domElement, c.domElement), \"Now you see it\");\n      c.remove();\n\n      ok(!$.contains(gui.domElement, c.domElement), \"Now you don't.\");\n\n      gui.destroy();\n\n    });\n\n    test('removeFolder', function() {\n\n      var gui = new GUI();\n\n      var f = gui.addFolder('Temporary folder');\n\n      ok($.contains(gui.domElement, f.domElement), \"Now you see it\");\n      gui.removeFolder(f);\n\n      ok(!$.contains(gui.domElement, f.domElement), \"Now you don't.\");\n\n      gui.destroy();\n\n    });\n\n    test('min, max & step', function() {\n\n      var gui = new GUI();\n\n      var min = -10;\n      var max = 200;\n      var step = 5;\n\n      var c = gui.add({ x: 0 }, 'x');\n\n      c.min(min);\n      equals(c.__min, min, 'min');\n\n      c.step(step);\n      equals(c.__step, step, 'step');\n\n      var c2 = c.max(max);\n      equals(c.__max, max, 'max');\n\n      notEqual(c2, c, 'Controller has changed.');\n\n      ok($(c2.__li).find('.slider').length > 0, 'Slider added');\n\n      equals(c.__step, step, 'step intact');\n\n      gui.destroy();\n\n    });\n\n    module(\"GUI Controller Augmentation\");\n\n    test('Adds NumberControllerBox to sliders', function() {\n      var gui = new GUI();\n\n      var c = gui.add({ x: 0 }, 'x', 0, 10);\n\n      ok($(c.__li).find('input').length > 0, 'NumberControllerBox added');\n\n      gui.destroy();\n\n    });\n\n    test('Clickable rows for BooleanControllers', function() {\n\n      var gui = new GUI();\n\n      var c = gui.add({ x: false }, 'x');\n\n      equal(c.__checkbox.checked, false, 'Acknowledges original');\n\n      dom.fakeEvent(c.__li, 'click');\n\n      equal($(c.__checkbox).attr('checked'), 'checked', 'Changes when I click the row');\n\n      dom.fakeEvent(c.__li, 'click');\n\n      equal(c.__checkbox.checked, false, 'Changes back');\n\n      gui.destroy();\n\n    });\n\n    test('Clickable rows for FunctionControllers', function() {\n\n      expect(3);\n\n      var gui = new GUI();\n\n      var c = gui.add({ x: function() {\n        ok(true)\n      } }, 'x');\n\n      dom.fakeEvent(c.__li, 'click');\n      c.fire();\n      dom.fakeEvent(c.__li, 'click');\n\n      gui.destroy();\n\n    });\n\n    module('GUI Saving');\n\n    test('Remembering values', function() {\n\n      var object = {\n        number: 0,\n        boolean: false,\n        string: 'hey'\n      };\n\n      var controllers = {};\n\n      var changed = {\n        number: -20,\n        boolean: true,\n        string: 'hang'\n      };\n\n      var gui = new GUI();\n      gui.remember(object);\n\n      for (var i in object) {\n        controllers[i] = gui.add(object, i);\n      }\n\n      for (i in controllers) {\n        controllers[i].setValue(changed[i]);\n      }\n\n      var saveObject = gui.getSaveObject();\n\n      gui.destroy();\n\n      gui = new GUI({\n            load: saveObject\n          });\n\n      gui.remember(object);\n\n      for (i in object) {\n        controllers[i] = gui.add(object, i);\n        equal(object[i], changed[i]);\n      }\n\n      ensurePresetSelectDisplay(gui);\n\n      gui.destroy();\n\n    });\n\n    test('Presets', function() {\n\n      var presetName = 'New Preset';\n\n      var object = {\n        number: 0,\n        boolean: false,\n        string: 'hey'\n      };\n\n      var original = {};\n\n      for (var i in object) {\n        original[i] = object[i];\n      }\n\n      var controllers = {};\n\n      var changed = {\n        number: -20,\n        boolean: true,\n        string: 'hang'\n      };\n\n      var gui = new GUI();\n      gui.remember(object);\n\n      for (i in object) {\n        controllers[i] = gui.add(object, i);\n      }\n\n      for (i in controllers) {\n        controllers[i].setValue(changed[i]);\n      }\n\n      ensurePresetSelectDisplay(gui);\n\n      gui.saveAs(presetName);\n\n      ensurePresetSelectDisplay(gui);\n\n      var saveObject = gui.getSaveObject();\n      console.log(saveObject);\n\n      gui.destroy();\n\n      gui = new GUI({\n            load: saveObject\n          });\n\n      gui.remember(object);\n\n      for (i in object) {\n        controllers[i] = gui.add(object, i);\n        equal(object[i], changed[i], \"Uses last defined preset\");\n      }\n\n      equal(gui.preset, presetName, \"Preset value correct\");\n      ensurePresetSelectDisplay(gui);\n\n      gui.destroy();\n\n      gui = new GUI({\n            preset: \"Default\",\n            load: saveObject\n          });\n\n      gui.remember(object);\n\n      for (i in object) {\n        controllers[i] = gui.add(object, i);\n        equal(object[i], original[i], \"Loads with explicitly set preset\");\n      }\n\n      equal(gui.preset, \"Default\", \"Preset value correct\");\n      ensurePresetSelectDisplay(gui);\n\n      gui.preset = presetName;\n\n      for (i in object) {\n        equal(object[i], changed[i], \"Changes via gui.preset property\");\n      }\n\n      $(gui.__preset_select).val('Default');\n      dom.fakeEvent(gui.__preset_select, 'change');\n\n      for (i in object) {\n        equal(object[i], original[i], \"Changes via dropdown\");\n      }\n\n      gui.destroy();\n\n    });\n\n    function ensurePresetSelectDisplay(gui) {\n\n      equal($(gui.__preset_select).children('option:selected')[0].value, gui.preset, \"Dropdown display matches preset value\");\n\n    }\n\n\n});\n</script>\n\n</head>\n<body>\n<h1 id=\"qunit-header\"></h1>\n\n<h2 id=\"qunit-banner\"></h2>\n\n<div id=\"qunit-testrunner-toolbar\"></div>\n<h2 id=\"qunit-userAgent\"></h2>\n<ol id=\"qunit-tests\"></ol>\n<div id=\"qunit-fixture\">test markup, will be hidden</div>\n</body>\n</html>\n"
  },
  {
    "path": "tests/jquery.js",
    "content": "/*!\n * jQuery JavaScript Library v1.6.4\n * http://jquery.com/\n *\n * Copyright 2011, John Resig\n * Dual licensed under the MIT or GPL Version 2 licenses.\n * http://jquery.org/license\n *\n * Includes Sizzle.js\n * http://sizzlejs.com/\n * Copyright 2011, The Dojo Foundation\n * Released under the MIT, BSD, and GPL Licenses.\n *\n * Date: Mon Sep 12 18:54:48 2011 -0400\n */\n(function( window, undefined ) {\n\n// Use the correct document accordingly with window argument (sandbox)\nvar document = window.document,\n\tnavigator = window.navigator,\n\tlocation = window.location;\nvar jQuery = (function() {\n\n// Define a local copy of jQuery\nvar jQuery = function( selector, context ) {\n\t\t// The jQuery object is actually just the init constructor 'enhanced'\n\t\treturn new jQuery.fn.init( selector, context, rootjQuery );\n\t},\n\n\t// Map over jQuery in case of overwrite\n\t_jQuery = window.jQuery,\n\n\t// Map over the $ in case of overwrite\n\t_$ = window.$,\n\n\t// A central reference to the root jQuery(document)\n\trootjQuery,\n\n\t// A simple way to check for HTML strings or ID strings\n\t// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)\n\tquickExpr = /^(?:[^#<]*(<[\\w\\W]+>)[^>]*$|#([\\w\\-]*)$)/,\n\n\t// Check if a string has a non-whitespace character in it\n\trnotwhite = /\\S/,\n\n\t// Used for trimming whitespace\n\ttrimLeft = /^\\s+/,\n\ttrimRight = /\\s+$/,\n\n\t// Check for digits\n\trdigit = /\\d/,\n\n\t// Match a standalone tag\n\trsingleTag = /^<(\\w+)\\s*\\/?>(?:<\\/\\1>)?$/,\n\n\t// JSON RegExp\n\trvalidchars = /^[\\],:{}\\s]*$/,\n\trvalidescape = /\\\\(?:[\"\\\\\\/bfnrt]|u[0-9a-fA-F]{4})/g,\n\trvalidtokens = /\"[^\"\\\\\\n\\r]*\"|true|false|null|-?\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?/g,\n\trvalidbraces = /(?:^|:|,)(?:\\s*\\[)+/g,\n\n\t// Useragent RegExp\n\trwebkit = /(webkit)[ \\/]([\\w.]+)/,\n\tropera = /(opera)(?:.*version)?[ \\/]([\\w.]+)/,\n\trmsie = /(msie) ([\\w.]+)/,\n\trmozilla = /(mozilla)(?:.*? rv:([\\w.]+))?/,\n\n\t// Matches dashed string for camelizing\n\trdashAlpha = /-([a-z]|[0-9])/ig,\n\trmsPrefix = /^-ms-/,\n\n\t// Used by jQuery.camelCase as callback to replace()\n\tfcamelCase = function( all, letter ) {\n\t\treturn ( letter + \"\" ).toUpperCase();\n\t},\n\n\t// Keep a UserAgent string for use with jQuery.browser\n\tuserAgent = navigator.userAgent,\n\n\t// For matching the engine and version of the browser\n\tbrowserMatch,\n\n\t// The deferred used on DOM ready\n\treadyList,\n\n\t// The ready event handler\n\tDOMContentLoaded,\n\n\t// Save a reference to some core methods\n\ttoString = Object.prototype.toString,\n\thasOwn = Object.prototype.hasOwnProperty,\n\tpush = Array.prototype.push,\n\tslice = Array.prototype.slice,\n\ttrim = String.prototype.trim,\n\tindexOf = Array.prototype.indexOf,\n\n\t// [[Class]] -> type pairs\n\tclass2type = {};\n\njQuery.fn = jQuery.prototype = {\n\tconstructor: jQuery,\n\tinit: function( selector, context, rootjQuery ) {\n\t\tvar match, elem, ret, doc;\n\n\t\t// Handle $(\"\"), $(null), or $(undefined)\n\t\tif ( !selector ) {\n\t\t\treturn this;\n\t\t}\n\n\t\t// Handle $(DOMElement)\n\t\tif ( selector.nodeType ) {\n\t\t\tthis.context = this[0] = selector;\n\t\t\tthis.length = 1;\n\t\t\treturn this;\n\t\t}\n\n\t\t// The body element only exists once, optimize finding it\n\t\tif ( selector === \"body\" && !context && document.body ) {\n\t\t\tthis.context = document;\n\t\t\tthis[0] = document.body;\n\t\t\tthis.selector = selector;\n\t\t\tthis.length = 1;\n\t\t\treturn this;\n\t\t}\n\n\t\t// Handle HTML strings\n\t\tif ( typeof selector === \"string\" ) {\n\t\t\t// Are we dealing with HTML string or an ID?\n\t\t\tif ( selector.charAt(0) === \"<\" && selector.charAt( selector.length - 1 ) === \">\" && selector.length >= 3 ) {\n\t\t\t\t// Assume that strings that start and end with <> are HTML and skip the regex check\n\t\t\t\tmatch = [ null, selector, null ];\n\n\t\t\t} else {\n\t\t\t\tmatch = quickExpr.exec( selector );\n\t\t\t}\n\n\t\t\t// Verify a match, and that no context was specified for #id\n\t\t\tif ( match && (match[1] || !context) ) {\n\n\t\t\t\t// HANDLE: $(html) -> $(array)\n\t\t\t\tif ( match[1] ) {\n\t\t\t\t\tcontext = context instanceof jQuery ? context[0] : context;\n\t\t\t\t\tdoc = (context ? context.ownerDocument || context : document);\n\n\t\t\t\t\t// If a single string is passed in and it's a single tag\n\t\t\t\t\t// just do a createElement and skip the rest\n\t\t\t\t\tret = rsingleTag.exec( selector );\n\n\t\t\t\t\tif ( ret ) {\n\t\t\t\t\t\tif ( jQuery.isPlainObject( context ) ) {\n\t\t\t\t\t\t\tselector = [ document.createElement( ret[1] ) ];\n\t\t\t\t\t\t\tjQuery.fn.attr.call( selector, context, true );\n\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tselector = [ doc.createElement( ret[1] ) ];\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tret = jQuery.buildFragment( [ match[1] ], [ doc ] );\n\t\t\t\t\t\tselector = (ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment).childNodes;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn jQuery.merge( this, selector );\n\n\t\t\t\t// HANDLE: $(\"#id\")\n\t\t\t\t} else {\n\t\t\t\t\telem = document.getElementById( match[2] );\n\n\t\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t\t// nodes that are no longer in the document #6963\n\t\t\t\t\tif ( elem && elem.parentNode ) {\n\t\t\t\t\t\t// Handle the case where IE and Opera return items\n\t\t\t\t\t\t// by name instead of ID\n\t\t\t\t\t\tif ( elem.id !== match[2] ) {\n\t\t\t\t\t\t\treturn rootjQuery.find( selector );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Otherwise, we inject the element directly into the jQuery object\n\t\t\t\t\t\tthis.length = 1;\n\t\t\t\t\t\tthis[0] = elem;\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.context = document;\n\t\t\t\t\tthis.selector = selector;\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\n\t\t\t// HANDLE: $(expr, $(...))\n\t\t\t} else if ( !context || context.jquery ) {\n\t\t\t\treturn (context || rootjQuery).find( selector );\n\n\t\t\t// HANDLE: $(expr, context)\n\t\t\t// (which is just equivalent to: $(context).find(expr)\n\t\t\t} else {\n\t\t\t\treturn this.constructor( context ).find( selector );\n\t\t\t}\n\n\t\t// HANDLE: $(function)\n\t\t// Shortcut for document ready\n\t\t} else if ( jQuery.isFunction( selector ) ) {\n\t\t\treturn rootjQuery.ready( selector );\n\t\t}\n\n\t\tif (selector.selector !== undefined) {\n\t\t\tthis.selector = selector.selector;\n\t\t\tthis.context = selector.context;\n\t\t}\n\n\t\treturn jQuery.makeArray( selector, this );\n\t},\n\n\t// Start with an empty selector\n\tselector: \"\",\n\n\t// The current version of jQuery being used\n\tjquery: \"1.6.4\",\n\n\t// The default length of a jQuery object is 0\n\tlength: 0,\n\n\t// The number of elements contained in the matched element set\n\tsize: function() {\n\t\treturn this.length;\n\t},\n\n\ttoArray: function() {\n\t\treturn slice.call( this, 0 );\n\t},\n\n\t// Get the Nth element in the matched element set OR\n\t// Get the whole matched element set as a clean array\n\tget: function( num ) {\n\t\treturn num == null ?\n\n\t\t\t// Return a 'clean' array\n\t\t\tthis.toArray() :\n\n\t\t\t// Return just the object\n\t\t\t( num < 0 ? this[ this.length + num ] : this[ num ] );\n\t},\n\n\t// Take an array of elements and push it onto the stack\n\t// (returning the new matched element set)\n\tpushStack: function( elems, name, selector ) {\n\t\t// Build a new jQuery matched element set\n\t\tvar ret = this.constructor();\n\n\t\tif ( jQuery.isArray( elems ) ) {\n\t\t\tpush.apply( ret, elems );\n\n\t\t} else {\n\t\t\tjQuery.merge( ret, elems );\n\t\t}\n\n\t\t// Add the old object onto the stack (as a reference)\n\t\tret.prevObject = this;\n\n\t\tret.context = this.context;\n\n\t\tif ( name === \"find\" ) {\n\t\t\tret.selector = this.selector + (this.selector ? \" \" : \"\") + selector;\n\t\t} else if ( name ) {\n\t\t\tret.selector = this.selector + \".\" + name + \"(\" + selector + \")\";\n\t\t}\n\n\t\t// Return the newly-formed element set\n\t\treturn ret;\n\t},\n\n\t// Execute a callback for every element in the matched set.\n\t// (You can seed the arguments with an array of args, but this is\n\t// only used internally.)\n\teach: function( callback, args ) {\n\t\treturn jQuery.each( this, callback, args );\n\t},\n\n\tready: function( fn ) {\n\t\t// Attach the listeners\n\t\tjQuery.bindReady();\n\n\t\t// Add the callback\n\t\treadyList.done( fn );\n\n\t\treturn this;\n\t},\n\n\teq: function( i ) {\n\t\treturn i === -1 ?\n\t\t\tthis.slice( i ) :\n\t\t\tthis.slice( i, +i + 1 );\n\t},\n\n\tfirst: function() {\n\t\treturn this.eq( 0 );\n\t},\n\n\tlast: function() {\n\t\treturn this.eq( -1 );\n\t},\n\n\tslice: function() {\n\t\treturn this.pushStack( slice.apply( this, arguments ),\n\t\t\t\"slice\", slice.call(arguments).join(\",\") );\n\t},\n\n\tmap: function( callback ) {\n\t\treturn this.pushStack( jQuery.map(this, function( elem, i ) {\n\t\t\treturn callback.call( elem, i, elem );\n\t\t}));\n\t},\n\n\tend: function() {\n\t\treturn this.prevObject || this.constructor(null);\n\t},\n\n\t// For internal use only.\n\t// Behaves like an Array's method, not like a jQuery method.\n\tpush: push,\n\tsort: [].sort,\n\tsplice: [].splice\n};\n\n// Give the init function the jQuery prototype for later instantiation\njQuery.fn.init.prototype = jQuery.fn;\n\njQuery.extend = jQuery.fn.extend = function() {\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}\n\n\t// Handle case when target is a string or something (possible in deep copy)\n\tif ( typeof target !== \"object\" && !jQuery.isFunction(target) ) {\n\t\ttarget = {};\n\t}\n\n\t// extend jQuery itself if only one argument is passed\n\tif ( length === i ) {\n\t\ttarget = this;\n\t\t--i;\n\t}\n\n\tfor ( ; i < length; i++ ) {\n\t\t// Only deal with non-null/undefined values\n\t\tif ( (options = arguments[ i ]) != 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 && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.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 && jQuery.isArray(src) ? src : [];\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclone = src && jQuery.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 ] = jQuery.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\njQuery.extend({\n\tnoConflict: function( deep ) {\n\t\tif ( window.$ === jQuery ) {\n\t\t\twindow.$ = _$;\n\t\t}\n\n\t\tif ( deep && window.jQuery === jQuery ) {\n\t\t\twindow.jQuery = _jQuery;\n\t\t}\n\n\t\treturn jQuery;\n\t},\n\n\t// Is the DOM ready to be used? Set to true once it occurs.\n\tisReady: false,\n\n\t// A counter to track how many items to wait for before\n\t// the ready event fires. See #6781\n\treadyWait: 1,\n\n\t// Hold (or release) the ready event\n\tholdReady: function( hold ) {\n\t\tif ( hold ) {\n\t\t\tjQuery.readyWait++;\n\t\t} else {\n\t\t\tjQuery.ready( true );\n\t\t}\n\t},\n\n\t// Handle when the DOM is ready\n\tready: function( wait ) {\n\t\t// Either a released hold or an DOMready/load event and not yet ready\n\t\tif ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) {\n\t\t\t// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).\n\t\t\tif ( !document.body ) {\n\t\t\t\treturn setTimeout( jQuery.ready, 1 );\n\t\t\t}\n\n\t\t\t// Remember that the DOM is ready\n\t\t\tjQuery.isReady = true;\n\n\t\t\t// If a normal DOM Ready event fired, decrement, and wait if need be\n\t\t\tif ( wait !== true && --jQuery.readyWait > 0 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If there are functions bound, to execute\n\t\t\treadyList.resolveWith( document, [ jQuery ] );\n\n\t\t\t// Trigger any bound ready events\n\t\t\tif ( jQuery.fn.trigger ) {\n\t\t\t\tjQuery( document ).trigger( \"ready\" ).unbind( \"ready\" );\n\t\t\t}\n\t\t}\n\t},\n\n\tbindReady: function() {\n\t\tif ( readyList ) {\n\t\t\treturn;\n\t\t}\n\n\t\treadyList = jQuery._Deferred();\n\n\t\t// Catch cases where $(document).ready() is called after the\n\t\t// browser event has already occurred.\n\t\tif ( document.readyState === \"complete\" ) {\n\t\t\t// Handle it asynchronously to allow scripts the opportunity to delay ready\n\t\t\treturn setTimeout( jQuery.ready, 1 );\n\t\t}\n\n\t\t// Mozilla, Opera and webkit nightlies currently support this event\n\t\tif ( document.addEventListener ) {\n\t\t\t// Use the handy event callback\n\t\t\tdocument.addEventListener( \"DOMContentLoaded\", DOMContentLoaded, false );\n\n\t\t\t// A fallback to window.onload, that will always work\n\t\t\twindow.addEventListener( \"load\", jQuery.ready, false );\n\n\t\t// If IE event model is used\n\t\t} else if ( document.attachEvent ) {\n\t\t\t// ensure firing before onload,\n\t\t\t// maybe late but safe also for iframes\n\t\t\tdocument.attachEvent( \"onreadystatechange\", DOMContentLoaded );\n\n\t\t\t// A fallback to window.onload, that will always work\n\t\t\twindow.attachEvent( \"onload\", jQuery.ready );\n\n\t\t\t// If IE and not a frame\n\t\t\t// continually check to see if the document is ready\n\t\t\tvar toplevel = false;\n\n\t\t\ttry {\n\t\t\t\ttoplevel = window.frameElement == null;\n\t\t\t} catch(e) {}\n\n\t\t\tif ( document.documentElement.doScroll && toplevel ) {\n\t\t\t\tdoScrollCheck();\n\t\t\t}\n\t\t}\n\t},\n\n\t// See test/unit/core.js for details concerning isFunction.\n\t// Since version 1.3, DOM methods and functions like alert\n\t// aren't supported. They return false on IE (#2968).\n\tisFunction: function( obj ) {\n\t\treturn jQuery.type(obj) === \"function\";\n\t},\n\n\tisArray: Array.isArray || function( obj ) {\n\t\treturn jQuery.type(obj) === \"array\";\n\t},\n\n\t// A crude way of determining if an object is a window\n\tisWindow: function( obj ) {\n\t\treturn obj && typeof obj === \"object\" && \"setInterval\" in obj;\n\t},\n\n\tisNaN: function( obj ) {\n\t\treturn obj == null || !rdigit.test( obj ) || isNaN( obj );\n\t},\n\n\ttype: function( obj ) {\n\t\treturn obj == null ?\n\t\t\tString( obj ) :\n\t\t\tclass2type[ toString.call(obj) ] || \"object\";\n\t},\n\n\tisPlainObject: function( obj ) {\n\t\t// Must be an Object.\n\t\t// Because of IE, we also have to check the presence of the constructor property.\n\t\t// Make sure that DOM nodes and window objects don't pass through, as well\n\t\tif ( !obj || jQuery.type(obj) !== \"object\" || obj.nodeType || jQuery.isWindow( obj ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\ttry {\n\t\t\t// Not own constructor property must be Object\n\t\t\tif ( obj.constructor &&\n\t\t\t\t!hasOwn.call(obj, \"constructor\") &&\n\t\t\t\t!hasOwn.call(obj.constructor.prototype, \"isPrototypeOf\") ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} catch ( e ) {\n\t\t\t// IE8,9 Will throw exceptions on certain host objects #9897\n\t\t\treturn false;\n\t\t}\n\n\t\t// Own properties are enumerated firstly, so to speed up,\n\t\t// if last one is own, then all properties are own.\n\n\t\tvar key;\n\t\tfor ( key in obj ) {}\n\n\t\treturn key === undefined || hasOwn.call( obj, key );\n\t},\n\n\tisEmptyObject: function( obj ) {\n\t\tfor ( var name in obj ) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t},\n\n\terror: function( msg ) {\n\t\tthrow msg;\n\t},\n\n\tparseJSON: function( data ) {\n\t\tif ( typeof data !== \"string\" || !data ) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Make sure leading/trailing whitespace is removed (IE can't handle it)\n\t\tdata = jQuery.trim( data );\n\n\t\t// Attempt to parse using the native JSON parser first\n\t\tif ( window.JSON && window.JSON.parse ) {\n\t\t\treturn window.JSON.parse( data );\n\t\t}\n\n\t\t// Make sure the incoming data is actual JSON\n\t\t// Logic borrowed from http://json.org/json2.js\n\t\tif ( rvalidchars.test( data.replace( rvalidescape, \"@\" )\n\t\t\t.replace( rvalidtokens, \"]\" )\n\t\t\t.replace( rvalidbraces, \"\")) ) {\n\n\t\t\treturn (new Function( \"return \" + data ))();\n\n\t\t}\n\t\tjQuery.error( \"Invalid JSON: \" + data );\n\t},\n\n\t// Cross-browser xml parsing\n\tparseXML: function( data ) {\n\t\tvar xml, tmp;\n\t\ttry {\n\t\t\tif ( window.DOMParser ) { // Standard\n\t\t\t\ttmp = new DOMParser();\n\t\t\t\txml = tmp.parseFromString( data , \"text/xml\" );\n\t\t\t} else { // IE\n\t\t\t\txml = new ActiveXObject( \"Microsoft.XMLDOM\" );\n\t\t\t\txml.async = \"false\";\n\t\t\t\txml.loadXML( data );\n\t\t\t}\n\t\t} catch( e ) {\n\t\t\txml = undefined;\n\t\t}\n\t\tif ( !xml || !xml.documentElement || xml.getElementsByTagName( \"parsererror\" ).length ) {\n\t\t\tjQuery.error( \"Invalid XML: \" + data );\n\t\t}\n\t\treturn xml;\n\t},\n\n\tnoop: function() {},\n\n\t// Evaluates a script in a global context\n\t// Workarounds based on findings by Jim Driscoll\n\t// http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context\n\tglobalEval: function( data ) {\n\t\tif ( data && rnotwhite.test( data ) ) {\n\t\t\t// We use execScript on Internet Explorer\n\t\t\t// We use an anonymous function so that context is window\n\t\t\t// rather than jQuery in Firefox\n\t\t\t( window.execScript || function( data ) {\n\t\t\t\twindow[ \"eval\" ].call( window, data );\n\t\t\t} )( data );\n\t\t}\n\t},\n\n\t// Convert dashed to camelCase; used by the css and data modules\n\t// Microsoft forgot to hump their vendor prefix (#9572)\n\tcamelCase: function( string ) {\n\t\treturn string.replace( rmsPrefix, \"ms-\" ).replace( rdashAlpha, fcamelCase );\n\t},\n\n\tnodeName: function( elem, name ) {\n\t\treturn elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();\n\t},\n\n\t// args is for internal usage only\n\teach: function( object, callback, args ) {\n\t\tvar name, i = 0,\n\t\t\tlength = object.length,\n\t\t\tisObj = length === undefined || jQuery.isFunction( object );\n\n\t\tif ( args ) {\n\t\t\tif ( isObj ) {\n\t\t\t\tfor ( name in object ) {\n\t\t\t\t\tif ( callback.apply( object[ name ], args ) === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( ; i < length; ) {\n\t\t\t\t\tif ( callback.apply( object[ i++ ], args ) === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// A special, fast, case for the most common use of each\n\t\t} else {\n\t\t\tif ( isObj ) {\n\t\t\t\tfor ( name in object ) {\n\t\t\t\t\tif ( callback.call( object[ name ], name, object[ name ] ) === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( ; i < length; ) {\n\t\t\t\t\tif ( callback.call( object[ i ], i, object[ i++ ] ) === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn object;\n\t},\n\n\t// Use native String.trim function wherever possible\n\ttrim: trim ?\n\t\tfunction( text ) {\n\t\t\treturn text == null ?\n\t\t\t\t\"\" :\n\t\t\t\ttrim.call( text );\n\t\t} :\n\n\t\t// Otherwise use our own trimming functionality\n\t\tfunction( text ) {\n\t\t\treturn text == null ?\n\t\t\t\t\"\" :\n\t\t\t\ttext.toString().replace( trimLeft, \"\" ).replace( trimRight, \"\" );\n\t\t},\n\n\t// results is for internal usage only\n\tmakeArray: function( array, results ) {\n\t\tvar ret = results || [];\n\n\t\tif ( array != null ) {\n\t\t\t// The window, strings (and functions) also have 'length'\n\t\t\t// The extra typeof function check is to prevent crashes\n\t\t\t// in Safari 2 (See: #3039)\n\t\t\t// Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930\n\t\t\tvar type = jQuery.type( array );\n\n\t\t\tif ( array.length == null || type === \"string\" || type === \"function\" || type === \"regexp\" || jQuery.isWindow( array ) ) {\n\t\t\t\tpush.call( ret, array );\n\t\t\t} else {\n\t\t\t\tjQuery.merge( ret, array );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tinArray: function( elem, array ) {\n\t\tif ( !array ) {\n\t\t\treturn -1;\n\t\t}\n\n\t\tif ( indexOf ) {\n\t\t\treturn indexOf.call( array, elem );\n\t\t}\n\n\t\tfor ( var i = 0, length = array.length; i < length; i++ ) {\n\t\t\tif ( array[ i ] === elem ) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\n\t\treturn -1;\n\t},\n\n\tmerge: function( first, second ) {\n\t\tvar i = first.length,\n\t\t\tj = 0;\n\n\t\tif ( typeof second.length === \"number\" ) {\n\t\t\tfor ( var l = second.length; j < l; j++ ) {\n\t\t\t\tfirst[ i++ ] = second[ j ];\n\t\t\t}\n\n\t\t} else {\n\t\t\twhile ( second[j] !== undefined ) {\n\t\t\t\tfirst[ i++ ] = second[ j++ ];\n\t\t\t}\n\t\t}\n\n\t\tfirst.length = i;\n\n\t\treturn first;\n\t},\n\n\tgrep: function( elems, callback, inv ) {\n\t\tvar ret = [], retVal;\n\t\tinv = !!inv;\n\n\t\t// Go through the array, only saving the items\n\t\t// that pass the validator function\n\t\tfor ( var i = 0, length = elems.length; i < length; i++ ) {\n\t\t\tretVal = !!callback( elems[ i ], i );\n\t\t\tif ( inv !== retVal ) {\n\t\t\t\tret.push( elems[ i ] );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\t// arg is for internal usage only\n\tmap: function( elems, callback, arg ) {\n\t\tvar value, key, ret = [],\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\t// jquery objects are treated as arrays\n\t\t\tisArray = elems instanceof jQuery || length !== undefined && typeof length === \"number\" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;\n\n\t\t// Go through the array, translating each of the items to their\n\t\tif ( isArray ) {\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret[ ret.length ] = value;\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Go through every key on the object,\n\t\t} else {\n\t\t\tfor ( key in elems ) {\n\t\t\t\tvalue = callback( elems[ key ], key, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret[ ret.length ] = value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Flatten any nested arrays\n\t\treturn ret.concat.apply( [], ret );\n\t},\n\n\t// A global GUID counter for objects\n\tguid: 1,\n\n\t// Bind a function to a context, optionally partially applying any\n\t// arguments.\n\tproxy: function( fn, context ) {\n\t\tif ( typeof context === \"string\" ) {\n\t\t\tvar tmp = fn[ context ];\n\t\t\tcontext = fn;\n\t\t\tfn = tmp;\n\t\t}\n\n\t\t// Quick check to determine if target is callable, in the spec\n\t\t// this throws a TypeError, but we will just return undefined.\n\t\tif ( !jQuery.isFunction( fn ) ) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\t// Simulated bind\n\t\tvar args = slice.call( arguments, 2 ),\n\t\t\tproxy = function() {\n\t\t\t\treturn fn.apply( context, args.concat( slice.call( arguments ) ) );\n\t\t\t};\n\n\t\t// Set the guid of unique handler to the same of original handler, so it can be removed\n\t\tproxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;\n\n\t\treturn proxy;\n\t},\n\n\t// Mutifunctional method to get and set values to a collection\n\t// The value/s can optionally be executed if it's a function\n\taccess: function( elems, key, value, exec, fn, pass ) {\n\t\tvar length = elems.length;\n\n\t\t// Setting many attributes\n\t\tif ( typeof key === \"object\" ) {\n\t\t\tfor ( var k in key ) {\n\t\t\t\tjQuery.access( elems, k, key[k], exec, fn, value );\n\t\t\t}\n\t\t\treturn elems;\n\t\t}\n\n\t\t// Setting one attribute\n\t\tif ( value !== undefined ) {\n\t\t\t// Optionally, function values get executed if exec is true\n\t\t\texec = !pass && exec && jQuery.isFunction(value);\n\n\t\t\tfor ( var i = 0; i < length; i++ ) {\n\t\t\t\tfn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );\n\t\t\t}\n\n\t\t\treturn elems;\n\t\t}\n\n\t\t// Getting an attribute\n\t\treturn length ? fn( elems[0], key ) : undefined;\n\t},\n\n\tnow: function() {\n\t\treturn (new Date()).getTime();\n\t},\n\n\t// Use of jQuery.browser is frowned upon.\n\t// More details: http://docs.jquery.com/Utilities/jQuery.browser\n\tuaMatch: function( ua ) {\n\t\tua = ua.toLowerCase();\n\n\t\tvar match = rwebkit.exec( ua ) ||\n\t\t\tropera.exec( ua ) ||\n\t\t\trmsie.exec( ua ) ||\n\t\t\tua.indexOf(\"compatible\") < 0 && rmozilla.exec( ua ) ||\n\t\t\t[];\n\n\t\treturn { browser: match[1] || \"\", version: match[2] || \"0\" };\n\t},\n\n\tsub: function() {\n\t\tfunction jQuerySub( selector, context ) {\n\t\t\treturn new jQuerySub.fn.init( selector, context );\n\t\t}\n\t\tjQuery.extend( true, jQuerySub, this );\n\t\tjQuerySub.superclass = this;\n\t\tjQuerySub.fn = jQuerySub.prototype = this();\n\t\tjQuerySub.fn.constructor = jQuerySub;\n\t\tjQuerySub.sub = this.sub;\n\t\tjQuerySub.fn.init = function init( selector, context ) {\n\t\t\tif ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {\n\t\t\t\tcontext = jQuerySub( context );\n\t\t\t}\n\n\t\t\treturn jQuery.fn.init.call( this, selector, context, rootjQuerySub );\n\t\t};\n\t\tjQuerySub.fn.init.prototype = jQuerySub.fn;\n\t\tvar rootjQuerySub = jQuerySub(document);\n\t\treturn jQuerySub;\n\t},\n\n\tbrowser: {}\n});\n\n// Populate the class2type map\njQuery.each(\"Boolean Number String Function Array Date RegExp Object\".split(\" \"), function(i, name) {\n\tclass2type[ \"[object \" + name + \"]\" ] = name.toLowerCase();\n});\n\nbrowserMatch = jQuery.uaMatch( userAgent );\nif ( browserMatch.browser ) {\n\tjQuery.browser[ browserMatch.browser ] = true;\n\tjQuery.browser.version = browserMatch.version;\n}\n\n// Deprecated, use jQuery.browser.webkit instead\nif ( jQuery.browser.webkit ) {\n\tjQuery.browser.safari = true;\n}\n\n// IE doesn't match non-breaking spaces with \\s\nif ( rnotwhite.test( \"\\xA0\" ) ) {\n\ttrimLeft = /^[\\s\\xA0]+/;\n\ttrimRight = /[\\s\\xA0]+$/;\n}\n\n// All jQuery objects should point back to these\nrootjQuery = jQuery(document);\n\n// Cleanup functions for the document ready method\nif ( document.addEventListener ) {\n\tDOMContentLoaded = function() {\n\t\tdocument.removeEventListener( \"DOMContentLoaded\", DOMContentLoaded, false );\n\t\tjQuery.ready();\n\t};\n\n} else if ( document.attachEvent ) {\n\tDOMContentLoaded = function() {\n\t\t// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).\n\t\tif ( document.readyState === \"complete\" ) {\n\t\t\tdocument.detachEvent( \"onreadystatechange\", DOMContentLoaded );\n\t\t\tjQuery.ready();\n\t\t}\n\t};\n}\n\n// The DOM ready check for Internet Explorer\nfunction doScrollCheck() {\n\tif ( jQuery.isReady ) {\n\t\treturn;\n\t}\n\n\ttry {\n\t\t// If IE is used, use the trick by Diego Perini\n\t\t// http://javascript.nwbox.com/IEContentLoaded/\n\t\tdocument.documentElement.doScroll(\"left\");\n\t} catch(e) {\n\t\tsetTimeout( doScrollCheck, 1 );\n\t\treturn;\n\t}\n\n\t// and execute any waiting functions\n\tjQuery.ready();\n}\n\nreturn jQuery;\n\n})();\n\n\nvar // Promise methods\n\tpromiseMethods = \"done fail isResolved isRejected promise then always pipe\".split( \" \" ),\n\t// Static reference to slice\n\tsliceDeferred = [].slice;\n\njQuery.extend({\n\t// Create a simple deferred (one callbacks list)\n\t_Deferred: function() {\n\t\tvar // callbacks list\n\t\t\tcallbacks = [],\n\t\t\t// stored [ context , args ]\n\t\t\tfired,\n\t\t\t// to avoid firing when already doing so\n\t\t\tfiring,\n\t\t\t// flag to know if the deferred has been cancelled\n\t\t\tcancelled,\n\t\t\t// the deferred itself\n\t\t\tdeferred  = {\n\n\t\t\t\t// done( f1, f2, ...)\n\t\t\t\tdone: function() {\n\t\t\t\t\tif ( !cancelled ) {\n\t\t\t\t\t\tvar args = arguments,\n\t\t\t\t\t\t\ti,\n\t\t\t\t\t\t\tlength,\n\t\t\t\t\t\t\telem,\n\t\t\t\t\t\t\ttype,\n\t\t\t\t\t\t\t_fired;\n\t\t\t\t\t\tif ( fired ) {\n\t\t\t\t\t\t\t_fired = fired;\n\t\t\t\t\t\t\tfired = 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfor ( i = 0, length = args.length; i < length; i++ ) {\n\t\t\t\t\t\t\telem = args[ i ];\n\t\t\t\t\t\t\ttype = jQuery.type( elem );\n\t\t\t\t\t\t\tif ( type === \"array\" ) {\n\t\t\t\t\t\t\t\tdeferred.done.apply( deferred, elem );\n\t\t\t\t\t\t\t} else if ( type === \"function\" ) {\n\t\t\t\t\t\t\t\tcallbacks.push( elem );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( _fired ) {\n\t\t\t\t\t\t\tdeferred.resolveWith( _fired[ 0 ], _fired[ 1 ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// resolve with given context and args\n\t\t\t\tresolveWith: function( context, args ) {\n\t\t\t\t\tif ( !cancelled && !fired && !firing ) {\n\t\t\t\t\t\t// make sure args are available (#8421)\n\t\t\t\t\t\targs = args || [];\n\t\t\t\t\t\tfiring = 1;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\twhile( callbacks[ 0 ] ) {\n\t\t\t\t\t\t\t\tcallbacks.shift().apply( context, args );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfinally {\n\t\t\t\t\t\t\tfired = [ context, args ];\n\t\t\t\t\t\t\tfiring = 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// resolve with this as context and given arguments\n\t\t\t\tresolve: function() {\n\t\t\t\t\tdeferred.resolveWith( this, arguments );\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Has this deferred been resolved?\n\t\t\t\tisResolved: function() {\n\t\t\t\t\treturn !!( firing || fired );\n\t\t\t\t},\n\n\t\t\t\t// Cancel\n\t\t\t\tcancel: function() {\n\t\t\t\t\tcancelled = 1;\n\t\t\t\t\tcallbacks = [];\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t};\n\n\t\treturn deferred;\n\t},\n\n\t// Full fledged deferred (two callbacks list)\n\tDeferred: function( func ) {\n\t\tvar deferred = jQuery._Deferred(),\n\t\t\tfailDeferred = jQuery._Deferred(),\n\t\t\tpromise;\n\t\t// Add errorDeferred methods, then and promise\n\t\tjQuery.extend( deferred, {\n\t\t\tthen: function( doneCallbacks, failCallbacks ) {\n\t\t\t\tdeferred.done( doneCallbacks ).fail( failCallbacks );\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\talways: function() {\n\t\t\t\treturn deferred.done.apply( deferred, arguments ).fail.apply( this, arguments );\n\t\t\t},\n\t\t\tfail: failDeferred.done,\n\t\t\trejectWith: failDeferred.resolveWith,\n\t\t\treject: failDeferred.resolve,\n\t\t\tisRejected: failDeferred.isResolved,\n\t\t\tpipe: function( fnDone, fnFail ) {\n\t\t\t\treturn jQuery.Deferred(function( newDefer ) {\n\t\t\t\t\tjQuery.each( {\n\t\t\t\t\t\tdone: [ fnDone, \"resolve\" ],\n\t\t\t\t\t\tfail: [ fnFail, \"reject\" ]\n\t\t\t\t\t}, function( handler, data ) {\n\t\t\t\t\t\tvar fn = data[ 0 ],\n\t\t\t\t\t\t\taction = data[ 1 ],\n\t\t\t\t\t\t\treturned;\n\t\t\t\t\t\tif ( jQuery.isFunction( fn ) ) {\n\t\t\t\t\t\t\tdeferred[ handler ](function() {\n\t\t\t\t\t\t\t\treturned = fn.apply( this, arguments );\n\t\t\t\t\t\t\t\tif ( returned && jQuery.isFunction( returned.promise ) ) {\n\t\t\t\t\t\t\t\t\treturned.promise().then( newDefer.resolve, newDefer.reject );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tnewDefer[ action + \"With\" ]( this === deferred ? newDefer : this, [ returned ] );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tdeferred[ handler ]( newDefer[ action ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}).promise();\n\t\t\t},\n\t\t\t// Get a promise for this deferred\n\t\t\t// If obj is provided, the promise aspect is added to the object\n\t\t\tpromise: function( obj ) {\n\t\t\t\tif ( obj == null ) {\n\t\t\t\t\tif ( promise ) {\n\t\t\t\t\t\treturn promise;\n\t\t\t\t\t}\n\t\t\t\t\tpromise = obj = {};\n\t\t\t\t}\n\t\t\t\tvar i = promiseMethods.length;\n\t\t\t\twhile( i-- ) {\n\t\t\t\t\tobj[ promiseMethods[i] ] = deferred[ promiseMethods[i] ];\n\t\t\t\t}\n\t\t\t\treturn obj;\n\t\t\t}\n\t\t});\n\t\t// Make sure only one callback list will be used\n\t\tdeferred.done( failDeferred.cancel ).fail( deferred.cancel );\n\t\t// Unexpose cancel\n\t\tdelete deferred.cancel;\n\t\t// Call given func if any\n\t\tif ( func ) {\n\t\t\tfunc.call( deferred, deferred );\n\t\t}\n\t\treturn deferred;\n\t},\n\n\t// Deferred helper\n\twhen: function( firstParam ) {\n\t\tvar args = arguments,\n\t\t\ti = 0,\n\t\t\tlength = args.length,\n\t\t\tcount = length,\n\t\t\tdeferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ?\n\t\t\t\tfirstParam :\n\t\t\t\tjQuery.Deferred();\n\t\tfunction resolveFunc( i ) {\n\t\t\treturn function( value ) {\n\t\t\t\targs[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;\n\t\t\t\tif ( !( --count ) ) {\n\t\t\t\t\t// Strange bug in FF4:\n\t\t\t\t\t// Values changed onto the arguments object sometimes end up as undefined values\n\t\t\t\t\t// outside the $.when method. Cloning the object into a fresh array solves the issue\n\t\t\t\t\tdeferred.resolveWith( deferred, sliceDeferred.call( args, 0 ) );\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\tif ( length > 1 ) {\n\t\t\tfor( ; i < length; i++ ) {\n\t\t\t\tif ( args[ i ] && jQuery.isFunction( args[ i ].promise ) ) {\n\t\t\t\t\targs[ i ].promise().then( resolveFunc(i), deferred.reject );\n\t\t\t\t} else {\n\t\t\t\t\t--count;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( !count ) {\n\t\t\t\tdeferred.resolveWith( deferred, args );\n\t\t\t}\n\t\t} else if ( deferred !== firstParam ) {\n\t\t\tdeferred.resolveWith( deferred, length ? [ firstParam ] : [] );\n\t\t}\n\t\treturn deferred.promise();\n\t}\n});\n\n\n\njQuery.support = (function() {\n\n\tvar div = document.createElement( \"div\" ),\n\t\tdocumentElement = document.documentElement,\n\t\tall,\n\t\ta,\n\t\tselect,\n\t\topt,\n\t\tinput,\n\t\tmarginDiv,\n\t\tsupport,\n\t\tfragment,\n\t\tbody,\n\t\ttestElementParent,\n\t\ttestElement,\n\t\ttestElementStyle,\n\t\ttds,\n\t\tevents,\n\t\teventName,\n\t\ti,\n\t\tisSupported;\n\n\t// Preliminary tests\n\tdiv.setAttribute(\"className\", \"t\");\n\tdiv.innerHTML = \"   <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>\";\n\n\n\tall = div.getElementsByTagName( \"*\" );\n\ta = div.getElementsByTagName( \"a\" )[ 0 ];\n\n\t// Can't get basic test support\n\tif ( !all || !all.length || !a ) {\n\t\treturn {};\n\t}\n\n\t// First batch of supports tests\n\tselect = document.createElement( \"select\" );\n\topt = select.appendChild( document.createElement(\"option\") );\n\tinput = div.getElementsByTagName( \"input\" )[ 0 ];\n\n\tsupport = {\n\t\t// IE strips leading whitespace when .innerHTML is used\n\t\tleadingWhitespace: ( div.firstChild.nodeType === 3 ),\n\n\t\t// Make sure that tbody elements aren't automatically inserted\n\t\t// IE will insert them into empty tables\n\t\ttbody: !div.getElementsByTagName( \"tbody\" ).length,\n\n\t\t// Make sure that link elements get serialized correctly by innerHTML\n\t\t// This requires a wrapper element in IE\n\t\thtmlSerialize: !!div.getElementsByTagName( \"link\" ).length,\n\n\t\t// Get the style information from getAttribute\n\t\t// (IE uses .cssText instead)\n\t\tstyle: /top/.test( a.getAttribute(\"style\") ),\n\n\t\t// Make sure that URLs aren't manipulated\n\t\t// (IE normalizes it by default)\n\t\threfNormalized: ( a.getAttribute( \"href\" ) === \"/a\" ),\n\n\t\t// Make sure that element opacity exists\n\t\t// (IE uses filter instead)\n\t\t// Use a regex to work around a WebKit issue. See #5145\n\t\topacity: /^0.55$/.test( a.style.opacity ),\n\n\t\t// Verify style float existence\n\t\t// (IE uses styleFloat instead of cssFloat)\n\t\tcssFloat: !!a.style.cssFloat,\n\n\t\t// Make sure that if no value is specified for a checkbox\n\t\t// that it defaults to \"on\".\n\t\t// (WebKit defaults to \"\" instead)\n\t\tcheckOn: ( input.value === \"on\" ),\n\n\t\t// Make sure that a selected-by-default option has a working selected property.\n\t\t// (WebKit defaults to false instead of true, IE too, if it's in an optgroup)\n\t\toptSelected: opt.selected,\n\n\t\t// Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)\n\t\tgetSetAttribute: div.className !== \"t\",\n\n\t\t// Will be defined later\n\t\tsubmitBubbles: true,\n\t\tchangeBubbles: true,\n\t\tfocusinBubbles: false,\n\t\tdeleteExpando: true,\n\t\tnoCloneEvent: true,\n\t\tinlineBlockNeedsLayout: false,\n\t\tshrinkWrapBlocks: false,\n\t\treliableMarginRight: true\n\t};\n\n\t// Make sure checked status is properly cloned\n\tinput.checked = true;\n\tsupport.noCloneChecked = input.cloneNode( true ).checked;\n\n\t// Make sure that the options inside disabled selects aren't marked as disabled\n\t// (WebKit marks them as disabled)\n\tselect.disabled = true;\n\tsupport.optDisabled = !opt.disabled;\n\n\t// Test to see if it's possible to delete an expando from an element\n\t// Fails in Internet Explorer\n\ttry {\n\t\tdelete div.test;\n\t} catch( e ) {\n\t\tsupport.deleteExpando = false;\n\t}\n\n\tif ( !div.addEventListener && div.attachEvent && div.fireEvent ) {\n\t\tdiv.attachEvent( \"onclick\", function() {\n\t\t\t// Cloning a node shouldn't copy over any\n\t\t\t// bound event handlers (IE does this)\n\t\t\tsupport.noCloneEvent = false;\n\t\t});\n\t\tdiv.cloneNode( true ).fireEvent( \"onclick\" );\n\t}\n\n\t// Check if a radio maintains it's value\n\t// after being appended to the DOM\n\tinput = document.createElement(\"input\");\n\tinput.value = \"t\";\n\tinput.setAttribute(\"type\", \"radio\");\n\tsupport.radioValue = input.value === \"t\";\n\n\tinput.setAttribute(\"checked\", \"checked\");\n\tdiv.appendChild( input );\n\tfragment = document.createDocumentFragment();\n\tfragment.appendChild( div.firstChild );\n\n\t// WebKit doesn't clone checked state correctly in fragments\n\tsupport.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;\n\n\tdiv.innerHTML = \"\";\n\n\t// Figure out if the W3C box model works as expected\n\tdiv.style.width = div.style.paddingLeft = \"1px\";\n\n\tbody = document.getElementsByTagName( \"body\" )[ 0 ];\n\t// We use our own, invisible, body unless the body is already present\n\t// in which case we use a div (#9239)\n\ttestElement = document.createElement( body ? \"div\" : \"body\" );\n\ttestElementStyle = {\n\t\tvisibility: \"hidden\",\n\t\twidth: 0,\n\t\theight: 0,\n\t\tborder: 0,\n\t\tmargin: 0,\n\t\tbackground: \"none\"\n\t};\n\tif ( body ) {\n\t\tjQuery.extend( testElementStyle, {\n\t\t\tposition: \"absolute\",\n\t\t\tleft: \"-1000px\",\n\t\t\ttop: \"-1000px\"\n\t\t});\n\t}\n\tfor ( i in testElementStyle ) {\n\t\ttestElement.style[ i ] = testElementStyle[ i ];\n\t}\n\ttestElement.appendChild( div );\n\ttestElementParent = body || documentElement;\n\ttestElementParent.insertBefore( testElement, testElementParent.firstChild );\n\n\t// Check if a disconnected checkbox will retain its checked\n\t// value of true after appended to the DOM (IE6/7)\n\tsupport.appendChecked = input.checked;\n\n\tsupport.boxModel = div.offsetWidth === 2;\n\n\tif ( \"zoom\" in div.style ) {\n\t\t// Check if natively block-level elements act like inline-block\n\t\t// elements when setting their display to 'inline' and giving\n\t\t// them layout\n\t\t// (IE < 8 does this)\n\t\tdiv.style.display = \"inline\";\n\t\tdiv.style.zoom = 1;\n\t\tsupport.inlineBlockNeedsLayout = ( div.offsetWidth === 2 );\n\n\t\t// Check if elements with layout shrink-wrap their children\n\t\t// (IE 6 does this)\n\t\tdiv.style.display = \"\";\n\t\tdiv.innerHTML = \"<div style='width:4px;'></div>\";\n\t\tsupport.shrinkWrapBlocks = ( div.offsetWidth !== 2 );\n\t}\n\n\tdiv.innerHTML = \"<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>\";\n\ttds = div.getElementsByTagName( \"td\" );\n\n\t// Check if table cells still have offsetWidth/Height when they are set\n\t// to display:none and there are still other visible table cells in a\n\t// table row; if so, offsetWidth/Height are not reliable for use when\n\t// determining if an element has been hidden directly using\n\t// display:none (it is still safe to use offsets if a parent element is\n\t// hidden; don safety goggles and see bug #4512 for more information).\n\t// (only IE 8 fails this test)\n\tisSupported = ( tds[ 0 ].offsetHeight === 0 );\n\n\ttds[ 0 ].style.display = \"\";\n\ttds[ 1 ].style.display = \"none\";\n\n\t// Check if empty table cells still have offsetWidth/Height\n\t// (IE < 8 fail this test)\n\tsupport.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );\n\tdiv.innerHTML = \"\";\n\n\t// Check if div with explicit width and no margin-right incorrectly\n\t// gets computed margin-right based on width of container. For more\n\t// info see bug #3333\n\t// Fails in WebKit before Feb 2011 nightlies\n\t// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right\n\tif ( document.defaultView && document.defaultView.getComputedStyle ) {\n\t\tmarginDiv = document.createElement( \"div\" );\n\t\tmarginDiv.style.width = \"0\";\n\t\tmarginDiv.style.marginRight = \"0\";\n\t\tdiv.appendChild( marginDiv );\n\t\tsupport.reliableMarginRight =\n\t\t\t( parseInt( ( document.defaultView.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0;\n\t}\n\n\t// Remove the body element we added\n\ttestElement.innerHTML = \"\";\n\ttestElementParent.removeChild( testElement );\n\n\t// Technique from Juriy Zaytsev\n\t// http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/\n\t// We only care about the case where non-standard event systems\n\t// are used, namely in IE. Short-circuiting here helps us to\n\t// avoid an eval call (in setAttribute) which can cause CSP\n\t// to go haywire. See: https://developer.mozilla.org/en/Security/CSP\n\tif ( div.attachEvent ) {\n\t\tfor( i in {\n\t\t\tsubmit: 1,\n\t\t\tchange: 1,\n\t\t\tfocusin: 1\n\t\t} ) {\n\t\t\teventName = \"on\" + i;\n\t\t\tisSupported = ( eventName in div );\n\t\t\tif ( !isSupported ) {\n\t\t\t\tdiv.setAttribute( eventName, \"return;\" );\n\t\t\t\tisSupported = ( typeof div[ eventName ] === \"function\" );\n\t\t\t}\n\t\t\tsupport[ i + \"Bubbles\" ] = isSupported;\n\t\t}\n\t}\n\n\t// Null connected elements to avoid leaks in IE\n\ttestElement = fragment = select = opt = body = marginDiv = div = input = null;\n\n\treturn support;\n})();\n\n// Keep track of boxModel\njQuery.boxModel = jQuery.support.boxModel;\n\n\n\n\nvar rbrace = /^(?:\\{.*\\}|\\[.*\\])$/,\n\trmultiDash = /([A-Z])/g;\n\njQuery.extend({\n\tcache: {},\n\n\t// Please use with caution\n\tuuid: 0,\n\n\t// Unique for each copy of jQuery on the page\n\t// Non-digits removed to match rinlinejQuery\n\texpando: \"jQuery\" + ( jQuery.fn.jquery + Math.random() ).replace( /\\D/g, \"\" ),\n\n\t// The following elements throw uncatchable exceptions if you\n\t// attempt to add expando properties to them.\n\tnoData: {\n\t\t\"embed\": true,\n\t\t// Ban all objects except for Flash (which handle expandos)\n\t\t\"object\": \"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\",\n\t\t\"applet\": true\n\t},\n\n\thasData: function( elem ) {\n\t\telem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];\n\n\t\treturn !!elem && !isEmptyDataObject( elem );\n\t},\n\n\tdata: function( elem, name, data, pvt /* Internal Use Only */ ) {\n\t\tif ( !jQuery.acceptData( elem ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar thisCache, ret,\n\t\t\tinternalKey = jQuery.expando,\n\t\t\tgetByName = typeof name === \"string\",\n\n\t\t\t// We have to handle DOM nodes and JS objects differently because IE6-7\n\t\t\t// can't GC object references properly across the DOM-JS boundary\n\t\t\tisNode = elem.nodeType,\n\n\t\t\t// Only DOM nodes need the global jQuery cache; JS object data is\n\t\t\t// attached directly to the object so GC can occur automatically\n\t\t\tcache = isNode ? jQuery.cache : elem,\n\n\t\t\t// Only defining an ID for JS objects if its cache already exists allows\n\t\t\t// the code to shortcut on the same path as a DOM node with no cache\n\t\t\tid = isNode ? elem[ jQuery.expando ] : elem[ jQuery.expando ] && jQuery.expando;\n\n\t\t// Avoid doing any more work than we need to when trying to get data on an\n\t\t// object that has no data at all\n\t\tif ( (!id || (pvt && id && (cache[ id ] && !cache[ id ][ internalKey ]))) && getByName && data === undefined ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !id ) {\n\t\t\t// Only DOM nodes need a new unique ID for each element since their data\n\t\t\t// ends up in the global cache\n\t\t\tif ( isNode ) {\n\t\t\t\telem[ jQuery.expando ] = id = ++jQuery.uuid;\n\t\t\t} else {\n\t\t\t\tid = jQuery.expando;\n\t\t\t}\n\t\t}\n\n\t\tif ( !cache[ id ] ) {\n\t\t\tcache[ id ] = {};\n\n\t\t\t// TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery\n\t\t\t// metadata on plain JS objects when the object is serialized using\n\t\t\t// JSON.stringify\n\t\t\tif ( !isNode ) {\n\t\t\t\tcache[ id ].toJSON = jQuery.noop;\n\t\t\t}\n\t\t}\n\n\t\t// An object can be passed to jQuery.data instead of a key/value pair; this gets\n\t\t// shallow copied over onto the existing cache\n\t\tif ( typeof name === \"object\" || typeof name === \"function\" ) {\n\t\t\tif ( pvt ) {\n\t\t\t\tcache[ id ][ internalKey ] = jQuery.extend(cache[ id ][ internalKey ], name);\n\t\t\t} else {\n\t\t\t\tcache[ id ] = jQuery.extend(cache[ id ], name);\n\t\t\t}\n\t\t}\n\n\t\tthisCache = cache[ id ];\n\n\t\t// Internal jQuery data is stored in a separate object inside the object's data\n\t\t// cache in order to avoid key collisions between internal data and user-defined\n\t\t// data\n\t\tif ( pvt ) {\n\t\t\tif ( !thisCache[ internalKey ] ) {\n\t\t\t\tthisCache[ internalKey ] = {};\n\t\t\t}\n\n\t\t\tthisCache = thisCache[ internalKey ];\n\t\t}\n\n\t\tif ( data !== undefined ) {\n\t\t\tthisCache[ jQuery.camelCase( name ) ] = data;\n\t\t}\n\n\t\t// TODO: This is a hack for 1.5 ONLY. It will be removed in 1.6. Users should\n\t\t// not attempt to inspect the internal events object using jQuery.data, as this\n\t\t// internal data object is undocumented and subject to change.\n\t\tif ( name === \"events\" && !thisCache[name] ) {\n\t\t\treturn thisCache[ internalKey ] && thisCache[ internalKey ].events;\n\t\t}\n\n\t\t// Check for both converted-to-camel and non-converted data property names\n\t\t// If a data property was specified\n\t\tif ( getByName ) {\n\n\t\t\t// First Try to find as-is property data\n\t\t\tret = thisCache[ name ];\n\n\t\t\t// Test for null|undefined property data\n\t\t\tif ( ret == null ) {\n\n\t\t\t\t// Try to find the camelCased property\n\t\t\t\tret = thisCache[ jQuery.camelCase( name ) ];\n\t\t\t}\n\t\t} else {\n\t\t\tret = thisCache;\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tremoveData: function( elem, name, pvt /* Internal Use Only */ ) {\n\t\tif ( !jQuery.acceptData( elem ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar thisCache,\n\n\t\t\t// Reference to internal data cache key\n\t\t\tinternalKey = jQuery.expando,\n\n\t\t\tisNode = elem.nodeType,\n\n\t\t\t// See jQuery.data for more information\n\t\t\tcache = isNode ? jQuery.cache : elem,\n\n\t\t\t// See jQuery.data for more information\n\t\t\tid = isNode ? elem[ jQuery.expando ] : jQuery.expando;\n\n\t\t// If there is already no cache entry for this object, there is no\n\t\t// purpose in continuing\n\t\tif ( !cache[ id ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( name ) {\n\n\t\t\tthisCache = pvt ? cache[ id ][ internalKey ] : cache[ id ];\n\n\t\t\tif ( thisCache ) {\n\n\t\t\t\t// Support interoperable removal of hyphenated or camelcased keys\n\t\t\t\tif ( !thisCache[ name ] ) {\n\t\t\t\t\tname = jQuery.camelCase( name );\n\t\t\t\t}\n\n\t\t\t\tdelete thisCache[ name ];\n\n\t\t\t\t// If there is no data left in the cache, we want to continue\n\t\t\t\t// and let the cache object itself get destroyed\n\t\t\t\tif ( !isEmptyDataObject(thisCache) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// See jQuery.data for more information\n\t\tif ( pvt ) {\n\t\t\tdelete cache[ id ][ internalKey ];\n\n\t\t\t// Don't destroy the parent cache unless the internal data object\n\t\t\t// had been the only thing left in it\n\t\t\tif ( !isEmptyDataObject(cache[ id ]) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tvar internalCache = cache[ id ][ internalKey ];\n\n\t\t// Browsers that fail expando deletion also refuse to delete expandos on\n\t\t// the window, but it will allow it on all other JS objects; other browsers\n\t\t// don't care\n\t\t// Ensure that `cache` is not a window object #10080\n\t\tif ( jQuery.support.deleteExpando || !cache.setInterval ) {\n\t\t\tdelete cache[ id ];\n\t\t} else {\n\t\t\tcache[ id ] = null;\n\t\t}\n\n\t\t// We destroyed the entire user cache at once because it's faster than\n\t\t// iterating through each key, but we need to continue to persist internal\n\t\t// data if it existed\n\t\tif ( internalCache ) {\n\t\t\tcache[ id ] = {};\n\t\t\t// TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery\n\t\t\t// metadata on plain JS objects when the object is serialized using\n\t\t\t// JSON.stringify\n\t\t\tif ( !isNode ) {\n\t\t\t\tcache[ id ].toJSON = jQuery.noop;\n\t\t\t}\n\n\t\t\tcache[ id ][ internalKey ] = internalCache;\n\n\t\t// Otherwise, we need to eliminate the expando on the node to avoid\n\t\t// false lookups in the cache for entries that no longer exist\n\t\t} else if ( isNode ) {\n\t\t\t// IE does not allow us to delete expando properties from nodes,\n\t\t\t// nor does it have a removeAttribute function on Document nodes;\n\t\t\t// we must handle all of these cases\n\t\t\tif ( jQuery.support.deleteExpando ) {\n\t\t\t\tdelete elem[ jQuery.expando ];\n\t\t\t} else if ( elem.removeAttribute ) {\n\t\t\t\telem.removeAttribute( jQuery.expando );\n\t\t\t} else {\n\t\t\t\telem[ jQuery.expando ] = null;\n\t\t\t}\n\t\t}\n\t},\n\n\t// For internal use only.\n\t_data: function( elem, name, data ) {\n\t\treturn jQuery.data( elem, name, data, true );\n\t},\n\n\t// A method for determining if a DOM node can handle the data expando\n\tacceptData: function( elem ) {\n\t\tif ( elem.nodeName ) {\n\t\t\tvar match = jQuery.noData[ elem.nodeName.toLowerCase() ];\n\n\t\t\tif ( match ) {\n\t\t\t\treturn !(match === true || elem.getAttribute(\"classid\") !== match);\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n});\n\njQuery.fn.extend({\n\tdata: function( key, value ) {\n\t\tvar data = null;\n\n\t\tif ( typeof key === \"undefined\" ) {\n\t\t\tif ( this.length ) {\n\t\t\t\tdata = jQuery.data( this[0] );\n\n\t\t\t\tif ( this[0].nodeType === 1 ) {\n\t\t\t    var attr = this[0].attributes, name;\n\t\t\t\t\tfor ( var i = 0, l = attr.length; i < l; i++ ) {\n\t\t\t\t\t\tname = attr[i].name;\n\n\t\t\t\t\t\tif ( name.indexOf( \"data-\" ) === 0 ) {\n\t\t\t\t\t\t\tname = jQuery.camelCase( name.substring(5) );\n\n\t\t\t\t\t\t\tdataAttr( this[0], name, data[ name ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn data;\n\n\t\t} else if ( typeof key === \"object\" ) {\n\t\t\treturn this.each(function() {\n\t\t\t\tjQuery.data( this, key );\n\t\t\t});\n\t\t}\n\n\t\tvar parts = key.split(\".\");\n\t\tparts[1] = parts[1] ? \".\" + parts[1] : \"\";\n\n\t\tif ( value === undefined ) {\n\t\t\tdata = this.triggerHandler(\"getData\" + parts[1] + \"!\", [parts[0]]);\n\n\t\t\t// Try to fetch any internally stored data first\n\t\t\tif ( data === undefined && this.length ) {\n\t\t\t\tdata = jQuery.data( this[0], key );\n\t\t\t\tdata = dataAttr( this[0], key, data );\n\t\t\t}\n\n\t\t\treturn data === undefined && parts[1] ?\n\t\t\t\tthis.data( parts[0] ) :\n\t\t\t\tdata;\n\n\t\t} else {\n\t\t\treturn this.each(function() {\n\t\t\t\tvar $this = jQuery( this ),\n\t\t\t\t\targs = [ parts[0], value ];\n\n\t\t\t\t$this.triggerHandler( \"setData\" + parts[1] + \"!\", args );\n\t\t\t\tjQuery.data( this, key, value );\n\t\t\t\t$this.triggerHandler( \"changeData\" + parts[1] + \"!\", args );\n\t\t\t});\n\t\t}\n\t},\n\n\tremoveData: function( key ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.removeData( this, key );\n\t\t});\n\t}\n});\n\nfunction dataAttr( elem, key, data ) {\n\t// If nothing was found internally, try to fetch any\n\t// data from the HTML5 data-* attribute\n\tif ( data === undefined && elem.nodeType === 1 ) {\n\n\t\tvar name = \"data-\" + key.replace( rmultiDash, \"-$1\" ).toLowerCase();\n\n\t\tdata = elem.getAttribute( name );\n\n\t\tif ( typeof data === \"string\" ) {\n\t\t\ttry {\n\t\t\t\tdata = data === \"true\" ? true :\n\t\t\t\tdata === \"false\" ? false :\n\t\t\t\tdata === \"null\" ? null :\n\t\t\t\t!jQuery.isNaN( data ) ? parseFloat( data ) :\n\t\t\t\t\trbrace.test( data ) ? jQuery.parseJSON( data ) :\n\t\t\t\t\tdata;\n\t\t\t} catch( e ) {}\n\n\t\t\t// Make sure we set the data so it isn't changed later\n\t\t\tjQuery.data( elem, key, data );\n\n\t\t} else {\n\t\t\tdata = undefined;\n\t\t}\n\t}\n\n\treturn data;\n}\n\n// TODO: This is a hack for 1.5 ONLY to allow objects with a single toJSON\n// property to be considered empty objects; this property always exists in\n// order to make sure JSON.stringify does not expose internal metadata\nfunction isEmptyDataObject( obj ) {\n\tfor ( var name in obj ) {\n\t\tif ( name !== \"toJSON\" ) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n\n\n\n\nfunction handleQueueMarkDefer( elem, type, src ) {\n\tvar deferDataKey = type + \"defer\",\n\t\tqueueDataKey = type + \"queue\",\n\t\tmarkDataKey = type + \"mark\",\n\t\tdefer = jQuery.data( elem, deferDataKey, undefined, true );\n\tif ( defer &&\n\t\t( src === \"queue\" || !jQuery.data( elem, queueDataKey, undefined, true ) ) &&\n\t\t( src === \"mark\" || !jQuery.data( elem, markDataKey, undefined, true ) ) ) {\n\t\t// Give room for hard-coded callbacks to fire first\n\t\t// and eventually mark/queue something else on the element\n\t\tsetTimeout( function() {\n\t\t\tif ( !jQuery.data( elem, queueDataKey, undefined, true ) &&\n\t\t\t\t!jQuery.data( elem, markDataKey, undefined, true ) ) {\n\t\t\t\tjQuery.removeData( elem, deferDataKey, true );\n\t\t\t\tdefer.resolve();\n\t\t\t}\n\t\t}, 0 );\n\t}\n}\n\njQuery.extend({\n\n\t_mark: function( elem, type ) {\n\t\tif ( elem ) {\n\t\t\ttype = (type || \"fx\") + \"mark\";\n\t\t\tjQuery.data( elem, type, (jQuery.data(elem,type,undefined,true) || 0) + 1, true );\n\t\t}\n\t},\n\n\t_unmark: function( force, elem, type ) {\n\t\tif ( force !== true ) {\n\t\t\ttype = elem;\n\t\t\telem = force;\n\t\t\tforce = false;\n\t\t}\n\t\tif ( elem ) {\n\t\t\ttype = type || \"fx\";\n\t\t\tvar key = type + \"mark\",\n\t\t\t\tcount = force ? 0 : ( (jQuery.data( elem, key, undefined, true) || 1 ) - 1 );\n\t\t\tif ( count ) {\n\t\t\t\tjQuery.data( elem, key, count, true );\n\t\t\t} else {\n\t\t\t\tjQuery.removeData( elem, key, true );\n\t\t\t\thandleQueueMarkDefer( elem, type, \"mark\" );\n\t\t\t}\n\t\t}\n\t},\n\n\tqueue: function( elem, type, data ) {\n\t\tif ( elem ) {\n\t\t\ttype = (type || \"fx\") + \"queue\";\n\t\t\tvar q = jQuery.data( elem, type, undefined, true );\n\t\t\t// Speed up dequeue by getting out quickly if this is just a lookup\n\t\t\tif ( data ) {\n\t\t\t\tif ( !q || jQuery.isArray(data) ) {\n\t\t\t\t\tq = jQuery.data( elem, type, jQuery.makeArray(data), true );\n\t\t\t\t} else {\n\t\t\t\t\tq.push( data );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn q || [];\n\t\t}\n\t},\n\n\tdequeue: function( elem, type ) {\n\t\ttype = type || \"fx\";\n\n\t\tvar queue = jQuery.queue( elem, type ),\n\t\t\tfn = queue.shift(),\n\t\t\tdefer;\n\n\t\t// If the fx queue is dequeued, always remove the progress sentinel\n\t\tif ( fn === \"inprogress\" ) {\n\t\t\tfn = queue.shift();\n\t\t}\n\n\t\tif ( fn ) {\n\t\t\t// Add a progress sentinel to prevent the fx queue from being\n\t\t\t// automatically dequeued\n\t\t\tif ( type === \"fx\" ) {\n\t\t\t\tqueue.unshift(\"inprogress\");\n\t\t\t}\n\n\t\t\tfn.call(elem, function() {\n\t\t\t\tjQuery.dequeue(elem, type);\n\t\t\t});\n\t\t}\n\n\t\tif ( !queue.length ) {\n\t\t\tjQuery.removeData( elem, type + \"queue\", true );\n\t\t\thandleQueueMarkDefer( elem, type, \"queue\" );\n\t\t}\n\t}\n});\n\njQuery.fn.extend({\n\tqueue: function( type, data ) {\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tdata = type;\n\t\t\ttype = \"fx\";\n\t\t}\n\n\t\tif ( data === undefined ) {\n\t\t\treturn jQuery.queue( this[0], type );\n\t\t}\n\t\treturn this.each(function() {\n\t\t\tvar queue = jQuery.queue( this, type, data );\n\n\t\t\tif ( type === \"fx\" && queue[0] !== \"inprogress\" ) {\n\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t}\n\t\t});\n\t},\n\tdequeue: function( type ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.dequeue( this, type );\n\t\t});\n\t},\n\t// Based off of the plugin by Clint Helfers, with permission.\n\t// http://blindsignals.com/index.php/2009/07/jquery-delay/\n\tdelay: function( time, type ) {\n\t\ttime = jQuery.fx ? jQuery.fx.speeds[time] || time : time;\n\t\ttype = type || \"fx\";\n\n\t\treturn this.queue( type, function() {\n\t\t\tvar elem = this;\n\t\t\tsetTimeout(function() {\n\t\t\t\tjQuery.dequeue( elem, type );\n\t\t\t}, time );\n\t\t});\n\t},\n\tclearQueue: function( type ) {\n\t\treturn this.queue( type || \"fx\", [] );\n\t},\n\t// Get a promise resolved when queues of a certain type\n\t// are emptied (fx is the type by default)\n\tpromise: function( type, object ) {\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tobject = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\ttype = type || \"fx\";\n\t\tvar defer = jQuery.Deferred(),\n\t\t\telements = this,\n\t\t\ti = elements.length,\n\t\t\tcount = 1,\n\t\t\tdeferDataKey = type + \"defer\",\n\t\t\tqueueDataKey = type + \"queue\",\n\t\t\tmarkDataKey = type + \"mark\",\n\t\t\ttmp;\n\t\tfunction resolve() {\n\t\t\tif ( !( --count ) ) {\n\t\t\t\tdefer.resolveWith( elements, [ elements ] );\n\t\t\t}\n\t\t}\n\t\twhile( i-- ) {\n\t\t\tif (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) ||\n\t\t\t\t\t( jQuery.data( elements[ i ], queueDataKey, undefined, true ) ||\n\t\t\t\t\t\tjQuery.data( elements[ i ], markDataKey, undefined, true ) ) &&\n\t\t\t\t\tjQuery.data( elements[ i ], deferDataKey, jQuery._Deferred(), true ) )) {\n\t\t\t\tcount++;\n\t\t\t\ttmp.done( resolve );\n\t\t\t}\n\t\t}\n\t\tresolve();\n\t\treturn defer.promise();\n\t}\n});\n\n\n\n\nvar rclass = /[\\n\\t\\r]/g,\n\trspace = /\\s+/,\n\trreturn = /\\r/g,\n\trtype = /^(?:button|input)$/i,\n\trfocusable = /^(?:button|input|object|select|textarea)$/i,\n\trclickable = /^a(?:rea)?$/i,\n\trboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,\n\tnodeHook, boolHook;\n\njQuery.fn.extend({\n\tattr: function( name, value ) {\n\t\treturn jQuery.access( this, name, value, true, jQuery.attr );\n\t},\n\n\tremoveAttr: function( name ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.removeAttr( this, name );\n\t\t});\n\t},\n\t\n\tprop: function( name, value ) {\n\t\treturn jQuery.access( this, name, value, true, jQuery.prop );\n\t},\n\t\n\tremoveProp: function( name ) {\n\t\tname = jQuery.propFix[ name ] || name;\n\t\treturn this.each(function() {\n\t\t\t// try/catch handles cases where IE balks (such as removing a property on window)\n\t\t\ttry {\n\t\t\t\tthis[ name ] = undefined;\n\t\t\t\tdelete this[ name ];\n\t\t\t} catch( e ) {}\n\t\t});\n\t},\n\n\taddClass: function( value ) {\n\t\tvar classNames, i, l, elem,\n\t\t\tsetClass, c, cl;\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( j ) {\n\t\t\t\tjQuery( this ).addClass( value.call(this, j, this.className) );\n\t\t\t});\n\t\t}\n\n\t\tif ( value && typeof value === \"string\" ) {\n\t\t\tclassNames = value.split( rspace );\n\n\t\t\tfor ( i = 0, l = this.length; i < l; i++ ) {\n\t\t\t\telem = this[ i ];\n\n\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\tif ( !elem.className && classNames.length === 1 ) {\n\t\t\t\t\t\telem.className = value;\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsetClass = \" \" + elem.className + \" \";\n\n\t\t\t\t\t\tfor ( c = 0, cl = classNames.length; c < cl; c++ ) {\n\t\t\t\t\t\t\tif ( !~setClass.indexOf( \" \" + classNames[ c ] + \" \" ) ) {\n\t\t\t\t\t\t\t\tsetClass += classNames[ c ] + \" \";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telem.className = jQuery.trim( setClass );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tremoveClass: function( value ) {\n\t\tvar classNames, i, l, elem, className, c, cl;\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( j ) {\n\t\t\t\tjQuery( this ).removeClass( value.call(this, j, this.className) );\n\t\t\t});\n\t\t}\n\n\t\tif ( (value && typeof value === \"string\") || value === undefined ) {\n\t\t\tclassNames = (value || \"\").split( rspace );\n\n\t\t\tfor ( i = 0, l = this.length; i < l; i++ ) {\n\t\t\t\telem = this[ i ];\n\n\t\t\t\tif ( elem.nodeType === 1 && elem.className ) {\n\t\t\t\t\tif ( value ) {\n\t\t\t\t\t\tclassName = (\" \" + elem.className + \" \").replace( rclass, \" \" );\n\t\t\t\t\t\tfor ( c = 0, cl = classNames.length; c < cl; c++ ) {\n\t\t\t\t\t\t\tclassName = className.replace(\" \" + classNames[ c ] + \" \", \" \");\n\t\t\t\t\t\t}\n\t\t\t\t\t\telem.className = jQuery.trim( className );\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\telem.className = \"\";\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\ttoggleClass: function( value, stateVal ) {\n\t\tvar type = typeof value,\n\t\t\tisBool = typeof stateVal === \"boolean\";\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( i ) {\n\t\t\t\tjQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );\n\t\t\t});\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tif ( type === \"string\" ) {\n\t\t\t\t// toggle individual class names\n\t\t\t\tvar className,\n\t\t\t\t\ti = 0,\n\t\t\t\t\tself = jQuery( this ),\n\t\t\t\t\tstate = stateVal,\n\t\t\t\t\tclassNames = value.split( rspace );\n\n\t\t\t\twhile ( (className = classNames[ i++ ]) ) {\n\t\t\t\t\t// check each className given, space seperated list\n\t\t\t\t\tstate = isBool ? state : !self.hasClass( className );\n\t\t\t\t\tself[ state ? \"addClass\" : \"removeClass\" ]( className );\n\t\t\t\t}\n\n\t\t\t} else if ( type === \"undefined\" || type === \"boolean\" ) {\n\t\t\t\tif ( this.className ) {\n\t\t\t\t\t// store className if set\n\t\t\t\t\tjQuery._data( this, \"__className__\", this.className );\n\t\t\t\t}\n\n\t\t\t\t// toggle whole className\n\t\t\t\tthis.className = this.className || value === false ? \"\" : jQuery._data( this, \"__className__\" ) || \"\";\n\t\t\t}\n\t\t});\n\t},\n\n\thasClass: function( selector ) {\n\t\tvar className = \" \" + selector + \" \";\n\t\tfor ( var i = 0, l = this.length; i < l; i++ ) {\n\t\t\tif ( this[i].nodeType === 1 && (\" \" + this[i].className + \" \").replace(rclass, \" \").indexOf( className ) > -1 ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t},\n\n\tval: function( value ) {\n\t\tvar hooks, ret,\n\t\t\telem = this[0];\n\t\t\n\t\tif ( !arguments.length ) {\n\t\t\tif ( elem ) {\n\t\t\t\thooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ];\n\n\t\t\t\tif ( hooks && \"get\" in hooks && (ret = hooks.get( elem, \"value\" )) !== undefined ) {\n\t\t\t\t\treturn ret;\n\t\t\t\t}\n\n\t\t\t\tret = elem.value;\n\n\t\t\t\treturn typeof ret === \"string\" ? \n\t\t\t\t\t// handle most common string cases\n\t\t\t\t\tret.replace(rreturn, \"\") : \n\t\t\t\t\t// handle cases where value is null/undef or number\n\t\t\t\t\tret == null ? \"\" : ret;\n\t\t\t}\n\n\t\t\treturn undefined;\n\t\t}\n\n\t\tvar isFunction = jQuery.isFunction( value );\n\n\t\treturn this.each(function( i ) {\n\t\t\tvar self = jQuery(this), val;\n\n\t\t\tif ( this.nodeType !== 1 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( isFunction ) {\n\t\t\t\tval = value.call( this, i, self.val() );\n\t\t\t} else {\n\t\t\t\tval = value;\n\t\t\t}\n\n\t\t\t// Treat null/undefined as \"\"; convert numbers to string\n\t\t\tif ( val == null ) {\n\t\t\t\tval = \"\";\n\t\t\t} else if ( typeof val === \"number\" ) {\n\t\t\t\tval += \"\";\n\t\t\t} else if ( jQuery.isArray( val ) ) {\n\t\t\t\tval = jQuery.map(val, function ( value ) {\n\t\t\t\t\treturn value == null ? \"\" : value + \"\";\n\t\t\t\t});\n\t\t\t}\n\n\t\t\thooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ];\n\n\t\t\t// If set returns undefined, fall back to normal setting\n\t\t\tif ( !hooks || !(\"set\" in hooks) || hooks.set( this, val, \"value\" ) === undefined ) {\n\t\t\t\tthis.value = val;\n\t\t\t}\n\t\t});\n\t}\n});\n\njQuery.extend({\n\tvalHooks: {\n\t\toption: {\n\t\t\tget: function( elem ) {\n\t\t\t\t// attributes.value is undefined in Blackberry 4.7 but\n\t\t\t\t// uses .value. See #6932\n\t\t\t\tvar val = elem.attributes.value;\n\t\t\t\treturn !val || val.specified ? elem.value : elem.text;\n\t\t\t}\n\t\t},\n\t\tselect: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar value,\n\t\t\t\t\tindex = elem.selectedIndex,\n\t\t\t\t\tvalues = [],\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tone = elem.type === \"select-one\";\n\n\t\t\t\t// Nothing was selected\n\t\t\t\tif ( index < 0 ) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\t// Loop through all the selected options\n\t\t\t\tfor ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {\n\t\t\t\t\tvar option = options[ i ];\n\n\t\t\t\t\t// Don't return options that are disabled or in a disabled optgroup\n\t\t\t\t\tif ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute(\"disabled\") === null) &&\n\t\t\t\t\t\t\t(!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, \"optgroup\" )) ) {\n\n\t\t\t\t\t\t// Get the specific value for the option\n\t\t\t\t\t\tvalue = jQuery( option ).val();\n\n\t\t\t\t\t\t// We don't need an array for one selects\n\t\t\t\t\t\tif ( one ) {\n\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Multi-Selects return an array\n\t\t\t\t\t\tvalues.push( value );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Fixes Bug #2551 -- select.val() broken in IE after form.reset()\n\t\t\t\tif ( one && !values.length && options.length ) {\n\t\t\t\t\treturn jQuery( options[ index ] ).val();\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\t\t\t},\n\n\t\t\tset: function( elem, value ) {\n\t\t\t\tvar values = jQuery.makeArray( value );\n\n\t\t\t\tjQuery(elem).find(\"option\").each(function() {\n\t\t\t\t\tthis.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;\n\t\t\t\t});\n\n\t\t\t\tif ( !values.length ) {\n\t\t\t\t\telem.selectedIndex = -1;\n\t\t\t\t}\n\t\t\t\treturn values;\n\t\t\t}\n\t\t}\n\t},\n\n\tattrFn: {\n\t\tval: true,\n\t\tcss: true,\n\t\thtml: true,\n\t\ttext: true,\n\t\tdata: true,\n\t\twidth: true,\n\t\theight: true,\n\t\toffset: true\n\t},\n\t\n\tattrFix: {\n\t\t// Always normalize to ensure hook usage\n\t\ttabindex: \"tabIndex\"\n\t},\n\t\n\tattr: function( elem, name, value, pass ) {\n\t\tvar nType = elem.nodeType;\n\t\t\n\t\t// don't get/set attributes on text, comment and attribute nodes\n\t\tif ( !elem || nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tif ( pass && name in jQuery.attrFn ) {\n\t\t\treturn jQuery( elem )[ name ]( value );\n\t\t}\n\n\t\t// Fallback to prop when attributes are not supported\n\t\tif ( !(\"getAttribute\" in elem) ) {\n\t\t\treturn jQuery.prop( elem, name, value );\n\t\t}\n\n\t\tvar ret, hooks,\n\t\t\tnotxml = nType !== 1 || !jQuery.isXMLDoc( elem );\n\n\t\t// Normalize the name if needed\n\t\tif ( notxml ) {\n\t\t\tname = jQuery.attrFix[ name ] || name;\n\n\t\t\thooks = jQuery.attrHooks[ name ];\n\n\t\t\tif ( !hooks ) {\n\t\t\t\t// Use boolHook for boolean attributes\n\t\t\t\tif ( rboolean.test( name ) ) {\n\t\t\t\t\thooks = boolHook;\n\n\t\t\t\t// Use nodeHook if available( IE6/7 )\n\t\t\t\t} else if ( nodeHook ) {\n\t\t\t\t\thooks = nodeHook;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\n\t\t\tif ( value === null ) {\n\t\t\t\tjQuery.removeAttr( elem, name );\n\t\t\t\treturn undefined;\n\n\t\t\t} else if ( hooks && \"set\" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {\n\t\t\t\treturn ret;\n\n\t\t\t} else {\n\t\t\t\telem.setAttribute( name, \"\" + value );\n\t\t\t\treturn value;\n\t\t\t}\n\n\t\t} else if ( hooks && \"get\" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) {\n\t\t\treturn ret;\n\n\t\t} else {\n\n\t\t\tret = elem.getAttribute( name );\n\n\t\t\t// Non-existent attributes return null, we normalize to undefined\n\t\t\treturn ret === null ?\n\t\t\t\tundefined :\n\t\t\t\tret;\n\t\t}\n\t},\n\n\tremoveAttr: function( elem, name ) {\n\t\tvar propName;\n\t\tif ( elem.nodeType === 1 ) {\n\t\t\tname = jQuery.attrFix[ name ] || name;\n\n\t\t\tjQuery.attr( elem, name, \"\" );\n\t\t\telem.removeAttribute( name );\n\n\t\t\t// Set corresponding property to false for boolean attributes\n\t\t\tif ( rboolean.test( name ) && (propName = jQuery.propFix[ name ] || name) in elem ) {\n\t\t\t\telem[ propName ] = false;\n\t\t\t}\n\t\t}\n\t},\n\n\tattrHooks: {\n\t\ttype: {\n\t\t\tset: function( elem, value ) {\n\t\t\t\t// We can't allow the type property to be changed (since it causes problems in IE)\n\t\t\t\tif ( rtype.test( elem.nodeName ) && elem.parentNode ) {\n\t\t\t\t\tjQuery.error( \"type property can't be changed\" );\n\t\t\t\t} else if ( !jQuery.support.radioValue && value === \"radio\" && jQuery.nodeName(elem, \"input\") ) {\n\t\t\t\t\t// Setting the type on a radio button after the value resets the value in IE6-9\n\t\t\t\t\t// Reset value to it's default in case type is set after value\n\t\t\t\t\t// This is for element creation\n\t\t\t\t\tvar val = elem.value;\n\t\t\t\t\telem.setAttribute( \"type\", value );\n\t\t\t\t\tif ( val ) {\n\t\t\t\t\t\telem.value = val;\n\t\t\t\t\t}\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t// Use the value property for back compat\n\t\t// Use the nodeHook for button elements in IE6/7 (#1954)\n\t\tvalue: {\n\t\t\tget: function( elem, name ) {\n\t\t\t\tif ( nodeHook && jQuery.nodeName( elem, \"button\" ) ) {\n\t\t\t\t\treturn nodeHook.get( elem, name );\n\t\t\t\t}\n\t\t\t\treturn name in elem ?\n\t\t\t\t\telem.value :\n\t\t\t\t\tnull;\n\t\t\t},\n\t\t\tset: function( elem, value, name ) {\n\t\t\t\tif ( nodeHook && jQuery.nodeName( elem, \"button\" ) ) {\n\t\t\t\t\treturn nodeHook.set( elem, value, name );\n\t\t\t\t}\n\t\t\t\t// Does not return so that setAttribute is also used\n\t\t\t\telem.value = value;\n\t\t\t}\n\t\t}\n\t},\n\n\tpropFix: {\n\t\ttabindex: \"tabIndex\",\n\t\treadonly: \"readOnly\",\n\t\t\"for\": \"htmlFor\",\n\t\t\"class\": \"className\",\n\t\tmaxlength: \"maxLength\",\n\t\tcellspacing: \"cellSpacing\",\n\t\tcellpadding: \"cellPadding\",\n\t\trowspan: \"rowSpan\",\n\t\tcolspan: \"colSpan\",\n\t\tusemap: \"useMap\",\n\t\tframeborder: \"frameBorder\",\n\t\tcontenteditable: \"contentEditable\"\n\t},\n\t\n\tprop: function( elem, name, value ) {\n\t\tvar nType = elem.nodeType;\n\n\t\t// don't get/set properties on text, comment and attribute nodes\n\t\tif ( !elem || nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tvar ret, hooks,\n\t\t\tnotxml = nType !== 1 || !jQuery.isXMLDoc( elem );\n\n\t\tif ( notxml ) {\n\t\t\t// Fix name and attach hooks\n\t\t\tname = jQuery.propFix[ name ] || name;\n\t\t\thooks = jQuery.propHooks[ name ];\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\tif ( hooks && \"set\" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {\n\t\t\t\treturn ret;\n\n\t\t\t} else {\n\t\t\t\treturn (elem[ name ] = value);\n\t\t\t}\n\n\t\t} else {\n\t\t\tif ( hooks && \"get\" in hooks && (ret = hooks.get( elem, name )) !== null ) {\n\t\t\t\treturn ret;\n\n\t\t\t} else {\n\t\t\t\treturn elem[ name ];\n\t\t\t}\n\t\t}\n\t},\n\t\n\tpropHooks: {\n\t\ttabIndex: {\n\t\t\tget: function( elem ) {\n\t\t\t\t// elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set\n\t\t\t\t// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/\n\t\t\t\tvar attributeNode = elem.getAttributeNode(\"tabindex\");\n\n\t\t\t\treturn attributeNode && attributeNode.specified ?\n\t\t\t\t\tparseInt( attributeNode.value, 10 ) :\n\t\t\t\t\trfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?\n\t\t\t\t\t\t0 :\n\t\t\t\t\t\tundefined;\n\t\t\t}\n\t\t}\n\t}\n});\n\n// Add the tabindex propHook to attrHooks for back-compat\njQuery.attrHooks.tabIndex = jQuery.propHooks.tabIndex;\n\n// Hook for boolean attributes\nboolHook = {\n\tget: function( elem, name ) {\n\t\t// Align boolean attributes with corresponding properties\n\t\t// Fall back to attribute presence where some booleans are not supported\n\t\tvar attrNode;\n\t\treturn jQuery.prop( elem, name ) === true || ( attrNode = elem.getAttributeNode( name ) ) && attrNode.nodeValue !== false ?\n\t\t\tname.toLowerCase() :\n\t\t\tundefined;\n\t},\n\tset: function( elem, value, name ) {\n\t\tvar propName;\n\t\tif ( value === false ) {\n\t\t\t// Remove boolean attributes when set to false\n\t\t\tjQuery.removeAttr( elem, name );\n\t\t} else {\n\t\t\t// value is true since we know at this point it's type boolean and not false\n\t\t\t// Set boolean attributes to the same name and set the DOM property\n\t\t\tpropName = jQuery.propFix[ name ] || name;\n\t\t\tif ( propName in elem ) {\n\t\t\t\t// Only set the IDL specifically if it already exists on the element\n\t\t\t\telem[ propName ] = true;\n\t\t\t}\n\n\t\t\telem.setAttribute( name, name.toLowerCase() );\n\t\t}\n\t\treturn name;\n\t}\n};\n\n// IE6/7 do not support getting/setting some attributes with get/setAttribute\nif ( !jQuery.support.getSetAttribute ) {\n\t\n\t// Use this for any attribute in IE6/7\n\t// This fixes almost every IE6/7 issue\n\tnodeHook = jQuery.valHooks.button = {\n\t\tget: function( elem, name ) {\n\t\t\tvar ret;\n\t\t\tret = elem.getAttributeNode( name );\n\t\t\t// Return undefined if nodeValue is empty string\n\t\t\treturn ret && ret.nodeValue !== \"\" ?\n\t\t\t\tret.nodeValue :\n\t\t\t\tundefined;\n\t\t},\n\t\tset: function( elem, value, name ) {\n\t\t\t// Set the existing or create a new attribute node\n\t\t\tvar ret = elem.getAttributeNode( name );\n\t\t\tif ( !ret ) {\n\t\t\t\tret = document.createAttribute( name );\n\t\t\t\telem.setAttributeNode( ret );\n\t\t\t}\n\t\t\treturn (ret.nodeValue = value + \"\");\n\t\t}\n\t};\n\n\t// Set width and height to auto instead of 0 on empty string( Bug #8150 )\n\t// This is for removals\n\tjQuery.each([ \"width\", \"height\" ], function( i, name ) {\n\t\tjQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tif ( value === \"\" ) {\n\t\t\t\t\telem.setAttribute( name, \"auto\" );\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t});\n}\n\n\n// Some attributes require a special call on IE\nif ( !jQuery.support.hrefNormalized ) {\n\tjQuery.each([ \"href\", \"src\", \"width\", \"height\" ], function( i, name ) {\n\t\tjQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar ret = elem.getAttribute( name, 2 );\n\t\t\t\treturn ret === null ? undefined : ret;\n\t\t\t}\n\t\t});\n\t});\n}\n\nif ( !jQuery.support.style ) {\n\tjQuery.attrHooks.style = {\n\t\tget: function( elem ) {\n\t\t\t// Return undefined in the case of empty string\n\t\t\t// Normalize to lowercase since IE uppercases css property names\n\t\t\treturn elem.style.cssText.toLowerCase() || undefined;\n\t\t},\n\t\tset: function( elem, value ) {\n\t\t\treturn (elem.style.cssText = \"\" + value);\n\t\t}\n\t};\n}\n\n// Safari mis-reports the default selected property of an option\n// Accessing the parent's selectedIndex property fixes it\nif ( !jQuery.support.optSelected ) {\n\tjQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {\n\t\tget: function( elem ) {\n\t\t\tvar parent = elem.parentNode;\n\n\t\t\tif ( parent ) {\n\t\t\t\tparent.selectedIndex;\n\n\t\t\t\t// Make sure that it also works with optgroups, see #5701\n\t\t\t\tif ( parent.parentNode ) {\n\t\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t});\n}\n\n// Radios and checkboxes getter/setter\nif ( !jQuery.support.checkOn ) {\n\tjQuery.each([ \"radio\", \"checkbox\" ], function() {\n\t\tjQuery.valHooks[ this ] = {\n\t\t\tget: function( elem ) {\n\t\t\t\t// Handle the case where in Webkit \"\" is returned instead of \"on\" if a value isn't specified\n\t\t\t\treturn elem.getAttribute(\"value\") === null ? \"on\" : elem.value;\n\t\t\t}\n\t\t};\n\t});\n}\njQuery.each([ \"radio\", \"checkbox\" ], function() {\n\tjQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {\n\t\tset: function( elem, value ) {\n\t\t\tif ( jQuery.isArray( value ) ) {\n\t\t\t\treturn (elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0);\n\t\t\t}\n\t\t}\n\t});\n});\n\n\n\n\nvar rnamespaces = /\\.(.*)$/,\n\trformElems = /^(?:textarea|input|select)$/i,\n\trperiod = /\\./g,\n\trspaces = / /g,\n\trescape = /[^\\w\\s.|`]/g,\n\tfcleanup = function( nm ) {\n\t\treturn nm.replace(rescape, \"\\\\$&\");\n\t};\n\n/*\n * A number of helper functions used for managing events.\n * Many of the ideas behind this code originated from\n * Dean Edwards' addEvent library.\n */\njQuery.event = {\n\n\t// Bind an event to an element\n\t// Original by Dean Edwards\n\tadd: function( elem, types, handler, data ) {\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 8 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( handler === false ) {\n\t\t\thandler = returnFalse;\n\t\t} else if ( !handler ) {\n\t\t\t// Fixes bug #7229. Fix recommended by jdalton\n\t\t\treturn;\n\t\t}\n\n\t\tvar handleObjIn, handleObj;\n\n\t\tif ( handler.handler ) {\n\t\t\thandleObjIn = handler;\n\t\t\thandler = handleObjIn.handler;\n\t\t}\n\n\t\t// Make sure that the function being executed has a unique ID\n\t\tif ( !handler.guid ) {\n\t\t\thandler.guid = jQuery.guid++;\n\t\t}\n\n\t\t// Init the element's event structure\n\t\tvar elemData = jQuery._data( elem );\n\n\t\t// If no elemData is found then we must be trying to bind to one of the\n\t\t// banned noData elements\n\t\tif ( !elemData ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar events = elemData.events,\n\t\t\teventHandle = elemData.handle;\n\n\t\tif ( !events ) {\n\t\t\telemData.events = events = {};\n\t\t}\n\n\t\tif ( !eventHandle ) {\n\t\t\telemData.handle = eventHandle = function( e ) {\n\t\t\t\t// Discard the second event of a jQuery.event.trigger() and\n\t\t\t\t// when an event is called after a page has unloaded\n\t\t\t\treturn typeof jQuery !== \"undefined\" && (!e || jQuery.event.triggered !== e.type) ?\n\t\t\t\t\tjQuery.event.handle.apply( eventHandle.elem, arguments ) :\n\t\t\t\t\tundefined;\n\t\t\t};\n\t\t}\n\n\t\t// Add elem as a property of the handle function\n\t\t// This is to prevent a memory leak with non-native events in IE.\n\t\teventHandle.elem = elem;\n\n\t\t// Handle multiple events separated by a space\n\t\t// jQuery(...).bind(\"mouseover mouseout\", fn);\n\t\ttypes = types.split(\" \");\n\n\t\tvar type, i = 0, namespaces;\n\n\t\twhile ( (type = types[ i++ ]) ) {\n\t\t\thandleObj = handleObjIn ?\n\t\t\t\tjQuery.extend({}, handleObjIn) :\n\t\t\t\t{ handler: handler, data: data };\n\n\t\t\t// Namespaced event handlers\n\t\t\tif ( type.indexOf(\".\") > -1 ) {\n\t\t\t\tnamespaces = type.split(\".\");\n\t\t\t\ttype = namespaces.shift();\n\t\t\t\thandleObj.namespace = namespaces.slice(0).sort().join(\".\");\n\n\t\t\t} else {\n\t\t\t\tnamespaces = [];\n\t\t\t\thandleObj.namespace = \"\";\n\t\t\t}\n\n\t\t\thandleObj.type = type;\n\t\t\tif ( !handleObj.guid ) {\n\t\t\t\thandleObj.guid = handler.guid;\n\t\t\t}\n\n\t\t\t// Get the current list of functions bound to this event\n\t\t\tvar handlers = events[ type ],\n\t\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// Init the event handler queue\n\t\t\tif ( !handlers ) {\n\t\t\t\thandlers = events[ type ] = [];\n\n\t\t\t\t// Check for a special event handler\n\t\t\t\t// Only use addEventListener/attachEvent if the special\n\t\t\t\t// events handler returns false\n\t\t\t\tif ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {\n\t\t\t\t\t// Bind the global event handler to the element\n\t\t\t\t\tif ( elem.addEventListener ) {\n\t\t\t\t\t\telem.addEventListener( type, eventHandle, false );\n\n\t\t\t\t\t} else if ( elem.attachEvent ) {\n\t\t\t\t\t\telem.attachEvent( \"on\" + type, eventHandle );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( special.add ) {\n\t\t\t\tspecial.add.call( elem, handleObj );\n\n\t\t\t\tif ( !handleObj.handler.guid ) {\n\t\t\t\t\thandleObj.handler.guid = handler.guid;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add the function to the element's handler list\n\t\t\thandlers.push( handleObj );\n\n\t\t\t// Keep track of which events have been used, for event optimization\n\t\t\tjQuery.event.global[ type ] = true;\n\t\t}\n\n\t\t// Nullify elem to prevent memory leaks in IE\n\t\telem = null;\n\t},\n\n\tglobal: {},\n\n\t// Detach an event or set of events from an element\n\tremove: function( elem, types, handler, pos ) {\n\t\t// don't do events on text and comment nodes\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 8 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( handler === false ) {\n\t\t\thandler = returnFalse;\n\t\t}\n\n\t\tvar ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,\n\t\t\telemData = jQuery.hasData( elem ) && jQuery._data( elem ),\n\t\t\tevents = elemData && elemData.events;\n\n\t\tif ( !elemData || !events ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// types is actually an event object here\n\t\tif ( types && types.type ) {\n\t\t\thandler = types.handler;\n\t\t\ttypes = types.type;\n\t\t}\n\n\t\t// Unbind all events for the element\n\t\tif ( !types || typeof types === \"string\" && types.charAt(0) === \".\" ) {\n\t\t\ttypes = types || \"\";\n\n\t\t\tfor ( type in events ) {\n\t\t\t\tjQuery.event.remove( elem, type + types );\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\t// Handle multiple events separated by a space\n\t\t// jQuery(...).unbind(\"mouseover mouseout\", fn);\n\t\ttypes = types.split(\" \");\n\n\t\twhile ( (type = types[ i++ ]) ) {\n\t\t\torigType = type;\n\t\t\thandleObj = null;\n\t\t\tall = type.indexOf(\".\") < 0;\n\t\t\tnamespaces = [];\n\n\t\t\tif ( !all ) {\n\t\t\t\t// Namespaced event handlers\n\t\t\t\tnamespaces = type.split(\".\");\n\t\t\t\ttype = namespaces.shift();\n\n\t\t\t\tnamespace = new RegExp(\"(^|\\\\.)\" +\n\t\t\t\t\tjQuery.map( namespaces.slice(0).sort(), fcleanup ).join(\"\\\\.(?:.*\\\\.)?\") + \"(\\\\.|$)\");\n\t\t\t}\n\n\t\t\teventType = events[ type ];\n\n\t\t\tif ( !eventType ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif ( !handler ) {\n\t\t\t\tfor ( j = 0; j < eventType.length; j++ ) {\n\t\t\t\t\thandleObj = eventType[ j ];\n\n\t\t\t\t\tif ( all || namespace.test( handleObj.namespace ) ) {\n\t\t\t\t\t\tjQuery.event.remove( elem, origType, handleObj.handler, j );\n\t\t\t\t\t\teventType.splice( j--, 1 );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\tfor ( j = pos || 0; j < eventType.length; j++ ) {\n\t\t\t\thandleObj = eventType[ j ];\n\n\t\t\t\tif ( handler.guid === handleObj.guid ) {\n\t\t\t\t\t// remove the given handler for the given type\n\t\t\t\t\tif ( all || namespace.test( handleObj.namespace ) ) {\n\t\t\t\t\t\tif ( pos == null ) {\n\t\t\t\t\t\t\teventType.splice( j--, 1 );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( special.remove ) {\n\t\t\t\t\t\t\tspecial.remove.call( elem, handleObj );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( pos != null ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// remove generic event handler if no more handlers exist\n\t\t\tif ( eventType.length === 0 || pos != null && eventType.length === 1 ) {\n\t\t\t\tif ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {\n\t\t\t\t\tjQuery.removeEvent( elem, type, elemData.handle );\n\t\t\t\t}\n\n\t\t\t\tret = null;\n\t\t\t\tdelete events[ type ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove the expando if it's no longer used\n\t\tif ( jQuery.isEmptyObject( events ) ) {\n\t\t\tvar handle = elemData.handle;\n\t\t\tif ( handle ) {\n\t\t\t\thandle.elem = null;\n\t\t\t}\n\n\t\t\tdelete elemData.events;\n\t\t\tdelete elemData.handle;\n\n\t\t\tif ( jQuery.isEmptyObject( elemData ) ) {\n\t\t\t\tjQuery.removeData( elem, undefined, true );\n\t\t\t}\n\t\t}\n\t},\n\t\n\t// Events that are safe to short-circuit if no handlers are attached.\n\t// Native DOM events should not be added, they may have inline handlers.\n\tcustomEvent: {\n\t\t\"getData\": true,\n\t\t\"setData\": true,\n\t\t\"changeData\": true\n\t},\n\n\ttrigger: function( event, data, elem, onlyHandlers ) {\n\t\t// Event object or event type\n\t\tvar type = event.type || event,\n\t\t\tnamespaces = [],\n\t\t\texclusive;\n\n\t\tif ( type.indexOf(\"!\") >= 0 ) {\n\t\t\t// Exclusive events trigger only for the exact event (no namespaces)\n\t\t\ttype = type.slice(0, -1);\n\t\t\texclusive = true;\n\t\t}\n\n\t\tif ( type.indexOf(\".\") >= 0 ) {\n\t\t\t// Namespaced trigger; create a regexp to match event type in handle()\n\t\t\tnamespaces = type.split(\".\");\n\t\t\ttype = namespaces.shift();\n\t\t\tnamespaces.sort();\n\t\t}\n\n\t\tif ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) {\n\t\t\t// No jQuery handlers for this event type, and it can't have inline handlers\n\t\t\treturn;\n\t\t}\n\n\t\t// Caller can pass in an Event, Object, or just an event type string\n\t\tevent = typeof event === \"object\" ?\n\t\t\t// jQuery.Event object\n\t\t\tevent[ jQuery.expando ] ? event :\n\t\t\t// Object literal\n\t\t\tnew jQuery.Event( type, event ) :\n\t\t\t// Just the event type (string)\n\t\t\tnew jQuery.Event( type );\n\n\t\tevent.type = type;\n\t\tevent.exclusive = exclusive;\n\t\tevent.namespace = namespaces.join(\".\");\n\t\tevent.namespace_re = new RegExp(\"(^|\\\\.)\" + namespaces.join(\"\\\\.(?:.*\\\\.)?\") + \"(\\\\.|$)\");\n\t\t\n\t\t// triggerHandler() and global events don't bubble or run the default action\n\t\tif ( onlyHandlers || !elem ) {\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\t\t}\n\n\t\t// Handle a global trigger\n\t\tif ( !elem ) {\n\t\t\t// TODO: Stop taunting the data cache; remove global events and always attach to document\n\t\t\tjQuery.each( jQuery.cache, function() {\n\t\t\t\t// internalKey variable is just used to make it easier to find\n\t\t\t\t// and potentially change this stuff later; currently it just\n\t\t\t\t// points to jQuery.expando\n\t\t\t\tvar internalKey = jQuery.expando,\n\t\t\t\t\tinternalCache = this[ internalKey ];\n\t\t\t\tif ( internalCache && internalCache.events && internalCache.events[ type ] ) {\n\t\t\t\t\tjQuery.event.trigger( event, data, internalCache.handle.elem );\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\t// Don't do events on text and comment nodes\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 8 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Clean up the event in case it is being reused\n\t\tevent.result = undefined;\n\t\tevent.target = elem;\n\n\t\t// Clone any incoming data and prepend the event, creating the handler arg list\n\t\tdata = data != null ? jQuery.makeArray( data ) : [];\n\t\tdata.unshift( event );\n\n\t\tvar cur = elem,\n\t\t\t// IE doesn't like method names with a colon (#3533, #8272)\n\t\t\tontype = type.indexOf(\":\") < 0 ? \"on\" + type : \"\";\n\n\t\t// Fire event on the current element, then bubble up the DOM tree\n\t\tdo {\n\t\t\tvar handle = jQuery._data( cur, \"handle\" );\n\n\t\t\tevent.currentTarget = cur;\n\t\t\tif ( handle ) {\n\t\t\t\thandle.apply( cur, data );\n\t\t\t}\n\n\t\t\t// Trigger an inline bound script\n\t\t\tif ( ontype && jQuery.acceptData( cur ) && cur[ ontype ] && cur[ ontype ].apply( cur, data ) === false ) {\n\t\t\t\tevent.result = false;\n\t\t\t\tevent.preventDefault();\n\t\t\t}\n\n\t\t\t// Bubble up to document, then to window\n\t\t\tcur = cur.parentNode || cur.ownerDocument || cur === event.target.ownerDocument && window;\n\t\t} while ( cur && !event.isPropagationStopped() );\n\n\t\t// If nobody prevented the default action, do it now\n\t\tif ( !event.isDefaultPrevented() ) {\n\t\t\tvar old,\n\t\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\tif ( (!special._default || special._default.call( elem.ownerDocument, event ) === false) &&\n\t\t\t\t!(type === \"click\" && jQuery.nodeName( elem, \"a\" )) && jQuery.acceptData( elem ) ) {\n\n\t\t\t\t// Call a native DOM method on the target with the same name name as the event.\n\t\t\t\t// Can't use an .isFunction)() check here because IE6/7 fails that test.\n\t\t\t\t// IE<9 dies on focus to hidden element (#1486), may want to revisit a try/catch.\n\t\t\t\ttry {\n\t\t\t\t\tif ( ontype && elem[ type ] ) {\n\t\t\t\t\t\t// Don't re-trigger an onFOO event when we call its FOO() method\n\t\t\t\t\t\told = elem[ ontype ];\n\n\t\t\t\t\t\tif ( old ) {\n\t\t\t\t\t\t\telem[ ontype ] = null;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tjQuery.event.triggered = type;\n\t\t\t\t\t\telem[ type ]();\n\t\t\t\t\t}\n\t\t\t\t} catch ( ieError ) {}\n\n\t\t\t\tif ( old ) {\n\t\t\t\t\telem[ ontype ] = old;\n\t\t\t\t}\n\n\t\t\t\tjQuery.event.triggered = undefined;\n\t\t\t}\n\t\t}\n\t\t\n\t\treturn event.result;\n\t},\n\n\thandle: function( event ) {\n\t\tevent = jQuery.event.fix( event || window.event );\n\t\t// Snapshot the handlers list since a called handler may add/remove events.\n\t\tvar handlers = ((jQuery._data( this, \"events\" ) || {})[ event.type ] || []).slice(0),\n\t\t\trun_all = !event.exclusive && !event.namespace,\n\t\t\targs = Array.prototype.slice.call( arguments, 0 );\n\n\t\t// Use the fix-ed Event rather than the (read-only) native event\n\t\targs[0] = event;\n\t\tevent.currentTarget = this;\n\n\t\tfor ( var j = 0, l = handlers.length; j < l; j++ ) {\n\t\t\tvar handleObj = handlers[ j ];\n\n\t\t\t// Triggered event must 1) be non-exclusive and have no namespace, or\n\t\t\t// 2) have namespace(s) a subset or equal to those in the bound event.\n\t\t\tif ( run_all || event.namespace_re.test( handleObj.namespace ) ) {\n\t\t\t\t// Pass in a reference to the handler function itself\n\t\t\t\t// So that we can later remove it\n\t\t\t\tevent.handler = handleObj.handler;\n\t\t\t\tevent.data = handleObj.data;\n\t\t\t\tevent.handleObj = handleObj;\n\n\t\t\t\tvar ret = handleObj.handler.apply( this, args );\n\n\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\tevent.result = ret;\n\t\t\t\t\tif ( ret === false ) {\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( event.isImmediatePropagationStopped() ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn event.result;\n\t},\n\n\tprops: \"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which\".split(\" \"),\n\n\tfix: function( event ) {\n\t\tif ( event[ jQuery.expando ] ) {\n\t\t\treturn event;\n\t\t}\n\n\t\t// store a copy of the original event object\n\t\t// and \"clone\" to set read-only properties\n\t\tvar originalEvent = event;\n\t\tevent = jQuery.Event( originalEvent );\n\n\t\tfor ( var i = this.props.length, prop; i; ) {\n\t\t\tprop = this.props[ --i ];\n\t\t\tevent[ prop ] = originalEvent[ prop ];\n\t\t}\n\n\t\t// Fix target property, if necessary\n\t\tif ( !event.target ) {\n\t\t\t// Fixes #1925 where srcElement might not be defined either\n\t\t\tevent.target = event.srcElement || document;\n\t\t}\n\n\t\t// check if target is a textnode (safari)\n\t\tif ( event.target.nodeType === 3 ) {\n\t\t\tevent.target = event.target.parentNode;\n\t\t}\n\n\t\t// Add relatedTarget, if necessary\n\t\tif ( !event.relatedTarget && event.fromElement ) {\n\t\t\tevent.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;\n\t\t}\n\n\t\t// Calculate pageX/Y if missing and clientX/Y available\n\t\tif ( event.pageX == null && event.clientX != null ) {\n\t\t\tvar eventDocument = event.target.ownerDocument || document,\n\t\t\t\tdoc = eventDocument.documentElement,\n\t\t\t\tbody = eventDocument.body;\n\n\t\t\tevent.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);\n\t\t\tevent.pageY = event.clientY + (doc && doc.scrollTop  || body && body.scrollTop  || 0) - (doc && doc.clientTop  || body && body.clientTop  || 0);\n\t\t}\n\n\t\t// Add which for key events\n\t\tif ( event.which == null && (event.charCode != null || event.keyCode != null) ) {\n\t\t\tevent.which = event.charCode != null ? event.charCode : event.keyCode;\n\t\t}\n\n\t\t// Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)\n\t\tif ( !event.metaKey && event.ctrlKey ) {\n\t\t\tevent.metaKey = event.ctrlKey;\n\t\t}\n\n\t\t// Add which for click: 1 === left; 2 === middle; 3 === right\n\t\t// Note: button is not normalized, so don't use it\n\t\tif ( !event.which && event.button !== undefined ) {\n\t\t\tevent.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));\n\t\t}\n\n\t\treturn event;\n\t},\n\n\t// Deprecated, use jQuery.guid instead\n\tguid: 1E8,\n\n\t// Deprecated, use jQuery.proxy instead\n\tproxy: jQuery.proxy,\n\n\tspecial: {\n\t\tready: {\n\t\t\t// Make sure the ready event is setup\n\t\t\tsetup: jQuery.bindReady,\n\t\t\tteardown: jQuery.noop\n\t\t},\n\n\t\tlive: {\n\t\t\tadd: function( handleObj ) {\n\t\t\t\tjQuery.event.add( this,\n\t\t\t\t\tliveConvert( handleObj.origType, handleObj.selector ),\n\t\t\t\t\tjQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) );\n\t\t\t},\n\n\t\t\tremove: function( handleObj ) {\n\t\t\t\tjQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj );\n\t\t\t}\n\t\t},\n\n\t\tbeforeunload: {\n\t\t\tsetup: function( data, namespaces, eventHandle ) {\n\t\t\t\t// We only want to do this special case on windows\n\t\t\t\tif ( jQuery.isWindow( this ) ) {\n\t\t\t\t\tthis.onbeforeunload = eventHandle;\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tteardown: function( namespaces, eventHandle ) {\n\t\t\t\tif ( this.onbeforeunload === eventHandle ) {\n\t\t\t\t\tthis.onbeforeunload = null;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n};\n\njQuery.removeEvent = document.removeEventListener ?\n\tfunction( elem, type, handle ) {\n\t\tif ( elem.removeEventListener ) {\n\t\t\telem.removeEventListener( type, handle, false );\n\t\t}\n\t} :\n\tfunction( elem, type, handle ) {\n\t\tif ( elem.detachEvent ) {\n\t\t\telem.detachEvent( \"on\" + type, handle );\n\t\t}\n\t};\n\njQuery.Event = function( src, props ) {\n\t// Allow instantiation without the 'new' keyword\n\tif ( !this.preventDefault ) {\n\t\treturn new jQuery.Event( src, props );\n\t}\n\n\t// Event object\n\tif ( src && src.type ) {\n\t\tthis.originalEvent = src;\n\t\tthis.type = src.type;\n\n\t\t// Events bubbling up the document may have been marked as prevented\n\t\t// by a handler lower down the tree; reflect the correct value.\n\t\tthis.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false ||\n\t\t\tsrc.getPreventDefault && src.getPreventDefault()) ? returnTrue : returnFalse;\n\n\t// Event type\n\t} else {\n\t\tthis.type = src;\n\t}\n\n\t// Put explicitly provided properties onto the event object\n\tif ( props ) {\n\t\tjQuery.extend( this, props );\n\t}\n\n\t// timeStamp is buggy for some events on Firefox(#3843)\n\t// So we won't rely on the native value\n\tthis.timeStamp = jQuery.now();\n\n\t// Mark it as fixed\n\tthis[ jQuery.expando ] = true;\n};\n\nfunction returnFalse() {\n\treturn false;\n}\nfunction returnTrue() {\n\treturn true;\n}\n\n// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding\n// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\njQuery.Event.prototype = {\n\tpreventDefault: function() {\n\t\tthis.isDefaultPrevented = returnTrue;\n\n\t\tvar e = this.originalEvent;\n\t\tif ( !e ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// if preventDefault exists run it on the original event\n\t\tif ( e.preventDefault ) {\n\t\t\te.preventDefault();\n\n\t\t// otherwise set the returnValue property of the original event to false (IE)\n\t\t} else {\n\t\t\te.returnValue = false;\n\t\t}\n\t},\n\tstopPropagation: function() {\n\t\tthis.isPropagationStopped = returnTrue;\n\n\t\tvar e = this.originalEvent;\n\t\tif ( !e ) {\n\t\t\treturn;\n\t\t}\n\t\t// if stopPropagation exists run it on the original event\n\t\tif ( e.stopPropagation ) {\n\t\t\te.stopPropagation();\n\t\t}\n\t\t// otherwise set the cancelBubble property of the original event to true (IE)\n\t\te.cancelBubble = true;\n\t},\n\tstopImmediatePropagation: function() {\n\t\tthis.isImmediatePropagationStopped = returnTrue;\n\t\tthis.stopPropagation();\n\t},\n\tisDefaultPrevented: returnFalse,\n\tisPropagationStopped: returnFalse,\n\tisImmediatePropagationStopped: returnFalse\n};\n\n// Checks if an event happened on an element within another element\n// Used in jQuery.event.special.mouseenter and mouseleave handlers\nvar withinElement = function( event ) {\n\n\t// Check if mouse(over|out) are still within the same parent element\n\tvar related = event.relatedTarget,\n\t\tinside = false,\n\t\teventType = event.type;\n\n\tevent.type = event.data;\n\n\tif ( related !== this ) {\n\n\t\tif ( related ) {\n\t\t\tinside = jQuery.contains( this, related );\n\t\t}\n\n\t\tif ( !inside ) {\n\n\t\t\tjQuery.event.handle.apply( this, arguments );\n\n\t\t\tevent.type = eventType;\n\t\t}\n\t}\n},\n\n// In case of event delegation, we only need to rename the event.type,\n// liveHandler will take care of the rest.\ndelegate = function( event ) {\n\tevent.type = event.data;\n\tjQuery.event.handle.apply( this, arguments );\n};\n\n// Create mouseenter and mouseleave events\njQuery.each({\n\tmouseenter: \"mouseover\",\n\tmouseleave: \"mouseout\"\n}, function( orig, fix ) {\n\tjQuery.event.special[ orig ] = {\n\t\tsetup: function( data ) {\n\t\t\tjQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );\n\t\t},\n\t\tteardown: function( data ) {\n\t\t\tjQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );\n\t\t}\n\t};\n});\n\n// submit delegation\nif ( !jQuery.support.submitBubbles ) {\n\n\tjQuery.event.special.submit = {\n\t\tsetup: function( data, namespaces ) {\n\t\t\tif ( !jQuery.nodeName( this, \"form\" ) ) {\n\t\t\t\tjQuery.event.add(this, \"click.specialSubmit\", function( e ) {\n\t\t\t\t\t// Avoid triggering error on non-existent type attribute in IE VML (#7071)\n\t\t\t\t\tvar elem = e.target,\n\t\t\t\t\t\ttype = jQuery.nodeName( elem, \"input\" ) || jQuery.nodeName( elem, \"button\" ) ? elem.type : \"\";\n\n\t\t\t\t\tif ( (type === \"submit\" || type === \"image\") && jQuery( elem ).closest(\"form\").length ) {\n\t\t\t\t\t\ttrigger( \"submit\", this, arguments );\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tjQuery.event.add(this, \"keypress.specialSubmit\", function( e ) {\n\t\t\t\t\tvar elem = e.target,\n\t\t\t\t\t\ttype = jQuery.nodeName( elem, \"input\" ) || jQuery.nodeName( elem, \"button\" ) ? elem.type : \"\";\n\n\t\t\t\t\tif ( (type === \"text\" || type === \"password\") && jQuery( elem ).closest(\"form\").length && e.keyCode === 13 ) {\n\t\t\t\t\t\ttrigger( \"submit\", this, arguments );\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t} else {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\n\t\tteardown: function( namespaces ) {\n\t\t\tjQuery.event.remove( this, \".specialSubmit\" );\n\t\t}\n\t};\n\n}\n\n// change delegation, happens here so we have bind.\nif ( !jQuery.support.changeBubbles ) {\n\n\tvar changeFilters,\n\n\tgetVal = function( elem ) {\n\t\tvar type = jQuery.nodeName( elem, \"input\" ) ? elem.type : \"\",\n\t\t\tval = elem.value;\n\n\t\tif ( type === \"radio\" || type === \"checkbox\" ) {\n\t\t\tval = elem.checked;\n\n\t\t} else if ( type === \"select-multiple\" ) {\n\t\t\tval = elem.selectedIndex > -1 ?\n\t\t\t\tjQuery.map( elem.options, function( elem ) {\n\t\t\t\t\treturn elem.selected;\n\t\t\t\t}).join(\"-\") :\n\t\t\t\t\"\";\n\n\t\t} else if ( jQuery.nodeName( elem, \"select\" ) ) {\n\t\t\tval = elem.selectedIndex;\n\t\t}\n\n\t\treturn val;\n\t},\n\n\ttestChange = function testChange( e ) {\n\t\tvar elem = e.target, data, val;\n\n\t\tif ( !rformElems.test( elem.nodeName ) || elem.readOnly ) {\n\t\t\treturn;\n\t\t}\n\n\t\tdata = jQuery._data( elem, \"_change_data\" );\n\t\tval = getVal(elem);\n\n\t\t// the current data will be also retrieved by beforeactivate\n\t\tif ( e.type !== \"focusout\" || elem.type !== \"radio\" ) {\n\t\t\tjQuery._data( elem, \"_change_data\", val );\n\t\t}\n\n\t\tif ( data === undefined || val === data ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( data != null || val ) {\n\t\t\te.type = \"change\";\n\t\t\te.liveFired = undefined;\n\t\t\tjQuery.event.trigger( e, arguments[1], elem );\n\t\t}\n\t};\n\n\tjQuery.event.special.change = {\n\t\tfilters: {\n\t\t\tfocusout: testChange,\n\n\t\t\tbeforedeactivate: testChange,\n\n\t\t\tclick: function( e ) {\n\t\t\t\tvar elem = e.target, type = jQuery.nodeName( elem, \"input\" ) ? elem.type : \"\";\n\n\t\t\t\tif ( type === \"radio\" || type === \"checkbox\" || jQuery.nodeName( elem, \"select\" ) ) {\n\t\t\t\t\ttestChange.call( this, e );\n\t\t\t\t}\n\t\t\t},\n\n\t\t\t// Change has to be called before submit\n\t\t\t// Keydown will be called before keypress, which is used in submit-event delegation\n\t\t\tkeydown: function( e ) {\n\t\t\t\tvar elem = e.target, type = jQuery.nodeName( elem, \"input\" ) ? elem.type : \"\";\n\n\t\t\t\tif ( (e.keyCode === 13 && !jQuery.nodeName( elem, \"textarea\" ) ) ||\n\t\t\t\t\t(e.keyCode === 32 && (type === \"checkbox\" || type === \"radio\")) ||\n\t\t\t\t\ttype === \"select-multiple\" ) {\n\t\t\t\t\ttestChange.call( this, e );\n\t\t\t\t}\n\t\t\t},\n\n\t\t\t// Beforeactivate happens also before the previous element is blurred\n\t\t\t// with this event you can't trigger a change event, but you can store\n\t\t\t// information\n\t\t\tbeforeactivate: function( e ) {\n\t\t\t\tvar elem = e.target;\n\t\t\t\tjQuery._data( elem, \"_change_data\", getVal(elem) );\n\t\t\t}\n\t\t},\n\n\t\tsetup: function( data, namespaces ) {\n\t\t\tif ( this.type === \"file\" ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tfor ( var type in changeFilters ) {\n\t\t\t\tjQuery.event.add( this, type + \".specialChange\", changeFilters[type] );\n\t\t\t}\n\n\t\t\treturn rformElems.test( this.nodeName );\n\t\t},\n\n\t\tteardown: function( namespaces ) {\n\t\t\tjQuery.event.remove( this, \".specialChange\" );\n\n\t\t\treturn rformElems.test( this.nodeName );\n\t\t}\n\t};\n\n\tchangeFilters = jQuery.event.special.change.filters;\n\n\t// Handle when the input is .focus()'d\n\tchangeFilters.focus = changeFilters.beforeactivate;\n}\n\nfunction trigger( type, elem, args ) {\n\t// Piggyback on a donor event to simulate a different one.\n\t// Fake originalEvent to avoid donor's stopPropagation, but if the\n\t// simulated event prevents default then we do the same on the donor.\n\t// Don't pass args or remember liveFired; they apply to the donor event.\n\tvar event = jQuery.extend( {}, args[ 0 ] );\n\tevent.type = type;\n\tevent.originalEvent = {};\n\tevent.liveFired = undefined;\n\tjQuery.event.handle.call( elem, event );\n\tif ( event.isDefaultPrevented() ) {\n\t\targs[ 0 ].preventDefault();\n\t}\n}\n\n// Create \"bubbling\" focus and blur events\nif ( !jQuery.support.focusinBubbles ) {\n\tjQuery.each({ focus: \"focusin\", blur: \"focusout\" }, function( orig, fix ) {\n\n\t\t// Attach a single capturing handler while someone wants focusin/focusout\n\t\tvar attaches = 0;\n\n\t\tjQuery.event.special[ fix ] = {\n\t\t\tsetup: function() {\n\t\t\t\tif ( attaches++ === 0 ) {\n\t\t\t\t\tdocument.addEventListener( orig, handler, true );\n\t\t\t\t}\n\t\t\t},\n\t\t\tteardown: function() {\n\t\t\t\tif ( --attaches === 0 ) {\n\t\t\t\t\tdocument.removeEventListener( orig, handler, true );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tfunction handler( donor ) {\n\t\t\t// Donor event is always a native one; fix it and switch its type.\n\t\t\t// Let focusin/out handler cancel the donor focus/blur event.\n\t\t\tvar e = jQuery.event.fix( donor );\n\t\t\te.type = fix;\n\t\t\te.originalEvent = {};\n\t\t\tjQuery.event.trigger( e, null, e.target );\n\t\t\tif ( e.isDefaultPrevented() ) {\n\t\t\t\tdonor.preventDefault();\n\t\t\t}\n\t\t}\n\t});\n}\n\njQuery.each([\"bind\", \"one\"], function( i, name ) {\n\tjQuery.fn[ name ] = function( type, data, fn ) {\n\t\tvar handler;\n\n\t\t// Handle object literals\n\t\tif ( typeof type === \"object\" ) {\n\t\t\tfor ( var key in type ) {\n\t\t\t\tthis[ name ](key, data, type[key], fn);\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\n\t\tif ( arguments.length === 2 || data === false ) {\n\t\t\tfn = data;\n\t\t\tdata = undefined;\n\t\t}\n\n\t\tif ( name === \"one\" ) {\n\t\t\thandler = function( event ) {\n\t\t\t\tjQuery( this ).unbind( event, handler );\n\t\t\t\treturn fn.apply( this, arguments );\n\t\t\t};\n\t\t\thandler.guid = fn.guid || jQuery.guid++;\n\t\t} else {\n\t\t\thandler = fn;\n\t\t}\n\n\t\tif ( type === \"unload\" && name !== \"one\" ) {\n\t\t\tthis.one( type, data, fn );\n\n\t\t} else {\n\t\t\tfor ( var i = 0, l = this.length; i < l; i++ ) {\n\t\t\t\tjQuery.event.add( this[i], type, handler, data );\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t};\n});\n\njQuery.fn.extend({\n\tunbind: function( type, fn ) {\n\t\t// Handle object literals\n\t\tif ( typeof type === \"object\" && !type.preventDefault ) {\n\t\t\tfor ( var key in type ) {\n\t\t\t\tthis.unbind(key, type[key]);\n\t\t\t}\n\n\t\t} else {\n\t\t\tfor ( var i = 0, l = this.length; i < l; i++ ) {\n\t\t\t\tjQuery.event.remove( this[i], type, fn );\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tdelegate: function( selector, types, data, fn ) {\n\t\treturn this.live( types, data, fn, selector );\n\t},\n\n\tundelegate: function( selector, types, fn ) {\n\t\tif ( arguments.length === 0 ) {\n\t\t\treturn this.unbind( \"live\" );\n\n\t\t} else {\n\t\t\treturn this.die( types, null, fn, selector );\n\t\t}\n\t},\n\n\ttrigger: function( type, data ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.event.trigger( type, data, this );\n\t\t});\n\t},\n\n\ttriggerHandler: function( type, data ) {\n\t\tif ( this[0] ) {\n\t\t\treturn jQuery.event.trigger( type, data, this[0], true );\n\t\t}\n\t},\n\n\ttoggle: function( fn ) {\n\t\t// Save reference to arguments for access in closure\n\t\tvar args = arguments,\n\t\t\tguid = fn.guid || jQuery.guid++,\n\t\t\ti = 0,\n\t\t\ttoggler = function( event ) {\n\t\t\t\t// Figure out which function to execute\n\t\t\t\tvar lastToggle = ( jQuery.data( this, \"lastToggle\" + fn.guid ) || 0 ) % i;\n\t\t\t\tjQuery.data( this, \"lastToggle\" + fn.guid, lastToggle + 1 );\n\n\t\t\t\t// Make sure that clicks stop\n\t\t\t\tevent.preventDefault();\n\n\t\t\t\t// and execute the function\n\t\t\t\treturn args[ lastToggle ].apply( this, arguments ) || false;\n\t\t\t};\n\n\t\t// link all the functions, so any of them can unbind this click handler\n\t\ttoggler.guid = guid;\n\t\twhile ( i < args.length ) {\n\t\t\targs[ i++ ].guid = guid;\n\t\t}\n\n\t\treturn this.click( toggler );\n\t},\n\n\thover: function( fnOver, fnOut ) {\n\t\treturn this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );\n\t}\n});\n\nvar liveMap = {\n\tfocus: \"focusin\",\n\tblur: \"focusout\",\n\tmouseenter: \"mouseover\",\n\tmouseleave: \"mouseout\"\n};\n\njQuery.each([\"live\", \"die\"], function( i, name ) {\n\tjQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {\n\t\tvar type, i = 0, match, namespaces, preType,\n\t\t\tselector = origSelector || this.selector,\n\t\t\tcontext = origSelector ? this : jQuery( this.context );\n\n\t\tif ( typeof types === \"object\" && !types.preventDefault ) {\n\t\t\tfor ( var key in types ) {\n\t\t\t\tcontext[ name ]( key, data, types[key], selector );\n\t\t\t}\n\n\t\t\treturn this;\n\t\t}\n\n\t\tif ( name === \"die\" && !types &&\n\t\t\t\t\torigSelector && origSelector.charAt(0) === \".\" ) {\n\n\t\t\tcontext.unbind( origSelector );\n\n\t\t\treturn this;\n\t\t}\n\n\t\tif ( data === false || jQuery.isFunction( data ) ) {\n\t\t\tfn = data || returnFalse;\n\t\t\tdata = undefined;\n\t\t}\n\n\t\ttypes = (types || \"\").split(\" \");\n\n\t\twhile ( (type = types[ i++ ]) != null ) {\n\t\t\tmatch = rnamespaces.exec( type );\n\t\t\tnamespaces = \"\";\n\n\t\t\tif ( match )  {\n\t\t\t\tnamespaces = match[0];\n\t\t\t\ttype = type.replace( rnamespaces, \"\" );\n\t\t\t}\n\n\t\t\tif ( type === \"hover\" ) {\n\t\t\t\ttypes.push( \"mouseenter\" + namespaces, \"mouseleave\" + namespaces );\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tpreType = type;\n\n\t\t\tif ( liveMap[ type ] ) {\n\t\t\t\ttypes.push( liveMap[ type ] + namespaces );\n\t\t\t\ttype = type + namespaces;\n\n\t\t\t} else {\n\t\t\t\ttype = (liveMap[ type ] || type) + namespaces;\n\t\t\t}\n\n\t\t\tif ( name === \"live\" ) {\n\t\t\t\t// bind live handler\n\t\t\t\tfor ( var j = 0, l = context.length; j < l; j++ ) {\n\t\t\t\t\tjQuery.event.add( context[j], \"live.\" + liveConvert( type, selector ),\n\t\t\t\t\t\t{ data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );\n\t\t\t\t}\n\n\t\t\t} else {\n\t\t\t\t// unbind live handler\n\t\t\t\tcontext.unbind( \"live.\" + liveConvert( type, selector ), fn );\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t};\n});\n\nfunction liveHandler( event ) {\n\tvar stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret,\n\t\telems = [],\n\t\tselectors = [],\n\t\tevents = jQuery._data( this, \"events\" );\n\n\t// Make sure we avoid non-left-click bubbling in Firefox (#3861) and disabled elements in IE (#6911)\n\tif ( event.liveFired === this || !events || !events.live || event.target.disabled || event.button && event.type === \"click\" ) {\n\t\treturn;\n\t}\n\n\tif ( event.namespace ) {\n\t\tnamespace = new RegExp(\"(^|\\\\.)\" + event.namespace.split(\".\").join(\"\\\\.(?:.*\\\\.)?\") + \"(\\\\.|$)\");\n\t}\n\n\tevent.liveFired = this;\n\n\tvar live = events.live.slice(0);\n\n\tfor ( j = 0; j < live.length; j++ ) {\n\t\thandleObj = live[j];\n\n\t\tif ( handleObj.origType.replace( rnamespaces, \"\" ) === event.type ) {\n\t\t\tselectors.push( handleObj.selector );\n\n\t\t} else {\n\t\t\tlive.splice( j--, 1 );\n\t\t}\n\t}\n\n\tmatch = jQuery( event.target ).closest( selectors, event.currentTarget );\n\n\tfor ( i = 0, l = match.length; i < l; i++ ) {\n\t\tclose = match[i];\n\n\t\tfor ( j = 0; j < live.length; j++ ) {\n\t\t\thandleObj = live[j];\n\n\t\t\tif ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) && !close.elem.disabled ) {\n\t\t\t\telem = close.elem;\n\t\t\t\trelated = null;\n\n\t\t\t\t// Those two events require additional checking\n\t\t\t\tif ( handleObj.preType === \"mouseenter\" || handleObj.preType === \"mouseleave\" ) {\n\t\t\t\t\tevent.type = handleObj.preType;\n\t\t\t\t\trelated = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];\n\n\t\t\t\t\t// Make sure not to accidentally match a child element with the same selector\n\t\t\t\t\tif ( related && jQuery.contains( elem, related ) ) {\n\t\t\t\t\t\trelated = elem;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( !related || related !== elem ) {\n\t\t\t\t\telems.push({ elem: elem, handleObj: handleObj, level: close.level });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tfor ( i = 0, l = elems.length; i < l; i++ ) {\n\t\tmatch = elems[i];\n\n\t\tif ( maxLevel && match.level > maxLevel ) {\n\t\t\tbreak;\n\t\t}\n\n\t\tevent.currentTarget = match.elem;\n\t\tevent.data = match.handleObj.data;\n\t\tevent.handleObj = match.handleObj;\n\n\t\tret = match.handleObj.origHandler.apply( match.elem, arguments );\n\n\t\tif ( ret === false || event.isPropagationStopped() ) {\n\t\t\tmaxLevel = match.level;\n\n\t\t\tif ( ret === false ) {\n\t\t\t\tstop = false;\n\t\t\t}\n\t\t\tif ( event.isImmediatePropagationStopped() ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn stop;\n}\n\nfunction liveConvert( type, selector ) {\n\treturn (type && type !== \"*\" ? type + \".\" : \"\") + selector.replace(rperiod, \"`\").replace(rspaces, \"&\");\n}\n\njQuery.each( (\"blur focus focusin focusout load resize scroll unload click dblclick \" +\n\t\"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave \" +\n\t\"change select submit keydown keypress keyup error\").split(\" \"), function( i, name ) {\n\n\t// Handle event binding\n\tjQuery.fn[ name ] = function( data, fn ) {\n\t\tif ( fn == null ) {\n\t\t\tfn = data;\n\t\t\tdata = null;\n\t\t}\n\n\t\treturn arguments.length > 0 ?\n\t\t\tthis.bind( name, data, fn ) :\n\t\t\tthis.trigger( name );\n\t};\n\n\tif ( jQuery.attrFn ) {\n\t\tjQuery.attrFn[ name ] = true;\n\t}\n});\n\n\n\n/*!\n * Sizzle CSS Selector Engine\n *  Copyright 2011, The Dojo Foundation\n *  Released under the MIT, BSD, and GPL Licenses.\n *  More information: http://sizzlejs.com/\n */\n(function(){\n\nvar chunker = /((?:\\((?:\\([^()]+\\)|[^()]+)+\\)|\\[(?:\\[[^\\[\\]]*\\]|['\"][^'\"]*['\"]|[^\\[\\]'\"]+)+\\]|\\\\.|[^ >+~,(\\[\\\\]+)+|[>+~])(\\s*,\\s*)?((?:.|\\r|\\n)*)/g,\n\tdone = 0,\n\ttoString = Object.prototype.toString,\n\thasDuplicate = false,\n\tbaseHasDuplicate = true,\n\trBackslash = /\\\\/g,\n\trNonWord = /\\W/;\n\n// Here we check if the JavaScript engine is using some sort of\n// optimization where it does not always call our comparision\n// function. If that is the case, discard the hasDuplicate value.\n//   Thus far that includes Google Chrome.\n[0, 0].sort(function() {\n\tbaseHasDuplicate = false;\n\treturn 0;\n});\n\nvar Sizzle = function( selector, context, results, seed ) {\n\tresults = results || [];\n\tcontext = context || document;\n\n\tvar origContext = context;\n\n\tif ( context.nodeType !== 1 && context.nodeType !== 9 ) {\n\t\treturn [];\n\t}\n\t\n\tif ( !selector || typeof selector !== \"string\" ) {\n\t\treturn results;\n\t}\n\n\tvar m, set, checkSet, extra, ret, cur, pop, i,\n\t\tprune = true,\n\t\tcontextXML = Sizzle.isXML( context ),\n\t\tparts = [],\n\t\tsoFar = selector;\n\t\n\t// Reset the position of the chunker regexp (start from head)\n\tdo {\n\t\tchunker.exec( \"\" );\n\t\tm = chunker.exec( soFar );\n\n\t\tif ( m ) {\n\t\t\tsoFar = m[3];\n\t\t\n\t\t\tparts.push( m[1] );\n\t\t\n\t\t\tif ( m[2] ) {\n\t\t\t\textra = m[3];\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t} while ( m );\n\n\tif ( parts.length > 1 && origPOS.exec( selector ) ) {\n\n\t\tif ( parts.length === 2 && Expr.relative[ parts[0] ] ) {\n\t\t\tset = posProcess( parts[0] + parts[1], context );\n\n\t\t} else {\n\t\t\tset = Expr.relative[ parts[0] ] ?\n\t\t\t\t[ context ] :\n\t\t\t\tSizzle( parts.shift(), context );\n\n\t\t\twhile ( parts.length ) {\n\t\t\t\tselector = parts.shift();\n\n\t\t\t\tif ( Expr.relative[ selector ] ) {\n\t\t\t\t\tselector += parts.shift();\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tset = posProcess( selector, set );\n\t\t\t}\n\t\t}\n\n\t} else {\n\t\t// Take a shortcut and set the context if the root selector is an ID\n\t\t// (but not if it'll be faster if the inner selector is an ID)\n\t\tif ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&\n\t\t\t\tExpr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {\n\n\t\t\tret = Sizzle.find( parts.shift(), context, contextXML );\n\t\t\tcontext = ret.expr ?\n\t\t\t\tSizzle.filter( ret.expr, ret.set )[0] :\n\t\t\t\tret.set[0];\n\t\t}\n\n\t\tif ( context ) {\n\t\t\tret = seed ?\n\t\t\t\t{ expr: parts.pop(), set: makeArray(seed) } :\n\t\t\t\tSizzle.find( parts.pop(), parts.length === 1 && (parts[0] === \"~\" || parts[0] === \"+\") && context.parentNode ? context.parentNode : context, contextXML );\n\n\t\t\tset = ret.expr ?\n\t\t\t\tSizzle.filter( ret.expr, ret.set ) :\n\t\t\t\tret.set;\n\n\t\t\tif ( parts.length > 0 ) {\n\t\t\t\tcheckSet = makeArray( set );\n\n\t\t\t} else {\n\t\t\t\tprune = false;\n\t\t\t}\n\n\t\t\twhile ( parts.length ) {\n\t\t\t\tcur = parts.pop();\n\t\t\t\tpop = cur;\n\n\t\t\t\tif ( !Expr.relative[ cur ] ) {\n\t\t\t\t\tcur = \"\";\n\t\t\t\t} else {\n\t\t\t\t\tpop = parts.pop();\n\t\t\t\t}\n\n\t\t\t\tif ( pop == null ) {\n\t\t\t\t\tpop = context;\n\t\t\t\t}\n\n\t\t\t\tExpr.relative[ cur ]( checkSet, pop, contextXML );\n\t\t\t}\n\n\t\t} else {\n\t\t\tcheckSet = parts = [];\n\t\t}\n\t}\n\n\tif ( !checkSet ) {\n\t\tcheckSet = set;\n\t}\n\n\tif ( !checkSet ) {\n\t\tSizzle.error( cur || selector );\n\t}\n\n\tif ( toString.call(checkSet) === \"[object Array]\" ) {\n\t\tif ( !prune ) {\n\t\t\tresults.push.apply( results, checkSet );\n\n\t\t} else if ( context && context.nodeType === 1 ) {\n\t\t\tfor ( i = 0; checkSet[i] != null; i++ ) {\n\t\t\t\tif ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {\n\t\t\t\t\tresults.push( set[i] );\n\t\t\t\t}\n\t\t\t}\n\n\t\t} else {\n\t\t\tfor ( i = 0; checkSet[i] != null; i++ ) {\n\t\t\t\tif ( checkSet[i] && checkSet[i].nodeType === 1 ) {\n\t\t\t\t\tresults.push( set[i] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t} else {\n\t\tmakeArray( checkSet, results );\n\t}\n\n\tif ( extra ) {\n\t\tSizzle( extra, origContext, results, seed );\n\t\tSizzle.uniqueSort( results );\n\t}\n\n\treturn results;\n};\n\nSizzle.uniqueSort = function( results ) {\n\tif ( sortOrder ) {\n\t\thasDuplicate = baseHasDuplicate;\n\t\tresults.sort( sortOrder );\n\n\t\tif ( hasDuplicate ) {\n\t\t\tfor ( var i = 1; i < results.length; i++ ) {\n\t\t\t\tif ( results[i] === results[ i - 1 ] ) {\n\t\t\t\t\tresults.splice( i--, 1 );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn results;\n};\n\nSizzle.matches = function( expr, set ) {\n\treturn Sizzle( expr, null, null, set );\n};\n\nSizzle.matchesSelector = function( node, expr ) {\n\treturn Sizzle( expr, null, null, [node] ).length > 0;\n};\n\nSizzle.find = function( expr, context, isXML ) {\n\tvar set;\n\n\tif ( !expr ) {\n\t\treturn [];\n\t}\n\n\tfor ( var i = 0, l = Expr.order.length; i < l; i++ ) {\n\t\tvar match,\n\t\t\ttype = Expr.order[i];\n\t\t\n\t\tif ( (match = Expr.leftMatch[ type ].exec( expr )) ) {\n\t\t\tvar left = match[1];\n\t\t\tmatch.splice( 1, 1 );\n\n\t\t\tif ( left.substr( left.length - 1 ) !== \"\\\\\" ) {\n\t\t\t\tmatch[1] = (match[1] || \"\").replace( rBackslash, \"\" );\n\t\t\t\tset = Expr.find[ type ]( match, context, isXML );\n\n\t\t\t\tif ( set != null ) {\n\t\t\t\t\texpr = expr.replace( Expr.match[ type ], \"\" );\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( !set ) {\n\t\tset = typeof context.getElementsByTagName !== \"undefined\" ?\n\t\t\tcontext.getElementsByTagName( \"*\" ) :\n\t\t\t[];\n\t}\n\n\treturn { set: set, expr: expr };\n};\n\nSizzle.filter = function( expr, set, inplace, not ) {\n\tvar match, anyFound,\n\t\told = expr,\n\t\tresult = [],\n\t\tcurLoop = set,\n\t\tisXMLFilter = set && set[0] && Sizzle.isXML( set[0] );\n\n\twhile ( expr && set.length ) {\n\t\tfor ( var type in Expr.filter ) {\n\t\t\tif ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {\n\t\t\t\tvar found, item,\n\t\t\t\t\tfilter = Expr.filter[ type ],\n\t\t\t\t\tleft = match[1];\n\n\t\t\t\tanyFound = false;\n\n\t\t\t\tmatch.splice(1,1);\n\n\t\t\t\tif ( left.substr( left.length - 1 ) === \"\\\\\" ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif ( curLoop === result ) {\n\t\t\t\t\tresult = [];\n\t\t\t\t}\n\n\t\t\t\tif ( Expr.preFilter[ type ] ) {\n\t\t\t\t\tmatch = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );\n\n\t\t\t\t\tif ( !match ) {\n\t\t\t\t\t\tanyFound = found = true;\n\n\t\t\t\t\t} else if ( match === true ) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( match ) {\n\t\t\t\t\tfor ( var i = 0; (item = curLoop[i]) != null; i++ ) {\n\t\t\t\t\t\tif ( item ) {\n\t\t\t\t\t\t\tfound = filter( item, match, i, curLoop );\n\t\t\t\t\t\t\tvar pass = not ^ !!found;\n\n\t\t\t\t\t\t\tif ( inplace && found != null ) {\n\t\t\t\t\t\t\t\tif ( pass ) {\n\t\t\t\t\t\t\t\t\tanyFound = true;\n\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tcurLoop[i] = false;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else if ( pass ) {\n\t\t\t\t\t\t\t\tresult.push( item );\n\t\t\t\t\t\t\t\tanyFound = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( found !== undefined ) {\n\t\t\t\t\tif ( !inplace ) {\n\t\t\t\t\t\tcurLoop = result;\n\t\t\t\t\t}\n\n\t\t\t\t\texpr = expr.replace( Expr.match[ type ], \"\" );\n\n\t\t\t\t\tif ( !anyFound ) {\n\t\t\t\t\t\treturn [];\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Improper expression\n\t\tif ( expr === old ) {\n\t\t\tif ( anyFound == null ) {\n\t\t\t\tSizzle.error( expr );\n\n\t\t\t} else {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\told = expr;\n\t}\n\n\treturn curLoop;\n};\n\nSizzle.error = function( msg ) {\n\tthrow \"Syntax error, unrecognized expression: \" + msg;\n};\n\nvar Expr = Sizzle.selectors = {\n\torder: [ \"ID\", \"NAME\", \"TAG\" ],\n\n\tmatch: {\n\t\tID: /#((?:[\\w\\u00c0-\\uFFFF\\-]|\\\\.)+)/,\n\t\tCLASS: /\\.((?:[\\w\\u00c0-\\uFFFF\\-]|\\\\.)+)/,\n\t\tNAME: /\\[name=['\"]*((?:[\\w\\u00c0-\\uFFFF\\-]|\\\\.)+)['\"]*\\]/,\n\t\tATTR: /\\[\\s*((?:[\\w\\u00c0-\\uFFFF\\-]|\\\\.)+)\\s*(?:(\\S?=)\\s*(?:(['\"])(.*?)\\3|(#?(?:[\\w\\u00c0-\\uFFFF\\-]|\\\\.)*)|)|)\\s*\\]/,\n\t\tTAG: /^((?:[\\w\\u00c0-\\uFFFF\\*\\-]|\\\\.)+)/,\n\t\tCHILD: /:(only|nth|last|first)-child(?:\\(\\s*(even|odd|(?:[+\\-]?\\d+|(?:[+\\-]?\\d*)?n\\s*(?:[+\\-]\\s*\\d+)?))\\s*\\))?/,\n\t\tPOS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\\((\\d*)\\))?(?=[^\\-]|$)/,\n\t\tPSEUDO: /:((?:[\\w\\u00c0-\\uFFFF\\-]|\\\\.)+)(?:\\((['\"]?)((?:\\([^\\)]+\\)|[^\\(\\)]*)+)\\2\\))?/\n\t},\n\n\tleftMatch: {},\n\n\tattrMap: {\n\t\t\"class\": \"className\",\n\t\t\"for\": \"htmlFor\"\n\t},\n\n\tattrHandle: {\n\t\thref: function( elem ) {\n\t\t\treturn elem.getAttribute( \"href\" );\n\t\t},\n\t\ttype: function( elem ) {\n\t\t\treturn elem.getAttribute( \"type\" );\n\t\t}\n\t},\n\n\trelative: {\n\t\t\"+\": function(checkSet, part){\n\t\t\tvar isPartStr = typeof part === \"string\",\n\t\t\t\tisTag = isPartStr && !rNonWord.test( part ),\n\t\t\t\tisPartStrNotTag = isPartStr && !isTag;\n\n\t\t\tif ( isTag ) {\n\t\t\t\tpart = part.toLowerCase();\n\t\t\t}\n\n\t\t\tfor ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {\n\t\t\t\tif ( (elem = checkSet[i]) ) {\n\t\t\t\t\twhile ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}\n\n\t\t\t\t\tcheckSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?\n\t\t\t\t\t\telem || false :\n\t\t\t\t\t\telem === part;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( isPartStrNotTag ) {\n\t\t\t\tSizzle.filter( part, checkSet, true );\n\t\t\t}\n\t\t},\n\n\t\t\">\": function( checkSet, part ) {\n\t\t\tvar elem,\n\t\t\t\tisPartStr = typeof part === \"string\",\n\t\t\t\ti = 0,\n\t\t\t\tl = checkSet.length;\n\n\t\t\tif ( isPartStr && !rNonWord.test( part ) ) {\n\t\t\t\tpart = part.toLowerCase();\n\n\t\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\t\telem = checkSet[i];\n\n\t\t\t\t\tif ( elem ) {\n\t\t\t\t\t\tvar parent = elem.parentNode;\n\t\t\t\t\t\tcheckSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t} else {\n\t\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\t\telem = checkSet[i];\n\n\t\t\t\t\tif ( elem ) {\n\t\t\t\t\t\tcheckSet[i] = isPartStr ?\n\t\t\t\t\t\t\telem.parentNode :\n\t\t\t\t\t\t\telem.parentNode === part;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( isPartStr ) {\n\t\t\t\t\tSizzle.filter( part, checkSet, true );\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t\"\": function(checkSet, part, isXML){\n\t\t\tvar nodeCheck,\n\t\t\t\tdoneName = done++,\n\t\t\t\tcheckFn = dirCheck;\n\n\t\t\tif ( typeof part === \"string\" && !rNonWord.test( part ) ) {\n\t\t\t\tpart = part.toLowerCase();\n\t\t\t\tnodeCheck = part;\n\t\t\t\tcheckFn = dirNodeCheck;\n\t\t\t}\n\n\t\t\tcheckFn( \"parentNode\", part, doneName, checkSet, nodeCheck, isXML );\n\t\t},\n\n\t\t\"~\": function( checkSet, part, isXML ) {\n\t\t\tvar nodeCheck,\n\t\t\t\tdoneName = done++,\n\t\t\t\tcheckFn = dirCheck;\n\n\t\t\tif ( typeof part === \"string\" && !rNonWord.test( part ) ) {\n\t\t\t\tpart = part.toLowerCase();\n\t\t\t\tnodeCheck = part;\n\t\t\t\tcheckFn = dirNodeCheck;\n\t\t\t}\n\n\t\t\tcheckFn( \"previousSibling\", part, doneName, checkSet, nodeCheck, isXML );\n\t\t}\n\t},\n\n\tfind: {\n\t\tID: function( match, context, isXML ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && !isXML ) {\n\t\t\t\tvar m = context.getElementById(match[1]);\n\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t// nodes that are no longer in the document #6963\n\t\t\t\treturn m && m.parentNode ? [m] : [];\n\t\t\t}\n\t\t},\n\n\t\tNAME: function( match, context ) {\n\t\t\tif ( typeof context.getElementsByName !== \"undefined\" ) {\n\t\t\t\tvar ret = [],\n\t\t\t\t\tresults = context.getElementsByName( match[1] );\n\n\t\t\t\tfor ( var i = 0, l = results.length; i < l; i++ ) {\n\t\t\t\t\tif ( results[i].getAttribute(\"name\") === match[1] ) {\n\t\t\t\t\t\tret.push( results[i] );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn ret.length === 0 ? null : ret;\n\t\t\t}\n\t\t},\n\n\t\tTAG: function( match, context ) {\n\t\t\tif ( typeof context.getElementsByTagName !== \"undefined\" ) {\n\t\t\t\treturn context.getElementsByTagName( match[1] );\n\t\t\t}\n\t\t}\n\t},\n\tpreFilter: {\n\t\tCLASS: function( match, curLoop, inplace, result, not, isXML ) {\n\t\t\tmatch = \" \" + match[1].replace( rBackslash, \"\" ) + \" \";\n\n\t\t\tif ( isXML ) {\n\t\t\t\treturn match;\n\t\t\t}\n\n\t\t\tfor ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {\n\t\t\t\tif ( elem ) {\n\t\t\t\t\tif ( not ^ (elem.className && (\" \" + elem.className + \" \").replace(/[\\t\\n\\r]/g, \" \").indexOf(match) >= 0) ) {\n\t\t\t\t\t\tif ( !inplace ) {\n\t\t\t\t\t\t\tresult.push( elem );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else if ( inplace ) {\n\t\t\t\t\t\tcurLoop[i] = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn false;\n\t\t},\n\n\t\tID: function( match ) {\n\t\t\treturn match[1].replace( rBackslash, \"\" );\n\t\t},\n\n\t\tTAG: function( match, curLoop ) {\n\t\t\treturn match[1].replace( rBackslash, \"\" ).toLowerCase();\n\t\t},\n\n\t\tCHILD: function( match ) {\n\t\t\tif ( match[1] === \"nth\" ) {\n\t\t\t\tif ( !match[2] ) {\n\t\t\t\t\tSizzle.error( match[0] );\n\t\t\t\t}\n\n\t\t\t\tmatch[2] = match[2].replace(/^\\+|\\s*/g, '');\n\n\t\t\t\t// parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'\n\t\t\t\tvar test = /(-?)(\\d*)(?:n([+\\-]?\\d*))?/.exec(\n\t\t\t\t\tmatch[2] === \"even\" && \"2n\" || match[2] === \"odd\" && \"2n+1\" ||\n\t\t\t\t\t!/\\D/.test( match[2] ) && \"0n+\" + match[2] || match[2]);\n\n\t\t\t\t// calculate the numbers (first)n+(last) including if they are negative\n\t\t\t\tmatch[2] = (test[1] + (test[2] || 1)) - 0;\n\t\t\t\tmatch[3] = test[3] - 0;\n\t\t\t}\n\t\t\telse if ( match[2] ) {\n\t\t\t\tSizzle.error( match[0] );\n\t\t\t}\n\n\t\t\t// TODO: Move to normal caching system\n\t\t\tmatch[0] = done++;\n\n\t\t\treturn match;\n\t\t},\n\n\t\tATTR: function( match, curLoop, inplace, result, not, isXML ) {\n\t\t\tvar name = match[1] = match[1].replace( rBackslash, \"\" );\n\t\t\t\n\t\t\tif ( !isXML && Expr.attrMap[name] ) {\n\t\t\t\tmatch[1] = Expr.attrMap[name];\n\t\t\t}\n\n\t\t\t// Handle if an un-quoted value was used\n\t\t\tmatch[4] = ( match[4] || match[5] || \"\" ).replace( rBackslash, \"\" );\n\n\t\t\tif ( match[2] === \"~=\" ) {\n\t\t\t\tmatch[4] = \" \" + match[4] + \" \";\n\t\t\t}\n\n\t\t\treturn match;\n\t\t},\n\n\t\tPSEUDO: function( match, curLoop, inplace, result, not ) {\n\t\t\tif ( match[1] === \"not\" ) {\n\t\t\t\t// If we're dealing with a complex expression, or a simple one\n\t\t\t\tif ( ( chunker.exec(match[3]) || \"\" ).length > 1 || /^\\w/.test(match[3]) ) {\n\t\t\t\t\tmatch[3] = Sizzle(match[3], null, null, curLoop);\n\n\t\t\t\t} else {\n\t\t\t\t\tvar ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);\n\n\t\t\t\t\tif ( !inplace ) {\n\t\t\t\t\t\tresult.push.apply( result, ret );\n\t\t\t\t\t}\n\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t} else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\t\n\t\t\treturn match;\n\t\t},\n\n\t\tPOS: function( match ) {\n\t\t\tmatch.unshift( true );\n\n\t\t\treturn match;\n\t\t}\n\t},\n\t\n\tfilters: {\n\t\tenabled: function( elem ) {\n\t\t\treturn elem.disabled === false && elem.type !== \"hidden\";\n\t\t},\n\n\t\tdisabled: function( elem ) {\n\t\t\treturn elem.disabled === true;\n\t\t},\n\n\t\tchecked: function( elem ) {\n\t\t\treturn elem.checked === true;\n\t\t},\n\t\t\n\t\tselected: function( elem ) {\n\t\t\t// Accessing this property makes selected-by-default\n\t\t\t// options in Safari work properly\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\telem.parentNode.selectedIndex;\n\t\t\t}\n\t\t\t\n\t\t\treturn elem.selected === true;\n\t\t},\n\n\t\tparent: function( elem ) {\n\t\t\treturn !!elem.firstChild;\n\t\t},\n\n\t\tempty: function( elem ) {\n\t\t\treturn !elem.firstChild;\n\t\t},\n\n\t\thas: function( elem, i, match ) {\n\t\t\treturn !!Sizzle( match[3], elem ).length;\n\t\t},\n\n\t\theader: function( elem ) {\n\t\t\treturn (/h\\d/i).test( elem.nodeName );\n\t\t},\n\n\t\ttext: function( elem ) {\n\t\t\tvar attr = elem.getAttribute( \"type\" ), type = elem.type;\n\t\t\t// IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) \n\t\t\t// use getAttribute instead to test this case\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" && \"text\" === type && ( attr === type || attr === null );\n\t\t},\n\n\t\tradio: function( elem ) {\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" && \"radio\" === elem.type;\n\t\t},\n\n\t\tcheckbox: function( elem ) {\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" && \"checkbox\" === elem.type;\n\t\t},\n\n\t\tfile: function( elem ) {\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" && \"file\" === elem.type;\n\t\t},\n\n\t\tpassword: function( elem ) {\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" && \"password\" === elem.type;\n\t\t},\n\n\t\tsubmit: function( elem ) {\n\t\t\tvar name = elem.nodeName.toLowerCase();\n\t\t\treturn (name === \"input\" || name === \"button\") && \"submit\" === elem.type;\n\t\t},\n\n\t\timage: function( elem ) {\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" && \"image\" === elem.type;\n\t\t},\n\n\t\treset: function( elem ) {\n\t\t\tvar name = elem.nodeName.toLowerCase();\n\t\t\treturn (name === \"input\" || name === \"button\") && \"reset\" === elem.type;\n\t\t},\n\n\t\tbutton: function( elem ) {\n\t\t\tvar name = elem.nodeName.toLowerCase();\n\t\t\treturn name === \"input\" && \"button\" === elem.type || name === \"button\";\n\t\t},\n\n\t\tinput: function( elem ) {\n\t\t\treturn (/input|select|textarea|button/i).test( elem.nodeName );\n\t\t},\n\n\t\tfocus: function( elem ) {\n\t\t\treturn elem === elem.ownerDocument.activeElement;\n\t\t}\n\t},\n\tsetFilters: {\n\t\tfirst: function( elem, i ) {\n\t\t\treturn i === 0;\n\t\t},\n\n\t\tlast: function( elem, i, match, array ) {\n\t\t\treturn i === array.length - 1;\n\t\t},\n\n\t\teven: function( elem, i ) {\n\t\t\treturn i % 2 === 0;\n\t\t},\n\n\t\todd: function( elem, i ) {\n\t\t\treturn i % 2 === 1;\n\t\t},\n\n\t\tlt: function( elem, i, match ) {\n\t\t\treturn i < match[3] - 0;\n\t\t},\n\n\t\tgt: function( elem, i, match ) {\n\t\t\treturn i > match[3] - 0;\n\t\t},\n\n\t\tnth: function( elem, i, match ) {\n\t\t\treturn match[3] - 0 === i;\n\t\t},\n\n\t\teq: function( elem, i, match ) {\n\t\t\treturn match[3] - 0 === i;\n\t\t}\n\t},\n\tfilter: {\n\t\tPSEUDO: function( elem, match, i, array ) {\n\t\t\tvar name = match[1],\n\t\t\t\tfilter = Expr.filters[ name ];\n\n\t\t\tif ( filter ) {\n\t\t\t\treturn filter( elem, i, match, array );\n\n\t\t\t} else if ( name === \"contains\" ) {\n\t\t\t\treturn (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || \"\").indexOf(match[3]) >= 0;\n\n\t\t\t} else if ( name === \"not\" ) {\n\t\t\t\tvar not = match[3];\n\n\t\t\t\tfor ( var j = 0, l = not.length; j < l; j++ ) {\n\t\t\t\t\tif ( not[j] === elem ) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\n\t\t\t} else {\n\t\t\t\tSizzle.error( name );\n\t\t\t}\n\t\t},\n\n\t\tCHILD: function( elem, match ) {\n\t\t\tvar type = match[1],\n\t\t\t\tnode = elem;\n\n\t\t\tswitch ( type ) {\n\t\t\t\tcase \"only\":\n\t\t\t\tcase \"first\":\n\t\t\t\t\twhile ( (node = node.previousSibling) )\t {\n\t\t\t\t\t\tif ( node.nodeType === 1 ) { \n\t\t\t\t\t\t\treturn false; \n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( type === \"first\" ) { \n\t\t\t\t\t\treturn true; \n\t\t\t\t\t}\n\n\t\t\t\t\tnode = elem;\n\n\t\t\t\tcase \"last\":\n\t\t\t\t\twhile ( (node = node.nextSibling) )\t {\n\t\t\t\t\t\tif ( node.nodeType === 1 ) { \n\t\t\t\t\t\t\treturn false; \n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn true;\n\n\t\t\t\tcase \"nth\":\n\t\t\t\t\tvar first = match[2],\n\t\t\t\t\t\tlast = match[3];\n\n\t\t\t\t\tif ( first === 1 && last === 0 ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\tvar doneName = match[0],\n\t\t\t\t\t\tparent = elem.parentNode;\n\t\n\t\t\t\t\tif ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {\n\t\t\t\t\t\tvar count = 0;\n\t\t\t\t\t\t\n\t\t\t\t\t\tfor ( node = parent.firstChild; node; node = node.nextSibling ) {\n\t\t\t\t\t\t\tif ( node.nodeType === 1 ) {\n\t\t\t\t\t\t\t\tnode.nodeIndex = ++count;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} \n\n\t\t\t\t\t\tparent.sizcache = doneName;\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\tvar diff = elem.nodeIndex - last;\n\n\t\t\t\t\tif ( first === 0 ) {\n\t\t\t\t\t\treturn diff === 0;\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn ( diff % first === 0 && diff / first >= 0 );\n\t\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\tID: function( elem, match ) {\n\t\t\treturn elem.nodeType === 1 && elem.getAttribute(\"id\") === match;\n\t\t},\n\n\t\tTAG: function( elem, match ) {\n\t\t\treturn (match === \"*\" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;\n\t\t},\n\t\t\n\t\tCLASS: function( elem, match ) {\n\t\t\treturn (\" \" + (elem.className || elem.getAttribute(\"class\")) + \" \")\n\t\t\t\t.indexOf( match ) > -1;\n\t\t},\n\n\t\tATTR: function( elem, match ) {\n\t\t\tvar name = match[1],\n\t\t\t\tresult = Expr.attrHandle[ name ] ?\n\t\t\t\t\tExpr.attrHandle[ name ]( elem ) :\n\t\t\t\t\telem[ name ] != null ?\n\t\t\t\t\t\telem[ name ] :\n\t\t\t\t\t\telem.getAttribute( name ),\n\t\t\t\tvalue = result + \"\",\n\t\t\t\ttype = match[2],\n\t\t\t\tcheck = match[4];\n\n\t\t\treturn result == null ?\n\t\t\t\ttype === \"!=\" :\n\t\t\t\ttype === \"=\" ?\n\t\t\t\tvalue === check :\n\t\t\t\ttype === \"*=\" ?\n\t\t\t\tvalue.indexOf(check) >= 0 :\n\t\t\t\ttype === \"~=\" ?\n\t\t\t\t(\" \" + value + \" \").indexOf(check) >= 0 :\n\t\t\t\t!check ?\n\t\t\t\tvalue && result !== false :\n\t\t\t\ttype === \"!=\" ?\n\t\t\t\tvalue !== check :\n\t\t\t\ttype === \"^=\" ?\n\t\t\t\tvalue.indexOf(check) === 0 :\n\t\t\t\ttype === \"$=\" ?\n\t\t\t\tvalue.substr(value.length - check.length) === check :\n\t\t\t\ttype === \"|=\" ?\n\t\t\t\tvalue === check || value.substr(0, check.length + 1) === check + \"-\" :\n\t\t\t\tfalse;\n\t\t},\n\n\t\tPOS: function( elem, match, i, array ) {\n\t\t\tvar name = match[2],\n\t\t\t\tfilter = Expr.setFilters[ name ];\n\n\t\t\tif ( filter ) {\n\t\t\t\treturn filter( elem, i, match, array );\n\t\t\t}\n\t\t}\n\t}\n};\n\nvar origPOS = Expr.match.POS,\n\tfescape = function(all, num){\n\t\treturn \"\\\\\" + (num - 0 + 1);\n\t};\n\nfor ( var type in Expr.match ) {\n\tExpr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\\[]*\\])(?![^\\(]*\\))/.source) );\n\tExpr.leftMatch[ type ] = new RegExp( /(^(?:.|\\r|\\n)*?)/.source + Expr.match[ type ].source.replace(/\\\\(\\d+)/g, fescape) );\n}\n\nvar makeArray = function( array, results ) {\n\tarray = Array.prototype.slice.call( array, 0 );\n\n\tif ( results ) {\n\t\tresults.push.apply( results, array );\n\t\treturn results;\n\t}\n\t\n\treturn array;\n};\n\n// Perform a simple check to determine if the browser is capable of\n// converting a NodeList to an array using builtin methods.\n// Also verifies that the returned array holds DOM nodes\n// (which is not the case in the Blackberry browser)\ntry {\n\tArray.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;\n\n// Provide a fallback method if it does not work\n} catch( e ) {\n\tmakeArray = function( array, results ) {\n\t\tvar i = 0,\n\t\t\tret = results || [];\n\n\t\tif ( toString.call(array) === \"[object Array]\" ) {\n\t\t\tArray.prototype.push.apply( ret, array );\n\n\t\t} else {\n\t\t\tif ( typeof array.length === \"number\" ) {\n\t\t\t\tfor ( var l = array.length; i < l; i++ ) {\n\t\t\t\t\tret.push( array[i] );\n\t\t\t\t}\n\n\t\t\t} else {\n\t\t\t\tfor ( ; array[i]; i++ ) {\n\t\t\t\t\tret.push( array[i] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t};\n}\n\nvar sortOrder, siblingCheck;\n\nif ( document.documentElement.compareDocumentPosition ) {\n\tsortOrder = function( a, b ) {\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\tif ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {\n\t\t\treturn a.compareDocumentPosition ? -1 : 1;\n\t\t}\n\n\t\treturn a.compareDocumentPosition(b) & 4 ? -1 : 1;\n\t};\n\n} else {\n\tsortOrder = function( a, b ) {\n\t\t// The nodes are identical, we can exit early\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\n\t\t// Fallback to using sourceIndex (in IE) if it's available on both nodes\n\t\t} else if ( a.sourceIndex && b.sourceIndex ) {\n\t\t\treturn a.sourceIndex - b.sourceIndex;\n\t\t}\n\n\t\tvar al, bl,\n\t\t\tap = [],\n\t\t\tbp = [],\n\t\t\taup = a.parentNode,\n\t\t\tbup = b.parentNode,\n\t\t\tcur = aup;\n\n\t\t// If the nodes are siblings (or identical) we can do a quick check\n\t\tif ( aup === bup ) {\n\t\t\treturn siblingCheck( a, b );\n\n\t\t// If no parents were found then the nodes are disconnected\n\t\t} else if ( !aup ) {\n\t\t\treturn -1;\n\n\t\t} else if ( !bup ) {\n\t\t\treturn 1;\n\t\t}\n\n\t\t// Otherwise they're somewhere else in the tree so we need\n\t\t// to build up a full list of the parentNodes for comparison\n\t\twhile ( cur ) {\n\t\t\tap.unshift( cur );\n\t\t\tcur = cur.parentNode;\n\t\t}\n\n\t\tcur = bup;\n\n\t\twhile ( cur ) {\n\t\t\tbp.unshift( cur );\n\t\t\tcur = cur.parentNode;\n\t\t}\n\n\t\tal = ap.length;\n\t\tbl = bp.length;\n\n\t\t// Start walking down the tree looking for a discrepancy\n\t\tfor ( var i = 0; i < al && i < bl; i++ ) {\n\t\t\tif ( ap[i] !== bp[i] ) {\n\t\t\t\treturn siblingCheck( ap[i], bp[i] );\n\t\t\t}\n\t\t}\n\n\t\t// We ended someplace up the tree so do a sibling check\n\t\treturn i === al ?\n\t\t\tsiblingCheck( a, bp[i], -1 ) :\n\t\t\tsiblingCheck( ap[i], b, 1 );\n\t};\n\n\tsiblingCheck = function( a, b, ret ) {\n\t\tif ( a === b ) {\n\t\t\treturn ret;\n\t\t}\n\n\t\tvar cur = a.nextSibling;\n\n\t\twhile ( cur ) {\n\t\t\tif ( cur === b ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\n\t\t\tcur = cur.nextSibling;\n\t\t}\n\n\t\treturn 1;\n\t};\n}\n\n// Utility function for retreiving the text value of an array of DOM nodes\nSizzle.getText = function( elems ) {\n\tvar ret = \"\", elem;\n\n\tfor ( var i = 0; elems[i]; i++ ) {\n\t\telem = elems[i];\n\n\t\t// Get the text from text nodes and CDATA nodes\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 4 ) {\n\t\t\tret += elem.nodeValue;\n\n\t\t// Traverse everything else, except comment nodes\n\t\t} else if ( elem.nodeType !== 8 ) {\n\t\t\tret += Sizzle.getText( elem.childNodes );\n\t\t}\n\t}\n\n\treturn ret;\n};\n\n// Check to see if the browser returns elements by name when\n// querying by getElementById (and provide a workaround)\n(function(){\n\t// We're going to inject a fake input element with a specified name\n\tvar form = document.createElement(\"div\"),\n\t\tid = \"script\" + (new Date()).getTime(),\n\t\troot = document.documentElement;\n\n\tform.innerHTML = \"<a name='\" + id + \"'/>\";\n\n\t// Inject it into the root element, check its status, and remove it quickly\n\troot.insertBefore( form, root.firstChild );\n\n\t// The workaround has to do additional checks after a getElementById\n\t// Which slows things down for other browsers (hence the branching)\n\tif ( document.getElementById( id ) ) {\n\t\tExpr.find.ID = function( match, context, isXML ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && !isXML ) {\n\t\t\t\tvar m = context.getElementById(match[1]);\n\n\t\t\t\treturn m ?\n\t\t\t\t\tm.id === match[1] || typeof m.getAttributeNode !== \"undefined\" && m.getAttributeNode(\"id\").nodeValue === match[1] ?\n\t\t\t\t\t\t[m] :\n\t\t\t\t\t\tundefined :\n\t\t\t\t\t[];\n\t\t\t}\n\t\t};\n\n\t\tExpr.filter.ID = function( elem, match ) {\n\t\t\tvar node = typeof elem.getAttributeNode !== \"undefined\" && elem.getAttributeNode(\"id\");\n\n\t\t\treturn elem.nodeType === 1 && node && node.nodeValue === match;\n\t\t};\n\t}\n\n\troot.removeChild( form );\n\n\t// release memory in IE\n\troot = form = null;\n})();\n\n(function(){\n\t// Check to see if the browser returns only elements\n\t// when doing getElementsByTagName(\"*\")\n\n\t// Create a fake element\n\tvar div = document.createElement(\"div\");\n\tdiv.appendChild( document.createComment(\"\") );\n\n\t// Make sure no comments are found\n\tif ( div.getElementsByTagName(\"*\").length > 0 ) {\n\t\tExpr.find.TAG = function( match, context ) {\n\t\t\tvar results = context.getElementsByTagName( match[1] );\n\n\t\t\t// Filter out possible comments\n\t\t\tif ( match[1] === \"*\" ) {\n\t\t\t\tvar tmp = [];\n\n\t\t\t\tfor ( var i = 0; results[i]; i++ ) {\n\t\t\t\t\tif ( results[i].nodeType === 1 ) {\n\t\t\t\t\t\ttmp.push( results[i] );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tresults = tmp;\n\t\t\t}\n\n\t\t\treturn results;\n\t\t};\n\t}\n\n\t// Check to see if an attribute returns normalized href attributes\n\tdiv.innerHTML = \"<a href='#'></a>\";\n\n\tif ( div.firstChild && typeof div.firstChild.getAttribute !== \"undefined\" &&\n\t\t\tdiv.firstChild.getAttribute(\"href\") !== \"#\" ) {\n\n\t\tExpr.attrHandle.href = function( elem ) {\n\t\t\treturn elem.getAttribute( \"href\", 2 );\n\t\t};\n\t}\n\n\t// release memory in IE\n\tdiv = null;\n})();\n\nif ( document.querySelectorAll ) {\n\t(function(){\n\t\tvar oldSizzle = Sizzle,\n\t\t\tdiv = document.createElement(\"div\"),\n\t\t\tid = \"__sizzle__\";\n\n\t\tdiv.innerHTML = \"<p class='TEST'></p>\";\n\n\t\t// Safari can't handle uppercase or unicode characters when\n\t\t// in quirks mode.\n\t\tif ( div.querySelectorAll && div.querySelectorAll(\".TEST\").length === 0 ) {\n\t\t\treturn;\n\t\t}\n\t\n\t\tSizzle = function( query, context, extra, seed ) {\n\t\t\tcontext = context || document;\n\n\t\t\t// Only use querySelectorAll on non-XML documents\n\t\t\t// (ID selectors don't work in non-HTML documents)\n\t\t\tif ( !seed && !Sizzle.isXML(context) ) {\n\t\t\t\t// See if we find a selector to speed up\n\t\t\t\tvar match = /^(\\w+$)|^\\.([\\w\\-]+$)|^#([\\w\\-]+$)/.exec( query );\n\t\t\t\t\n\t\t\t\tif ( match && (context.nodeType === 1 || context.nodeType === 9) ) {\n\t\t\t\t\t// Speed-up: Sizzle(\"TAG\")\n\t\t\t\t\tif ( match[1] ) {\n\t\t\t\t\t\treturn makeArray( context.getElementsByTagName( query ), extra );\n\t\t\t\t\t\n\t\t\t\t\t// Speed-up: Sizzle(\".CLASS\")\n\t\t\t\t\t} else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) {\n\t\t\t\t\t\treturn makeArray( context.getElementsByClassName( match[2] ), extra );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tif ( context.nodeType === 9 ) {\n\t\t\t\t\t// Speed-up: Sizzle(\"body\")\n\t\t\t\t\t// The body element only exists once, optimize finding it\n\t\t\t\t\tif ( query === \"body\" && context.body ) {\n\t\t\t\t\t\treturn makeArray( [ context.body ], extra );\n\t\t\t\t\t\t\n\t\t\t\t\t// Speed-up: Sizzle(\"#ID\")\n\t\t\t\t\t} else if ( match && match[3] ) {\n\t\t\t\t\t\tvar elem = context.getElementById( match[3] );\n\n\t\t\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t\t\t// nodes that are no longer in the document #6963\n\t\t\t\t\t\tif ( elem && elem.parentNode ) {\n\t\t\t\t\t\t\t// Handle the case where IE and Opera return items\n\t\t\t\t\t\t\t// by name instead of ID\n\t\t\t\t\t\t\tif ( elem.id === match[3] ) {\n\t\t\t\t\t\t\t\treturn makeArray( [ elem ], extra );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn makeArray( [], extra );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\ttry {\n\t\t\t\t\t\treturn makeArray( context.querySelectorAll(query), extra );\n\t\t\t\t\t} catch(qsaError) {}\n\n\t\t\t\t// qSA works strangely on Element-rooted queries\n\t\t\t\t// We can work around this by specifying an extra ID on the root\n\t\t\t\t// and working up from there (Thanks to Andrew Dupont for the technique)\n\t\t\t\t// IE 8 doesn't work on object elements\n\t\t\t\t} else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== \"object\" ) {\n\t\t\t\t\tvar oldContext = context,\n\t\t\t\t\t\told = context.getAttribute( \"id\" ),\n\t\t\t\t\t\tnid = old || id,\n\t\t\t\t\t\thasParent = context.parentNode,\n\t\t\t\t\t\trelativeHierarchySelector = /^\\s*[+~]/.test( query );\n\n\t\t\t\t\tif ( !old ) {\n\t\t\t\t\t\tcontext.setAttribute( \"id\", nid );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnid = nid.replace( /'/g, \"\\\\$&\" );\n\t\t\t\t\t}\n\t\t\t\t\tif ( relativeHierarchySelector && hasParent ) {\n\t\t\t\t\t\tcontext = context.parentNode;\n\t\t\t\t\t}\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tif ( !relativeHierarchySelector || hasParent ) {\n\t\t\t\t\t\t\treturn makeArray( context.querySelectorAll( \"[id='\" + nid + \"'] \" + query ), extra );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} catch(pseudoError) {\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tif ( !old ) {\n\t\t\t\t\t\t\toldContext.removeAttribute( \"id\" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\n\t\t\treturn oldSizzle(query, context, extra, seed);\n\t\t};\n\n\t\tfor ( var prop in oldSizzle ) {\n\t\t\tSizzle[ prop ] = oldSizzle[ prop ];\n\t\t}\n\n\t\t// release memory in IE\n\t\tdiv = null;\n\t})();\n}\n\n(function(){\n\tvar html = document.documentElement,\n\t\tmatches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector;\n\n\tif ( matches ) {\n\t\t// Check to see if it's possible to do matchesSelector\n\t\t// on a disconnected node (IE 9 fails this)\n\t\tvar disconnectedMatch = !matches.call( document.createElement( \"div\" ), \"div\" ),\n\t\t\tpseudoWorks = false;\n\n\t\ttry {\n\t\t\t// This should fail with an exception\n\t\t\t// Gecko does not error, returns false instead\n\t\t\tmatches.call( document.documentElement, \"[test!='']:sizzle\" );\n\t\n\t\t} catch( pseudoError ) {\n\t\t\tpseudoWorks = true;\n\t\t}\n\n\t\tSizzle.matchesSelector = function( node, expr ) {\n\t\t\t// Make sure that attribute selectors are quoted\n\t\t\texpr = expr.replace(/\\=\\s*([^'\"\\]]*)\\s*\\]/g, \"='$1']\");\n\n\t\t\tif ( !Sizzle.isXML( node ) ) {\n\t\t\t\ttry { \n\t\t\t\t\tif ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {\n\t\t\t\t\t\tvar ret = matches.call( node, expr );\n\n\t\t\t\t\t\t// IE 9's matchesSelector returns false on disconnected nodes\n\t\t\t\t\t\tif ( ret || !disconnectedMatch ||\n\t\t\t\t\t\t\t\t// As well, disconnected nodes are said to be in a document\n\t\t\t\t\t\t\t\t// fragment in IE 9, so check for that\n\t\t\t\t\t\t\t\tnode.document && node.document.nodeType !== 11 ) {\n\t\t\t\t\t\t\treturn ret;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} catch(e) {}\n\t\t\t}\n\n\t\t\treturn Sizzle(expr, null, null, [node]).length > 0;\n\t\t};\n\t}\n})();\n\n(function(){\n\tvar div = document.createElement(\"div\");\n\n\tdiv.innerHTML = \"<div class='test e'></div><div class='test'></div>\";\n\n\t// Opera can't find a second classname (in 9.6)\n\t// Also, make sure that getElementsByClassName actually exists\n\tif ( !div.getElementsByClassName || div.getElementsByClassName(\"e\").length === 0 ) {\n\t\treturn;\n\t}\n\n\t// Safari caches class attributes, doesn't catch changes (in 3.2)\n\tdiv.lastChild.className = \"e\";\n\n\tif ( div.getElementsByClassName(\"e\").length === 1 ) {\n\t\treturn;\n\t}\n\t\n\tExpr.order.splice(1, 0, \"CLASS\");\n\tExpr.find.CLASS = function( match, context, isXML ) {\n\t\tif ( typeof context.getElementsByClassName !== \"undefined\" && !isXML ) {\n\t\t\treturn context.getElementsByClassName(match[1]);\n\t\t}\n\t};\n\n\t// release memory in IE\n\tdiv = null;\n})();\n\nfunction dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {\n\tfor ( var i = 0, l = checkSet.length; i < l; i++ ) {\n\t\tvar elem = checkSet[i];\n\n\t\tif ( elem ) {\n\t\t\tvar match = false;\n\n\t\t\telem = elem[dir];\n\n\t\t\twhile ( elem ) {\n\t\t\t\tif ( elem.sizcache === doneName ) {\n\t\t\t\t\tmatch = checkSet[elem.sizset];\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif ( elem.nodeType === 1 && !isXML ){\n\t\t\t\t\telem.sizcache = doneName;\n\t\t\t\t\telem.sizset = i;\n\t\t\t\t}\n\n\t\t\t\tif ( elem.nodeName.toLowerCase() === cur ) {\n\t\t\t\t\tmatch = elem;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\telem = elem[dir];\n\t\t\t}\n\n\t\t\tcheckSet[i] = match;\n\t\t}\n\t}\n}\n\nfunction dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {\n\tfor ( var i = 0, l = checkSet.length; i < l; i++ ) {\n\t\tvar elem = checkSet[i];\n\n\t\tif ( elem ) {\n\t\t\tvar match = false;\n\t\t\t\n\t\t\telem = elem[dir];\n\n\t\t\twhile ( elem ) {\n\t\t\t\tif ( elem.sizcache === doneName ) {\n\t\t\t\t\tmatch = checkSet[elem.sizset];\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\tif ( !isXML ) {\n\t\t\t\t\t\telem.sizcache = doneName;\n\t\t\t\t\t\telem.sizset = i;\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( typeof cur !== \"string\" ) {\n\t\t\t\t\t\tif ( elem === cur ) {\n\t\t\t\t\t\t\tmatch = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {\n\t\t\t\t\t\tmatch = elem;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\telem = elem[dir];\n\t\t\t}\n\n\t\t\tcheckSet[i] = match;\n\t\t}\n\t}\n}\n\nif ( document.documentElement.contains ) {\n\tSizzle.contains = function( a, b ) {\n\t\treturn a !== b && (a.contains ? a.contains(b) : true);\n\t};\n\n} else if ( document.documentElement.compareDocumentPosition ) {\n\tSizzle.contains = function( a, b ) {\n\t\treturn !!(a.compareDocumentPosition(b) & 16);\n\t};\n\n} else {\n\tSizzle.contains = function() {\n\t\treturn false;\n\t};\n}\n\nSizzle.isXML = function( elem ) {\n\t// documentElement is verified for cases where it doesn't yet exist\n\t// (such as loading iframes in IE - #4833) \n\tvar documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;\n\n\treturn documentElement ? documentElement.nodeName !== \"HTML\" : false;\n};\n\nvar posProcess = function( selector, context ) {\n\tvar match,\n\t\ttmpSet = [],\n\t\tlater = \"\",\n\t\troot = context.nodeType ? [context] : context;\n\n\t// Position selectors must be done after the filter\n\t// And so must :not(positional) so we move all PSEUDOs to the end\n\twhile ( (match = Expr.match.PSEUDO.exec( selector )) ) {\n\t\tlater += match[0];\n\t\tselector = selector.replace( Expr.match.PSEUDO, \"\" );\n\t}\n\n\tselector = Expr.relative[selector] ? selector + \"*\" : selector;\n\n\tfor ( var i = 0, l = root.length; i < l; i++ ) {\n\t\tSizzle( selector, root[i], tmpSet );\n\t}\n\n\treturn Sizzle.filter( later, tmpSet );\n};\n\n// EXPOSE\njQuery.find = Sizzle;\njQuery.expr = Sizzle.selectors;\njQuery.expr[\":\"] = jQuery.expr.filters;\njQuery.unique = Sizzle.uniqueSort;\njQuery.text = Sizzle.getText;\njQuery.isXMLDoc = Sizzle.isXML;\njQuery.contains = Sizzle.contains;\n\n\n})();\n\n\nvar runtil = /Until$/,\n\trparentsprev = /^(?:parents|prevUntil|prevAll)/,\n\t// Note: This RegExp should be improved, or likely pulled from Sizzle\n\trmultiselector = /,/,\n\tisSimple = /^.[^:#\\[\\.,]*$/,\n\tslice = Array.prototype.slice,\n\tPOS = jQuery.expr.match.POS,\n\t// methods guaranteed to produce a unique set when starting from a unique set\n\tguaranteedUnique = {\n\t\tchildren: true,\n\t\tcontents: true,\n\t\tnext: true,\n\t\tprev: true\n\t};\n\njQuery.fn.extend({\n\tfind: function( selector ) {\n\t\tvar self = this,\n\t\t\ti, l;\n\n\t\tif ( typeof selector !== \"string\" ) {\n\t\t\treturn jQuery( selector ).filter(function() {\n\t\t\t\tfor ( i = 0, l = self.length; i < l; i++ ) {\n\t\t\t\t\tif ( jQuery.contains( self[ i ], this ) ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tvar ret = this.pushStack( \"\", \"find\", selector ),\n\t\t\tlength, n, r;\n\n\t\tfor ( i = 0, l = this.length; i < l; i++ ) {\n\t\t\tlength = ret.length;\n\t\t\tjQuery.find( selector, this[i], ret );\n\n\t\t\tif ( i > 0 ) {\n\t\t\t\t// Make sure that the results are unique\n\t\t\t\tfor ( n = length; n < ret.length; n++ ) {\n\t\t\t\t\tfor ( r = 0; r < length; r++ ) {\n\t\t\t\t\t\tif ( ret[r] === ret[n] ) {\n\t\t\t\t\t\t\tret.splice(n--, 1);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\thas: function( target ) {\n\t\tvar targets = jQuery( target );\n\t\treturn this.filter(function() {\n\t\t\tfor ( var i = 0, l = targets.length; i < l; i++ ) {\n\t\t\t\tif ( jQuery.contains( this, targets[i] ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t},\n\n\tnot: function( selector ) {\n\t\treturn this.pushStack( winnow(this, selector, false), \"not\", selector);\n\t},\n\n\tfilter: function( selector ) {\n\t\treturn this.pushStack( winnow(this, selector, true), \"filter\", selector );\n\t},\n\n\tis: function( selector ) {\n\t\treturn !!selector && ( typeof selector === \"string\" ?\n\t\t\tjQuery.filter( selector, this ).length > 0 :\n\t\t\tthis.filter( selector ).length > 0 );\n\t},\n\n\tclosest: function( selectors, context ) {\n\t\tvar ret = [], i, l, cur = this[0];\n\t\t\n\t\t// Array\n\t\tif ( jQuery.isArray( selectors ) ) {\n\t\t\tvar match, selector,\n\t\t\t\tmatches = {},\n\t\t\t\tlevel = 1;\n\n\t\t\tif ( cur && selectors.length ) {\n\t\t\t\tfor ( i = 0, l = selectors.length; i < l; i++ ) {\n\t\t\t\t\tselector = selectors[i];\n\n\t\t\t\t\tif ( !matches[ selector ] ) {\n\t\t\t\t\t\tmatches[ selector ] = POS.test( selector ) ?\n\t\t\t\t\t\t\tjQuery( selector, context || this.context ) :\n\t\t\t\t\t\t\tselector;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\twhile ( cur && cur.ownerDocument && cur !== context ) {\n\t\t\t\t\tfor ( selector in matches ) {\n\t\t\t\t\t\tmatch = matches[ selector ];\n\n\t\t\t\t\t\tif ( match.jquery ? match.index( cur ) > -1 : jQuery( cur ).is( match ) ) {\n\t\t\t\t\t\t\tret.push({ selector: selector, elem: cur, level: level });\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tcur = cur.parentNode;\n\t\t\t\t\tlevel++;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn ret;\n\t\t}\n\n\t\t// String\n\t\tvar pos = POS.test( selectors ) || typeof selectors !== \"string\" ?\n\t\t\t\tjQuery( selectors, context || this.context ) :\n\t\t\t\t0;\n\n\t\tfor ( i = 0, l = this.length; i < l; i++ ) {\n\t\t\tcur = this[i];\n\n\t\t\twhile ( cur ) {\n\t\t\t\tif ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {\n\t\t\t\t\tret.push( cur );\n\t\t\t\t\tbreak;\n\n\t\t\t\t} else {\n\t\t\t\t\tcur = cur.parentNode;\n\t\t\t\t\tif ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tret = ret.length > 1 ? jQuery.unique( ret ) : ret;\n\n\t\treturn this.pushStack( ret, \"closest\", selectors );\n\t},\n\n\t// Determine the position of an element within\n\t// the matched set of elements\n\tindex: function( elem ) {\n\n\t\t// No argument, return index in parent\n\t\tif ( !elem ) {\n\t\t\treturn ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1;\n\t\t}\n\n\t\t// index in selector\n\t\tif ( typeof elem === \"string\" ) {\n\t\t\treturn jQuery.inArray( this[0], jQuery( elem ) );\n\t\t}\n\n\t\t// Locate the position of the desired element\n\t\treturn jQuery.inArray(\n\t\t\t// If it receives a jQuery object, the first element is used\n\t\t\telem.jquery ? elem[0] : elem, this );\n\t},\n\n\tadd: function( selector, context ) {\n\t\tvar set = typeof selector === \"string\" ?\n\t\t\t\tjQuery( selector, context ) :\n\t\t\t\tjQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),\n\t\t\tall = jQuery.merge( this.get(), set );\n\n\t\treturn this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?\n\t\t\tall :\n\t\t\tjQuery.unique( all ) );\n\t},\n\n\tandSelf: function() {\n\t\treturn this.add( this.prevObject );\n\t}\n});\n\n// A painfully simple check to see if an element is disconnected\n// from a document (should be improved, where feasible).\nfunction isDisconnected( node ) {\n\treturn !node || !node.parentNode || node.parentNode.nodeType === 11;\n}\n\njQuery.each({\n\tparent: function( elem ) {\n\t\tvar parent = elem.parentNode;\n\t\treturn parent && parent.nodeType !== 11 ? parent : null;\n\t},\n\tparents: function( elem ) {\n\t\treturn jQuery.dir( elem, \"parentNode\" );\n\t},\n\tparentsUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"parentNode\", until );\n\t},\n\tnext: function( elem ) {\n\t\treturn jQuery.nth( elem, 2, \"nextSibling\" );\n\t},\n\tprev: function( elem ) {\n\t\treturn jQuery.nth( elem, 2, \"previousSibling\" );\n\t},\n\tnextAll: function( elem ) {\n\t\treturn jQuery.dir( elem, \"nextSibling\" );\n\t},\n\tprevAll: function( elem ) {\n\t\treturn jQuery.dir( elem, \"previousSibling\" );\n\t},\n\tnextUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"nextSibling\", until );\n\t},\n\tprevUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"previousSibling\", until );\n\t},\n\tsiblings: function( elem ) {\n\t\treturn jQuery.sibling( elem.parentNode.firstChild, elem );\n\t},\n\tchildren: function( elem ) {\n\t\treturn jQuery.sibling( elem.firstChild );\n\t},\n\tcontents: function( elem ) {\n\t\treturn jQuery.nodeName( elem, \"iframe\" ) ?\n\t\t\telem.contentDocument || elem.contentWindow.document :\n\t\t\tjQuery.makeArray( elem.childNodes );\n\t}\n}, function( name, fn ) {\n\tjQuery.fn[ name ] = function( until, selector ) {\n\t\tvar ret = jQuery.map( this, fn, until ),\n\t\t\t// The variable 'args' was introduced in\n\t\t\t// https://github.com/jquery/jquery/commit/52a0238\n\t\t\t// to work around a bug in Chrome 10 (Dev) and should be removed when the bug is fixed.\n\t\t\t// http://code.google.com/p/v8/issues/detail?id=1050\n\t\t\targs = slice.call(arguments);\n\n\t\tif ( !runtil.test( name ) ) {\n\t\t\tselector = until;\n\t\t}\n\n\t\tif ( selector && typeof selector === \"string\" ) {\n\t\t\tret = jQuery.filter( selector, ret );\n\t\t}\n\n\t\tret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;\n\n\t\tif ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {\n\t\t\tret = ret.reverse();\n\t\t}\n\n\t\treturn this.pushStack( ret, name, args.join(\",\") );\n\t};\n});\n\njQuery.extend({\n\tfilter: function( expr, elems, not ) {\n\t\tif ( not ) {\n\t\t\texpr = \":not(\" + expr + \")\";\n\t\t}\n\n\t\treturn elems.length === 1 ?\n\t\t\tjQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :\n\t\t\tjQuery.find.matches(expr, elems);\n\t},\n\n\tdir: function( elem, dir, until ) {\n\t\tvar matched = [],\n\t\t\tcur = elem[ dir ];\n\n\t\twhile ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {\n\t\t\tif ( cur.nodeType === 1 ) {\n\t\t\t\tmatched.push( cur );\n\t\t\t}\n\t\t\tcur = cur[dir];\n\t\t}\n\t\treturn matched;\n\t},\n\n\tnth: function( cur, result, dir, elem ) {\n\t\tresult = result || 1;\n\t\tvar num = 0;\n\n\t\tfor ( ; cur; cur = cur[dir] ) {\n\t\t\tif ( cur.nodeType === 1 && ++num === result ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn cur;\n\t},\n\n\tsibling: function( n, elem ) {\n\t\tvar r = [];\n\n\t\tfor ( ; n; n = n.nextSibling ) {\n\t\t\tif ( n.nodeType === 1 && n !== elem ) {\n\t\t\t\tr.push( n );\n\t\t\t}\n\t\t}\n\n\t\treturn r;\n\t}\n});\n\n// Implement the identical functionality for filter and not\nfunction winnow( elements, qualifier, keep ) {\n\n\t// Can't pass null or undefined to indexOf in Firefox 4\n\t// Set to 0 to skip string check\n\tqualifier = qualifier || 0;\n\n\tif ( jQuery.isFunction( qualifier ) ) {\n\t\treturn jQuery.grep(elements, function( elem, i ) {\n\t\t\tvar retVal = !!qualifier.call( elem, i, elem );\n\t\t\treturn retVal === keep;\n\t\t});\n\n\t} else if ( qualifier.nodeType ) {\n\t\treturn jQuery.grep(elements, function( elem, i ) {\n\t\t\treturn (elem === qualifier) === keep;\n\t\t});\n\n\t} else if ( typeof qualifier === \"string\" ) {\n\t\tvar filtered = jQuery.grep(elements, function( elem ) {\n\t\t\treturn elem.nodeType === 1;\n\t\t});\n\n\t\tif ( isSimple.test( qualifier ) ) {\n\t\t\treturn jQuery.filter(qualifier, filtered, !keep);\n\t\t} else {\n\t\t\tqualifier = jQuery.filter( qualifier, filtered );\n\t\t}\n\t}\n\n\treturn jQuery.grep(elements, function( elem, i ) {\n\t\treturn (jQuery.inArray( elem, qualifier ) >= 0) === keep;\n\t});\n}\n\n\n\n\nvar rinlinejQuery = / jQuery\\d+=\"(?:\\d+|null)\"/g,\n\trleadingWhitespace = /^\\s+/,\n\trxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\\w:]+)[^>]*)\\/>/ig,\n\trtagName = /<([\\w:]+)/,\n\trtbody = /<tbody/i,\n\trhtml = /<|&#?\\w+;/,\n\trnocache = /<(?:script|object|embed|option|style)/i,\n\t// checked=\"checked\" or checked\n\trchecked = /checked\\s*(?:[^=]|=\\s*.checked.)/i,\n\trscriptType = /\\/(java|ecma)script/i,\n\trcleanScript = /^\\s*<!(?:\\[CDATA\\[|\\-\\-)/,\n\twrapMap = {\n\t\toption: [ 1, \"<select multiple='multiple'>\", \"</select>\" ],\n\t\tlegend: [ 1, \"<fieldset>\", \"</fieldset>\" ],\n\t\tthead: [ 1, \"<table>\", \"</table>\" ],\n\t\ttr: [ 2, \"<table><tbody>\", \"</tbody></table>\" ],\n\t\ttd: [ 3, \"<table><tbody><tr>\", \"</tr></tbody></table>\" ],\n\t\tcol: [ 2, \"<table><tbody></tbody><colgroup>\", \"</colgroup></table>\" ],\n\t\tarea: [ 1, \"<map>\", \"</map>\" ],\n\t\t_default: [ 0, \"\", \"\" ]\n\t};\n\nwrapMap.optgroup = wrapMap.option;\nwrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\n// IE can't serialize <link> and <script> tags normally\nif ( !jQuery.support.htmlSerialize ) {\n\twrapMap._default = [ 1, \"div<div>\", \"</div>\" ];\n}\n\njQuery.fn.extend({\n\ttext: function( text ) {\n\t\tif ( jQuery.isFunction(text) ) {\n\t\t\treturn this.each(function(i) {\n\t\t\t\tvar self = jQuery( this );\n\n\t\t\t\tself.text( text.call(this, i, self.text()) );\n\t\t\t});\n\t\t}\n\n\t\tif ( typeof text !== \"object\" && text !== undefined ) {\n\t\t\treturn this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );\n\t\t}\n\n\t\treturn jQuery.text( this );\n\t},\n\n\twrapAll: function( html ) {\n\t\tif ( jQuery.isFunction( html ) ) {\n\t\t\treturn this.each(function(i) {\n\t\t\t\tjQuery(this).wrapAll( html.call(this, i) );\n\t\t\t});\n\t\t}\n\n\t\tif ( this[0] ) {\n\t\t\t// The elements to wrap the target around\n\t\t\tvar wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);\n\n\t\t\tif ( this[0].parentNode ) {\n\t\t\t\twrap.insertBefore( this[0] );\n\t\t\t}\n\n\t\t\twrap.map(function() {\n\t\t\t\tvar elem = this;\n\n\t\t\t\twhile ( elem.firstChild && elem.firstChild.nodeType === 1 ) {\n\t\t\t\t\telem = elem.firstChild;\n\t\t\t\t}\n\n\t\t\t\treturn elem;\n\t\t\t}).append( this );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\twrapInner: function( html ) {\n\t\tif ( jQuery.isFunction( html ) ) {\n\t\t\treturn this.each(function(i) {\n\t\t\t\tjQuery(this).wrapInner( html.call(this, i) );\n\t\t\t});\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tvar self = jQuery( this ),\n\t\t\t\tcontents = self.contents();\n\n\t\t\tif ( contents.length ) {\n\t\t\t\tcontents.wrapAll( html );\n\n\t\t\t} else {\n\t\t\t\tself.append( html );\n\t\t\t}\n\t\t});\n\t},\n\n\twrap: function( html ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery( this ).wrapAll( html );\n\t\t});\n\t},\n\n\tunwrap: function() {\n\t\treturn this.parent().each(function() {\n\t\t\tif ( !jQuery.nodeName( this, \"body\" ) ) {\n\t\t\t\tjQuery( this ).replaceWith( this.childNodes );\n\t\t\t}\n\t\t}).end();\n\t},\n\n\tappend: function() {\n\t\treturn this.domManip(arguments, true, function( elem ) {\n\t\t\tif ( this.nodeType === 1 ) {\n\t\t\t\tthis.appendChild( elem );\n\t\t\t}\n\t\t});\n\t},\n\n\tprepend: function() {\n\t\treturn this.domManip(arguments, true, function( elem ) {\n\t\t\tif ( this.nodeType === 1 ) {\n\t\t\t\tthis.insertBefore( elem, this.firstChild );\n\t\t\t}\n\t\t});\n\t},\n\n\tbefore: function() {\n\t\tif ( this[0] && this[0].parentNode ) {\n\t\t\treturn this.domManip(arguments, false, function( elem ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this );\n\t\t\t});\n\t\t} else if ( arguments.length ) {\n\t\t\tvar set = jQuery(arguments[0]);\n\t\t\tset.push.apply( set, this.toArray() );\n\t\t\treturn this.pushStack( set, \"before\", arguments );\n\t\t}\n\t},\n\n\tafter: function() {\n\t\tif ( this[0] && this[0].parentNode ) {\n\t\t\treturn this.domManip(arguments, false, function( elem ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this.nextSibling );\n\t\t\t});\n\t\t} else if ( arguments.length ) {\n\t\t\tvar set = this.pushStack( this, \"after\", arguments );\n\t\t\tset.push.apply( set, jQuery(arguments[0]).toArray() );\n\t\t\treturn set;\n\t\t}\n\t},\n\n\t// keepData is for internal use only--do not document\n\tremove: function( selector, keepData ) {\n\t\tfor ( var i = 0, elem; (elem = this[i]) != null; i++ ) {\n\t\t\tif ( !selector || jQuery.filter( selector, [ elem ] ).length ) {\n\t\t\t\tif ( !keepData && elem.nodeType === 1 ) {\n\t\t\t\t\tjQuery.cleanData( elem.getElementsByTagName(\"*\") );\n\t\t\t\t\tjQuery.cleanData( [ elem ] );\n\t\t\t\t}\n\n\t\t\t\tif ( elem.parentNode ) {\n\t\t\t\t\telem.parentNode.removeChild( elem );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tempty: function() {\n\t\tfor ( var i = 0, elem; (elem = this[i]) != null; i++ ) {\n\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\tjQuery.cleanData( elem.getElementsByTagName(\"*\") );\n\t\t\t}\n\n\t\t\t// Remove any remaining nodes\n\t\t\twhile ( elem.firstChild ) {\n\t\t\t\telem.removeChild( elem.firstChild );\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tclone: function( dataAndEvents, deepDataAndEvents ) {\n\t\tdataAndEvents = dataAndEvents == null ? false : dataAndEvents;\n\t\tdeepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;\n\n\t\treturn this.map( function () {\n\t\t\treturn jQuery.clone( this, dataAndEvents, deepDataAndEvents );\n\t\t});\n\t},\n\n\thtml: function( value ) {\n\t\tif ( value === undefined ) {\n\t\t\treturn this[0] && this[0].nodeType === 1 ?\n\t\t\t\tthis[0].innerHTML.replace(rinlinejQuery, \"\") :\n\t\t\t\tnull;\n\n\t\t// See if we can take a shortcut and just use innerHTML\n\t\t} else if ( typeof value === \"string\" && !rnocache.test( value ) &&\n\t\t\t(jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&\n\t\t\t!wrapMap[ (rtagName.exec( value ) || [\"\", \"\"])[1].toLowerCase() ] ) {\n\n\t\t\tvalue = value.replace(rxhtmlTag, \"<$1></$2>\");\n\n\t\t\ttry {\n\t\t\t\tfor ( var i = 0, l = this.length; i < l; i++ ) {\n\t\t\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\t\t\tif ( this[i].nodeType === 1 ) {\n\t\t\t\t\t\tjQuery.cleanData( this[i].getElementsByTagName(\"*\") );\n\t\t\t\t\t\tthis[i].innerHTML = value;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// If using innerHTML throws an exception, use the fallback method\n\t\t\t} catch(e) {\n\t\t\t\tthis.empty().append( value );\n\t\t\t}\n\n\t\t} else if ( jQuery.isFunction( value ) ) {\n\t\t\tthis.each(function(i){\n\t\t\t\tvar self = jQuery( this );\n\n\t\t\t\tself.html( value.call(this, i, self.html()) );\n\t\t\t});\n\n\t\t} else {\n\t\t\tthis.empty().append( value );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\treplaceWith: function( value ) {\n\t\tif ( this[0] && this[0].parentNode ) {\n\t\t\t// Make sure that the elements are removed from the DOM before they are inserted\n\t\t\t// this can help fix replacing a parent with child elements\n\t\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\t\treturn this.each(function(i) {\n\t\t\t\t\tvar self = jQuery(this), old = self.html();\n\t\t\t\t\tself.replaceWith( value.call( this, i, old ) );\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif ( typeof value !== \"string\" ) {\n\t\t\t\tvalue = jQuery( value ).detach();\n\t\t\t}\n\n\t\t\treturn this.each(function() {\n\t\t\t\tvar next = this.nextSibling,\n\t\t\t\t\tparent = this.parentNode;\n\n\t\t\t\tjQuery( this ).remove();\n\n\t\t\t\tif ( next ) {\n\t\t\t\t\tjQuery(next).before( value );\n\t\t\t\t} else {\n\t\t\t\t\tjQuery(parent).append( value );\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\treturn this.length ?\n\t\t\t\tthis.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), \"replaceWith\", value ) :\n\t\t\t\tthis;\n\t\t}\n\t},\n\n\tdetach: function( selector ) {\n\t\treturn this.remove( selector, true );\n\t},\n\n\tdomManip: function( args, table, callback ) {\n\t\tvar results, first, fragment, parent,\n\t\t\tvalue = args[0],\n\t\t\tscripts = [];\n\n\t\t// We can't cloneNode fragments that contain checked, in WebKit\n\t\tif ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === \"string\" && rchecked.test( value ) ) {\n\t\t\treturn this.each(function() {\n\t\t\t\tjQuery(this).domManip( args, table, callback, true );\n\t\t\t});\n\t\t}\n\n\t\tif ( jQuery.isFunction(value) ) {\n\t\t\treturn this.each(function(i) {\n\t\t\t\tvar self = jQuery(this);\n\t\t\t\targs[0] = value.call(this, i, table ? self.html() : undefined);\n\t\t\t\tself.domManip( args, table, callback );\n\t\t\t});\n\t\t}\n\n\t\tif ( this[0] ) {\n\t\t\tparent = value && value.parentNode;\n\n\t\t\t// If we're in a fragment, just use that instead of building a new one\n\t\t\tif ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) {\n\t\t\t\tresults = { fragment: parent };\n\n\t\t\t} else {\n\t\t\t\tresults = jQuery.buildFragment( args, this, scripts );\n\t\t\t}\n\n\t\t\tfragment = results.fragment;\n\n\t\t\tif ( fragment.childNodes.length === 1 ) {\n\t\t\t\tfirst = fragment = fragment.firstChild;\n\t\t\t} else {\n\t\t\t\tfirst = fragment.firstChild;\n\t\t\t}\n\n\t\t\tif ( first ) {\n\t\t\t\ttable = table && jQuery.nodeName( first, \"tr\" );\n\n\t\t\t\tfor ( var i = 0, l = this.length, lastIndex = l - 1; i < l; i++ ) {\n\t\t\t\t\tcallback.call(\n\t\t\t\t\t\ttable ?\n\t\t\t\t\t\t\troot(this[i], first) :\n\t\t\t\t\t\t\tthis[i],\n\t\t\t\t\t\t// Make sure that we do not leak memory by inadvertently discarding\n\t\t\t\t\t\t// the original fragment (which might have attached data) instead of\n\t\t\t\t\t\t// using it; in addition, use the original fragment object for the last\n\t\t\t\t\t\t// item instead of first because it can end up being emptied incorrectly\n\t\t\t\t\t\t// in certain situations (Bug #8070).\n\t\t\t\t\t\t// Fragments from the fragment cache must always be cloned and never used\n\t\t\t\t\t\t// in place.\n\t\t\t\t\t\tresults.cacheable || (l > 1 && i < lastIndex) ?\n\t\t\t\t\t\t\tjQuery.clone( fragment, true, true ) :\n\t\t\t\t\t\t\tfragment\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( scripts.length ) {\n\t\t\t\tjQuery.each( scripts, evalScript );\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t}\n});\n\nfunction root( elem, cur ) {\n\treturn jQuery.nodeName(elem, \"table\") ?\n\t\t(elem.getElementsByTagName(\"tbody\")[0] ||\n\t\telem.appendChild(elem.ownerDocument.createElement(\"tbody\"))) :\n\t\telem;\n}\n\nfunction cloneCopyEvent( src, dest ) {\n\n\tif ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {\n\t\treturn;\n\t}\n\n\tvar internalKey = jQuery.expando,\n\t\toldData = jQuery.data( src ),\n\t\tcurData = jQuery.data( dest, oldData );\n\n\t// Switch to use the internal data object, if it exists, for the next\n\t// stage of data copying\n\tif ( (oldData = oldData[ internalKey ]) ) {\n\t\tvar events = oldData.events;\n\t\t\t\tcurData = curData[ internalKey ] = jQuery.extend({}, oldData);\n\n\t\tif ( events ) {\n\t\t\tdelete curData.handle;\n\t\t\tcurData.events = {};\n\n\t\t\tfor ( var type in events ) {\n\t\t\t\tfor ( var i = 0, l = events[ type ].length; i < l; i++ ) {\n\t\t\t\t\tjQuery.event.add( dest, type + ( events[ type ][ i ].namespace ? \".\" : \"\" ) + events[ type ][ i ].namespace, events[ type ][ i ], events[ type ][ i ].data );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction cloneFixAttributes( src, dest ) {\n\tvar nodeName;\n\n\t// We do not need to do anything for non-Elements\n\tif ( dest.nodeType !== 1 ) {\n\t\treturn;\n\t}\n\n\t// clearAttributes removes the attributes, which we don't want,\n\t// but also removes the attachEvent events, which we *do* want\n\tif ( dest.clearAttributes ) {\n\t\tdest.clearAttributes();\n\t}\n\n\t// mergeAttributes, in contrast, only merges back on the\n\t// original attributes, not the events\n\tif ( dest.mergeAttributes ) {\n\t\tdest.mergeAttributes( src );\n\t}\n\n\tnodeName = dest.nodeName.toLowerCase();\n\n\t// IE6-8 fail to clone children inside object elements that use\n\t// the proprietary classid attribute value (rather than the type\n\t// attribute) to identify the type of content to display\n\tif ( nodeName === \"object\" ) {\n\t\tdest.outerHTML = src.outerHTML;\n\n\t} else if ( nodeName === \"input\" && (src.type === \"checkbox\" || src.type === \"radio\") ) {\n\t\t// IE6-8 fails to persist the checked state of a cloned checkbox\n\t\t// or radio button. Worse, IE6-7 fail to give the cloned element\n\t\t// a checked appearance if the defaultChecked value isn't also set\n\t\tif ( src.checked ) {\n\t\t\tdest.defaultChecked = dest.checked = src.checked;\n\t\t}\n\n\t\t// IE6-7 get confused and end up setting the value of a cloned\n\t\t// checkbox/radio button to an empty string instead of \"on\"\n\t\tif ( dest.value !== src.value ) {\n\t\t\tdest.value = src.value;\n\t\t}\n\n\t// IE6-8 fails to return the selected option to the default selected\n\t// state when cloning options\n\t} else if ( nodeName === \"option\" ) {\n\t\tdest.selected = src.defaultSelected;\n\n\t// IE6-8 fails to set the defaultValue to the correct value when\n\t// cloning other types of input fields\n\t} else if ( nodeName === \"input\" || nodeName === \"textarea\" ) {\n\t\tdest.defaultValue = src.defaultValue;\n\t}\n\n\t// Event data gets referenced instead of copied if the expando\n\t// gets copied too\n\tdest.removeAttribute( jQuery.expando );\n}\n\njQuery.buildFragment = function( args, nodes, scripts ) {\n\tvar fragment, cacheable, cacheresults, doc;\n\n  // nodes may contain either an explicit document object,\n  // a jQuery collection or context object.\n  // If nodes[0] contains a valid object to assign to doc\n  if ( nodes && nodes[0] ) {\n    doc = nodes[0].ownerDocument || nodes[0];\n  }\n\n  // Ensure that an attr object doesn't incorrectly stand in as a document object\n\t// Chrome and Firefox seem to allow this to occur and will throw exception\n\t// Fixes #8950\n\tif ( !doc.createDocumentFragment ) {\n\t\tdoc = document;\n\t}\n\n\t// Only cache \"small\" (1/2 KB) HTML strings that are associated with the main document\n\t// Cloning options loses the selected state, so don't cache them\n\t// IE 6 doesn't like it when you put <object> or <embed> elements in a fragment\n\t// Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache\n\tif ( args.length === 1 && typeof args[0] === \"string\" && args[0].length < 512 && doc === document &&\n\t\targs[0].charAt(0) === \"<\" && !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {\n\n\t\tcacheable = true;\n\n\t\tcacheresults = jQuery.fragments[ args[0] ];\n\t\tif ( cacheresults && cacheresults !== 1 ) {\n\t\t\tfragment = cacheresults;\n\t\t}\n\t}\n\n\tif ( !fragment ) {\n\t\tfragment = doc.createDocumentFragment();\n\t\tjQuery.clean( args, doc, fragment, scripts );\n\t}\n\n\tif ( cacheable ) {\n\t\tjQuery.fragments[ args[0] ] = cacheresults ? fragment : 1;\n\t}\n\n\treturn { fragment: fragment, cacheable: cacheable };\n};\n\njQuery.fragments = {};\n\njQuery.each({\n\tappendTo: \"append\",\n\tprependTo: \"prepend\",\n\tinsertBefore: \"before\",\n\tinsertAfter: \"after\",\n\treplaceAll: \"replaceWith\"\n}, function( name, original ) {\n\tjQuery.fn[ name ] = function( selector ) {\n\t\tvar ret = [],\n\t\t\tinsert = jQuery( selector ),\n\t\t\tparent = this.length === 1 && this[0].parentNode;\n\n\t\tif ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {\n\t\t\tinsert[ original ]( this[0] );\n\t\t\treturn this;\n\n\t\t} else {\n\t\t\tfor ( var i = 0, l = insert.length; i < l; i++ ) {\n\t\t\t\tvar elems = (i > 0 ? this.clone(true) : this).get();\n\t\t\t\tjQuery( insert[i] )[ original ]( elems );\n\t\t\t\tret = ret.concat( elems );\n\t\t\t}\n\n\t\t\treturn this.pushStack( ret, name, insert.selector );\n\t\t}\n\t};\n});\n\nfunction getAll( elem ) {\n\tif ( \"getElementsByTagName\" in elem ) {\n\t\treturn elem.getElementsByTagName( \"*\" );\n\n\t} else if ( \"querySelectorAll\" in elem ) {\n\t\treturn elem.querySelectorAll( \"*\" );\n\n\t} else {\n\t\treturn [];\n\t}\n}\n\n// Used in clean, fixes the defaultChecked property\nfunction fixDefaultChecked( elem ) {\n\tif ( elem.type === \"checkbox\" || elem.type === \"radio\" ) {\n\t\telem.defaultChecked = elem.checked;\n\t}\n}\n// Finds all inputs and passes them to fixDefaultChecked\nfunction findInputs( elem ) {\n\tif ( jQuery.nodeName( elem, \"input\" ) ) {\n\t\tfixDefaultChecked( elem );\n\t} else if ( \"getElementsByTagName\" in elem ) {\n\t\tjQuery.grep( elem.getElementsByTagName(\"input\"), fixDefaultChecked );\n\t}\n}\n\njQuery.extend({\n\tclone: function( elem, dataAndEvents, deepDataAndEvents ) {\n\t\tvar clone = elem.cloneNode(true),\n\t\t\t\tsrcElements,\n\t\t\t\tdestElements,\n\t\t\t\ti;\n\n\t\tif ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&\n\t\t\t\t(elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {\n\t\t\t// IE copies events bound via attachEvent when using cloneNode.\n\t\t\t// Calling detachEvent on the clone will also remove the events\n\t\t\t// from the original. In order to get around this, we use some\n\t\t\t// proprietary methods to clear the events. Thanks to MooTools\n\t\t\t// guys for this hotness.\n\n\t\t\tcloneFixAttributes( elem, clone );\n\n\t\t\t// Using Sizzle here is crazy slow, so we use getElementsByTagName\n\t\t\t// instead\n\t\t\tsrcElements = getAll( elem );\n\t\t\tdestElements = getAll( clone );\n\n\t\t\t// Weird iteration because IE will replace the length property\n\t\t\t// with an element if you are cloning the body and one of the\n\t\t\t// elements on the page has a name or id of \"length\"\n\t\t\tfor ( i = 0; srcElements[i]; ++i ) {\n\t\t\t\t// Ensure that the destination node is not null; Fixes #9587\n\t\t\t\tif ( destElements[i] ) {\n\t\t\t\t\tcloneFixAttributes( srcElements[i], destElements[i] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Copy the events from the original to the clone\n\t\tif ( dataAndEvents ) {\n\t\t\tcloneCopyEvent( elem, clone );\n\n\t\t\tif ( deepDataAndEvents ) {\n\t\t\t\tsrcElements = getAll( elem );\n\t\t\t\tdestElements = getAll( clone );\n\n\t\t\t\tfor ( i = 0; srcElements[i]; ++i ) {\n\t\t\t\t\tcloneCopyEvent( srcElements[i], destElements[i] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tsrcElements = destElements = null;\n\n\t\t// Return the cloned set\n\t\treturn clone;\n\t},\n\n\tclean: function( elems, context, fragment, scripts ) {\n\t\tvar checkScriptType;\n\n\t\tcontext = context || document;\n\n\t\t// !context.createElement fails in IE with an error but returns typeof 'object'\n\t\tif ( typeof context.createElement === \"undefined\" ) {\n\t\t\tcontext = context.ownerDocument || context[0] && context[0].ownerDocument || document;\n\t\t}\n\n\t\tvar ret = [], j;\n\n\t\tfor ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {\n\t\t\tif ( typeof elem === \"number\" ) {\n\t\t\t\telem += \"\";\n\t\t\t}\n\n\t\t\tif ( !elem ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Convert html string into DOM nodes\n\t\t\tif ( typeof elem === \"string\" ) {\n\t\t\t\tif ( !rhtml.test( elem ) ) {\n\t\t\t\t\telem = context.createTextNode( elem );\n\t\t\t\t} else {\n\t\t\t\t\t// Fix \"XHTML\"-style tags in all browsers\n\t\t\t\t\telem = elem.replace(rxhtmlTag, \"<$1></$2>\");\n\n\t\t\t\t\t// Trim whitespace, otherwise indexOf won't work as expected\n\t\t\t\t\tvar tag = (rtagName.exec( elem ) || [\"\", \"\"])[1].toLowerCase(),\n\t\t\t\t\t\twrap = wrapMap[ tag ] || wrapMap._default,\n\t\t\t\t\t\tdepth = wrap[0],\n\t\t\t\t\t\tdiv = context.createElement(\"div\");\n\n\t\t\t\t\t// Go to html and back, then peel off extra wrappers\n\t\t\t\t\tdiv.innerHTML = wrap[1] + elem + wrap[2];\n\n\t\t\t\t\t// Move to the right depth\n\t\t\t\t\twhile ( depth-- ) {\n\t\t\t\t\t\tdiv = div.lastChild;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Remove IE's autoinserted <tbody> from table fragments\n\t\t\t\t\tif ( !jQuery.support.tbody ) {\n\n\t\t\t\t\t\t// String was a <table>, *may* have spurious <tbody>\n\t\t\t\t\t\tvar hasBody = rtbody.test(elem),\n\t\t\t\t\t\t\ttbody = tag === \"table\" && !hasBody ?\n\t\t\t\t\t\t\t\tdiv.firstChild && div.firstChild.childNodes :\n\n\t\t\t\t\t\t\t\t// String was a bare <thead> or <tfoot>\n\t\t\t\t\t\t\t\twrap[1] === \"<table>\" && !hasBody ?\n\t\t\t\t\t\t\t\t\tdiv.childNodes :\n\t\t\t\t\t\t\t\t\t[];\n\n\t\t\t\t\t\tfor ( j = tbody.length - 1; j >= 0 ; --j ) {\n\t\t\t\t\t\t\tif ( jQuery.nodeName( tbody[ j ], \"tbody\" ) && !tbody[ j ].childNodes.length ) {\n\t\t\t\t\t\t\t\ttbody[ j ].parentNode.removeChild( tbody[ j ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// IE completely kills leading whitespace when innerHTML is used\n\t\t\t\t\tif ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {\n\t\t\t\t\t\tdiv.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );\n\t\t\t\t\t}\n\n\t\t\t\t\telem = div.childNodes;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Resets defaultChecked for any radios and checkboxes\n\t\t\t// about to be appended to the DOM in IE 6/7 (#8060)\n\t\t\tvar len;\n\t\t\tif ( !jQuery.support.appendChecked ) {\n\t\t\t\tif ( elem[0] && typeof (len = elem.length) === \"number\" ) {\n\t\t\t\t\tfor ( j = 0; j < len; j++ ) {\n\t\t\t\t\t\tfindInputs( elem[j] );\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tfindInputs( elem );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( elem.nodeType ) {\n\t\t\t\tret.push( elem );\n\t\t\t} else {\n\t\t\t\tret = jQuery.merge( ret, elem );\n\t\t\t}\n\t\t}\n\n\t\tif ( fragment ) {\n\t\t\tcheckScriptType = function( elem ) {\n\t\t\t\treturn !elem.type || rscriptType.test( elem.type );\n\t\t\t};\n\t\t\tfor ( i = 0; ret[i]; i++ ) {\n\t\t\t\tif ( scripts && jQuery.nodeName( ret[i], \"script\" ) && (!ret[i].type || ret[i].type.toLowerCase() === \"text/javascript\") ) {\n\t\t\t\t\tscripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );\n\n\t\t\t\t} else {\n\t\t\t\t\tif ( ret[i].nodeType === 1 ) {\n\t\t\t\t\t\tvar jsTags = jQuery.grep( ret[i].getElementsByTagName( \"script\" ), checkScriptType );\n\n\t\t\t\t\t\tret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );\n\t\t\t\t\t}\n\t\t\t\t\tfragment.appendChild( ret[i] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tcleanData: function( elems ) {\n\t\tvar data, id, cache = jQuery.cache, internalKey = jQuery.expando, special = jQuery.event.special,\n\t\t\tdeleteExpando = jQuery.support.deleteExpando;\n\n\t\tfor ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {\n\t\t\tif ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tid = elem[ jQuery.expando ];\n\n\t\t\tif ( id ) {\n\t\t\t\tdata = cache[ id ] && cache[ id ][ internalKey ];\n\n\t\t\t\tif ( data && data.events ) {\n\t\t\t\t\tfor ( var type in data.events ) {\n\t\t\t\t\t\tif ( special[ type ] ) {\n\t\t\t\t\t\t\tjQuery.event.remove( elem, type );\n\n\t\t\t\t\t\t// This is a shortcut to avoid jQuery.event.remove's overhead\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tjQuery.removeEvent( elem, type, data.handle );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Null the DOM reference to avoid IE6/7/8 leak (#7054)\n\t\t\t\t\tif ( data.handle ) {\n\t\t\t\t\t\tdata.handle.elem = null;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( deleteExpando ) {\n\t\t\t\t\tdelete elem[ jQuery.expando ];\n\n\t\t\t\t} else if ( elem.removeAttribute ) {\n\t\t\t\t\telem.removeAttribute( jQuery.expando );\n\t\t\t\t}\n\n\t\t\t\tdelete cache[ id ];\n\t\t\t}\n\t\t}\n\t}\n});\n\nfunction evalScript( i, elem ) {\n\tif ( elem.src ) {\n\t\tjQuery.ajax({\n\t\t\turl: elem.src,\n\t\t\tasync: false,\n\t\t\tdataType: \"script\"\n\t\t});\n\t} else {\n\t\tjQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || \"\" ).replace( rcleanScript, \"/*$0*/\" ) );\n\t}\n\n\tif ( elem.parentNode ) {\n\t\telem.parentNode.removeChild( elem );\n\t}\n}\n\n\n\n\nvar ralpha = /alpha\\([^)]*\\)/i,\n\tropacity = /opacity=([^)]*)/,\n\t// fixed for IE9, see #8346\n\trupper = /([A-Z]|^ms)/g,\n\trnumpx = /^-?\\d+(?:px)?$/i,\n\trnum = /^-?\\d/,\n\trrelNum = /^([\\-+])=([\\-+.\\de]+)/,\n\n\tcssShow = { position: \"absolute\", visibility: \"hidden\", display: \"block\" },\n\tcssWidth = [ \"Left\", \"Right\" ],\n\tcssHeight = [ \"Top\", \"Bottom\" ],\n\tcurCSS,\n\n\tgetComputedStyle,\n\tcurrentStyle;\n\njQuery.fn.css = function( name, value ) {\n\t// Setting 'undefined' is a no-op\n\tif ( arguments.length === 2 && value === undefined ) {\n\t\treturn this;\n\t}\n\n\treturn jQuery.access( this, name, value, true, function( elem, name, value ) {\n\t\treturn value !== undefined ?\n\t\t\tjQuery.style( elem, name, value ) :\n\t\t\tjQuery.css( elem, name );\n\t});\n};\n\njQuery.extend({\n\t// Add in style property hooks for overriding the default\n\t// behavior of getting and setting a style property\n\tcssHooks: {\n\t\topacity: {\n\t\t\tget: function( elem, computed ) {\n\t\t\t\tif ( computed ) {\n\t\t\t\t\t// We should always get a number back from opacity\n\t\t\t\t\tvar ret = curCSS( elem, \"opacity\", \"opacity\" );\n\t\t\t\t\treturn ret === \"\" ? \"1\" : ret;\n\n\t\t\t\t} else {\n\t\t\t\t\treturn elem.style.opacity;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t// Exclude the following css properties to add px\n\tcssNumber: {\n\t\t\"fillOpacity\": true,\n\t\t\"fontWeight\": true,\n\t\t\"lineHeight\": true,\n\t\t\"opacity\": true,\n\t\t\"orphans\": true,\n\t\t\"widows\": true,\n\t\t\"zIndex\": true,\n\t\t\"zoom\": true\n\t},\n\n\t// Add in properties whose names you wish to fix before\n\t// setting or getting the value\n\tcssProps: {\n\t\t// normalize float css property\n\t\t\"float\": jQuery.support.cssFloat ? \"cssFloat\" : \"styleFloat\"\n\t},\n\n\t// Get and set the style property on a DOM Node\n\tstyle: function( elem, name, value, extra ) {\n\t\t// Don't set styles on text and comment nodes\n\t\tif ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure that we're working with the right name\n\t\tvar ret, type, origName = jQuery.camelCase( name ),\n\t\t\tstyle = elem.style, hooks = jQuery.cssHooks[ origName ];\n\n\t\tname = jQuery.cssProps[ origName ] || origName;\n\n\t\t// Check if we're setting a value\n\t\tif ( value !== undefined ) {\n\t\t\ttype = typeof value;\n\n\t\t\t// convert relative number strings (+= or -=) to relative numbers. #7345\n\t\t\tif ( type === \"string\" && (ret = rrelNum.exec( value )) ) {\n\t\t\t\tvalue = ( +( ret[1] + 1) * +ret[2] ) + parseFloat( jQuery.css( elem, name ) );\n\t\t\t\t// Fixes bug #9237\n\t\t\t\ttype = \"number\";\n\t\t\t}\n\n\t\t\t// Make sure that NaN and null values aren't set. See: #7116\n\t\t\tif ( value == null || type === \"number\" && isNaN( value ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If a number was passed in, add 'px' to the (except for certain CSS properties)\n\t\t\tif ( type === \"number\" && !jQuery.cssNumber[ origName ] ) {\n\t\t\t\tvalue += \"px\";\n\t\t\t}\n\n\t\t\t// If a hook was provided, use that value, otherwise just set the specified value\n\t\t\tif ( !hooks || !(\"set\" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {\n\t\t\t\t// Wrapped to prevent IE from throwing errors when 'invalid' values are provided\n\t\t\t\t// Fixes bug #5509\n\t\t\t\ttry {\n\t\t\t\t\tstyle[ name ] = value;\n\t\t\t\t} catch(e) {}\n\t\t\t}\n\n\t\t} else {\n\t\t\t// If a hook was provided get the non-computed value from there\n\t\t\tif ( hooks && \"get\" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\t// Otherwise just get the value from the style object\n\t\t\treturn style[ name ];\n\t\t}\n\t},\n\n\tcss: function( elem, name, extra ) {\n\t\tvar ret, hooks;\n\n\t\t// Make sure that we're working with the right name\n\t\tname = jQuery.camelCase( name );\n\t\thooks = jQuery.cssHooks[ name ];\n\t\tname = jQuery.cssProps[ name ] || name;\n\n\t\t// cssFloat needs a special treatment\n\t\tif ( name === \"cssFloat\" ) {\n\t\t\tname = \"float\";\n\t\t}\n\n\t\t// If a hook was provided get the computed value from there\n\t\tif ( hooks && \"get\" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {\n\t\t\treturn ret;\n\n\t\t// Otherwise, if a way to get the computed value exists, use that\n\t\t} else if ( curCSS ) {\n\t\t\treturn curCSS( elem, name );\n\t\t}\n\t},\n\n\t// A method for quickly swapping in/out CSS properties to get correct calculations\n\tswap: function( elem, options, callback ) {\n\t\tvar old = {};\n\n\t\t// Remember the old values, and insert the new ones\n\t\tfor ( var name in options ) {\n\t\t\told[ name ] = elem.style[ name ];\n\t\t\telem.style[ name ] = options[ name ];\n\t\t}\n\n\t\tcallback.call( elem );\n\n\t\t// Revert the old values\n\t\tfor ( name in options ) {\n\t\t\telem.style[ name ] = old[ name ];\n\t\t}\n\t}\n});\n\n// DEPRECATED, Use jQuery.css() instead\njQuery.curCSS = jQuery.css;\n\njQuery.each([\"height\", \"width\"], function( i, name ) {\n\tjQuery.cssHooks[ name ] = {\n\t\tget: function( elem, computed, extra ) {\n\t\t\tvar val;\n\n\t\t\tif ( computed ) {\n\t\t\t\tif ( elem.offsetWidth !== 0 ) {\n\t\t\t\t\treturn getWH( elem, name, extra );\n\t\t\t\t} else {\n\t\t\t\t\tjQuery.swap( elem, cssShow, function() {\n\t\t\t\t\t\tval = getWH( elem, name, extra );\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\treturn val;\n\t\t\t}\n\t\t},\n\n\t\tset: function( elem, value ) {\n\t\t\tif ( rnumpx.test( value ) ) {\n\t\t\t\t// ignore negative width and height values #1599\n\t\t\t\tvalue = parseFloat( value );\n\n\t\t\t\tif ( value >= 0 ) {\n\t\t\t\t\treturn value + \"px\";\n\t\t\t\t}\n\n\t\t\t} else {\n\t\t\t\treturn value;\n\t\t\t}\n\t\t}\n\t};\n});\n\nif ( !jQuery.support.opacity ) {\n\tjQuery.cssHooks.opacity = {\n\t\tget: function( elem, computed ) {\n\t\t\t// IE uses filters for opacity\n\t\t\treturn ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || \"\" ) ?\n\t\t\t\t( parseFloat( RegExp.$1 ) / 100 ) + \"\" :\n\t\t\t\tcomputed ? \"1\" : \"\";\n\t\t},\n\n\t\tset: function( elem, value ) {\n\t\t\tvar style = elem.style,\n\t\t\t\tcurrentStyle = elem.currentStyle,\n\t\t\t\topacity = jQuery.isNaN( value ) ? \"\" : \"alpha(opacity=\" + value * 100 + \")\",\n\t\t\t\tfilter = currentStyle && currentStyle.filter || style.filter || \"\";\n\n\t\t\t// IE has trouble with opacity if it does not have layout\n\t\t\t// Force it by setting the zoom level\n\t\t\tstyle.zoom = 1;\n\n\t\t\t// if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652\n\t\t\tif ( value >= 1 && jQuery.trim( filter.replace( ralpha, \"\" ) ) === \"\" ) {\n\n\t\t\t\t// Setting style.filter to null, \"\" & \" \" still leave \"filter:\" in the cssText\n\t\t\t\t// if \"filter:\" is present at all, clearType is disabled, we want to avoid this\n\t\t\t\t// style.removeAttribute is IE Only, but so apparently is this code path...\n\t\t\t\tstyle.removeAttribute( \"filter\" );\n\n\t\t\t\t// if there there is no filter style applied in a css rule, we are done\n\t\t\t\tif ( currentStyle && !currentStyle.filter ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// otherwise, set new filter values\n\t\t\tstyle.filter = ralpha.test( filter ) ?\n\t\t\t\tfilter.replace( ralpha, opacity ) :\n\t\t\t\tfilter + \" \" + opacity;\n\t\t}\n\t};\n}\n\njQuery(function() {\n\t// This hook cannot be added until DOM ready because the support test\n\t// for it is not run until after DOM ready\n\tif ( !jQuery.support.reliableMarginRight ) {\n\t\tjQuery.cssHooks.marginRight = {\n\t\t\tget: function( elem, computed ) {\n\t\t\t\t// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right\n\t\t\t\t// Work around by temporarily setting element display to inline-block\n\t\t\t\tvar ret;\n\t\t\t\tjQuery.swap( elem, { \"display\": \"inline-block\" }, function() {\n\t\t\t\t\tif ( computed ) {\n\t\t\t\t\t\tret = curCSS( elem, \"margin-right\", \"marginRight\" );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tret = elem.style.marginRight;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t};\n\t}\n});\n\nif ( document.defaultView && document.defaultView.getComputedStyle ) {\n\tgetComputedStyle = function( elem, name ) {\n\t\tvar ret, defaultView, computedStyle;\n\n\t\tname = name.replace( rupper, \"-$1\" ).toLowerCase();\n\n\t\tif ( !(defaultView = elem.ownerDocument.defaultView) ) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tif ( (computedStyle = defaultView.getComputedStyle( elem, null )) ) {\n\t\t\tret = computedStyle.getPropertyValue( name );\n\t\t\tif ( ret === \"\" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {\n\t\t\t\tret = jQuery.style( elem, name );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t};\n}\n\nif ( document.documentElement.currentStyle ) {\n\tcurrentStyle = function( elem, name ) {\n\t\tvar left,\n\t\t\tret = elem.currentStyle && elem.currentStyle[ name ],\n\t\t\trsLeft = elem.runtimeStyle && elem.runtimeStyle[ name ],\n\t\t\tstyle = elem.style;\n\n\t\t// From the awesome hack by Dean Edwards\n\t\t// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291\n\n\t\t// If we're not dealing with a regular pixel number\n\t\t// but a number that has a weird ending, we need to convert it to pixels\n\t\tif ( !rnumpx.test( ret ) && rnum.test( ret ) ) {\n\t\t\t// Remember the original values\n\t\t\tleft = style.left;\n\n\t\t\t// Put in the new values to get a computed value out\n\t\t\tif ( rsLeft ) {\n\t\t\t\telem.runtimeStyle.left = elem.currentStyle.left;\n\t\t\t}\n\t\t\tstyle.left = name === \"fontSize\" ? \"1em\" : (ret || 0);\n\t\t\tret = style.pixelLeft + \"px\";\n\n\t\t\t// Revert the changed values\n\t\t\tstyle.left = left;\n\t\t\tif ( rsLeft ) {\n\t\t\t\telem.runtimeStyle.left = rsLeft;\n\t\t\t}\n\t\t}\n\n\t\treturn ret === \"\" ? \"auto\" : ret;\n\t};\n}\n\ncurCSS = getComputedStyle || currentStyle;\n\nfunction getWH( elem, name, extra ) {\n\n\t// Start with offset property\n\tvar val = name === \"width\" ? elem.offsetWidth : elem.offsetHeight,\n\t\twhich = name === \"width\" ? cssWidth : cssHeight;\n\n\tif ( val > 0 ) {\n\t\tif ( extra !== \"border\" ) {\n\t\t\tjQuery.each( which, function() {\n\t\t\t\tif ( !extra ) {\n\t\t\t\t\tval -= parseFloat( jQuery.css( elem, \"padding\" + this ) ) || 0;\n\t\t\t\t}\n\t\t\t\tif ( extra === \"margin\" ) {\n\t\t\t\t\tval += parseFloat( jQuery.css( elem, extra + this ) ) || 0;\n\t\t\t\t} else {\n\t\t\t\t\tval -= parseFloat( jQuery.css( elem, \"border\" + this + \"Width\" ) ) || 0;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\treturn val + \"px\";\n\t}\n\n\t// Fall back to computed then uncomputed css if necessary\n\tval = curCSS( elem, name, name );\n\tif ( val < 0 || val == null ) {\n\t\tval = elem.style[ name ] || 0;\n\t}\n\t// Normalize \"\", auto, and prepare for extra\n\tval = parseFloat( val ) || 0;\n\n\t// Add padding, border, margin\n\tif ( extra ) {\n\t\tjQuery.each( which, function() {\n\t\t\tval += parseFloat( jQuery.css( elem, \"padding\" + this ) ) || 0;\n\t\t\tif ( extra !== \"padding\" ) {\n\t\t\t\tval += parseFloat( jQuery.css( elem, \"border\" + this + \"Width\" ) ) || 0;\n\t\t\t}\n\t\t\tif ( extra === \"margin\" ) {\n\t\t\t\tval += parseFloat( jQuery.css( elem, extra + this ) ) || 0;\n\t\t\t}\n\t\t});\n\t}\n\n\treturn val + \"px\";\n}\n\nif ( jQuery.expr && jQuery.expr.filters ) {\n\tjQuery.expr.filters.hidden = function( elem ) {\n\t\tvar width = elem.offsetWidth,\n\t\t\theight = elem.offsetHeight;\n\n\t\treturn (width === 0 && height === 0) || (!jQuery.support.reliableHiddenOffsets && (elem.style.display || jQuery.css( elem, \"display\" )) === \"none\");\n\t};\n\n\tjQuery.expr.filters.visible = function( elem ) {\n\t\treturn !jQuery.expr.filters.hidden( elem );\n\t};\n}\n\n\n\n\nvar r20 = /%20/g,\n\trbracket = /\\[\\]$/,\n\trCRLF = /\\r?\\n/g,\n\trhash = /#.*$/,\n\trheaders = /^(.*?):[ \\t]*([^\\r\\n]*)\\r?$/mg, // IE leaves an \\r character at EOL\n\trinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,\n\t// #7653, #8125, #8152: local protocol detection\n\trlocalProtocol = /^(?:about|app|app\\-storage|.+\\-extension|file|res|widget):$/,\n\trnoContent = /^(?:GET|HEAD)$/,\n\trprotocol = /^\\/\\//,\n\trquery = /\\?/,\n\trscript = /<script\\b[^<]*(?:(?!<\\/script>)<[^<]*)*<\\/script>/gi,\n\trselectTextarea = /^(?:select|textarea)/i,\n\trspacesAjax = /\\s+/,\n\trts = /([?&])_=[^&]*/,\n\trurl = /^([\\w\\+\\.\\-]+:)(?:\\/\\/([^\\/?#:]*)(?::(\\d+))?)?/,\n\n\t// Keep a copy of the old load method\n\t_load = jQuery.fn.load,\n\n\t/* Prefilters\n\t * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)\n\t * 2) These are called:\n\t *    - BEFORE asking for a transport\n\t *    - AFTER param serialization (s.data is a string if s.processData is true)\n\t * 3) key is the dataType\n\t * 4) the catchall symbol \"*\" can be used\n\t * 5) execution will start with transport dataType and THEN continue down to \"*\" if needed\n\t */\n\tprefilters = {},\n\n\t/* Transports bindings\n\t * 1) key is the dataType\n\t * 2) the catchall symbol \"*\" can be used\n\t * 3) selection will start with transport dataType and THEN go to \"*\" if needed\n\t */\n\ttransports = {},\n\n\t// Document location\n\tajaxLocation,\n\n\t// Document location segments\n\tajaxLocParts,\n\t\n\t// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression\n\tallTypes = [\"*/\"] + [\"*\"];\n\n// #8138, IE may throw an exception when accessing\n// a field from window.location if document.domain has been set\ntry {\n\tajaxLocation = location.href;\n} catch( e ) {\n\t// Use the href attribute of an A element\n\t// since IE will modify it given document.location\n\tajaxLocation = document.createElement( \"a\" );\n\tajaxLocation.href = \"\";\n\tajaxLocation = ajaxLocation.href;\n}\n\n// Segment location into parts\najaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];\n\n// Base \"constructor\" for jQuery.ajaxPrefilter and jQuery.ajaxTransport\nfunction addToPrefiltersOrTransports( structure ) {\n\n\t// dataTypeExpression is optional and defaults to \"*\"\n\treturn function( dataTypeExpression, func ) {\n\n\t\tif ( typeof dataTypeExpression !== \"string\" ) {\n\t\t\tfunc = dataTypeExpression;\n\t\t\tdataTypeExpression = \"*\";\n\t\t}\n\n\t\tif ( jQuery.isFunction( func ) ) {\n\t\t\tvar dataTypes = dataTypeExpression.toLowerCase().split( rspacesAjax ),\n\t\t\t\ti = 0,\n\t\t\t\tlength = dataTypes.length,\n\t\t\t\tdataType,\n\t\t\t\tlist,\n\t\t\t\tplaceBefore;\n\n\t\t\t// For each dataType in the dataTypeExpression\n\t\t\tfor(; i < length; i++ ) {\n\t\t\t\tdataType = dataTypes[ i ];\n\t\t\t\t// We control if we're asked to add before\n\t\t\t\t// any existing element\n\t\t\t\tplaceBefore = /^\\+/.test( dataType );\n\t\t\t\tif ( placeBefore ) {\n\t\t\t\t\tdataType = dataType.substr( 1 ) || \"*\";\n\t\t\t\t}\n\t\t\t\tlist = structure[ dataType ] = structure[ dataType ] || [];\n\t\t\t\t// then we add to the structure accordingly\n\t\t\t\tlist[ placeBefore ? \"unshift\" : \"push\" ]( func );\n\t\t\t}\n\t\t}\n\t};\n}\n\n// Base inspection function for prefilters and transports\nfunction inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR,\n\t\tdataType /* internal */, inspected /* internal */ ) {\n\n\tdataType = dataType || options.dataTypes[ 0 ];\n\tinspected = inspected || {};\n\n\tinspected[ dataType ] = true;\n\n\tvar list = structure[ dataType ],\n\t\ti = 0,\n\t\tlength = list ? list.length : 0,\n\t\texecuteOnly = ( structure === prefilters ),\n\t\tselection;\n\n\tfor(; i < length && ( executeOnly || !selection ); i++ ) {\n\t\tselection = list[ i ]( options, originalOptions, jqXHR );\n\t\t// If we got redirected to another dataType\n\t\t// we try there if executing only and not done already\n\t\tif ( typeof selection === \"string\" ) {\n\t\t\tif ( !executeOnly || inspected[ selection ] ) {\n\t\t\t\tselection = undefined;\n\t\t\t} else {\n\t\t\t\toptions.dataTypes.unshift( selection );\n\t\t\t\tselection = inspectPrefiltersOrTransports(\n\t\t\t\t\t\tstructure, options, originalOptions, jqXHR, selection, inspected );\n\t\t\t}\n\t\t}\n\t}\n\t// If we're only executing or nothing was selected\n\t// we try the catchall dataType if not done already\n\tif ( ( executeOnly || !selection ) && !inspected[ \"*\" ] ) {\n\t\tselection = inspectPrefiltersOrTransports(\n\t\t\t\tstructure, options, originalOptions, jqXHR, \"*\", inspected );\n\t}\n\t// unnecessary when only executing (prefilters)\n\t// but it'll be ignored by the caller in that case\n\treturn selection;\n}\n\n// A special extend for ajax options\n// that takes \"flat\" options (not to be deep extended)\n// Fixes #9887\nfunction ajaxExtend( target, src ) {\n\tvar key, deep,\n\t\tflatOptions = jQuery.ajaxSettings.flatOptions || {};\n\tfor( key in src ) {\n\t\tif ( src[ key ] !== undefined ) {\n\t\t\t( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];\n\t\t}\n\t}\n\tif ( deep ) {\n\t\tjQuery.extend( true, target, deep );\n\t}\n}\n\njQuery.fn.extend({\n\tload: function( url, params, callback ) {\n\t\tif ( typeof url !== \"string\" && _load ) {\n\t\t\treturn _load.apply( this, arguments );\n\n\t\t// Don't do a request if no elements are being requested\n\t\t} else if ( !this.length ) {\n\t\t\treturn this;\n\t\t}\n\n\t\tvar off = url.indexOf( \" \" );\n\t\tif ( off >= 0 ) {\n\t\t\tvar selector = url.slice( off, url.length );\n\t\t\turl = url.slice( 0, off );\n\t\t}\n\n\t\t// Default to a GET request\n\t\tvar type = \"GET\";\n\n\t\t// If the second parameter was provided\n\t\tif ( params ) {\n\t\t\t// If it's a function\n\t\t\tif ( jQuery.isFunction( params ) ) {\n\t\t\t\t// We assume that it's the callback\n\t\t\t\tcallback = params;\n\t\t\t\tparams = undefined;\n\n\t\t\t// Otherwise, build a param string\n\t\t\t} else if ( typeof params === \"object\" ) {\n\t\t\t\tparams = jQuery.param( params, jQuery.ajaxSettings.traditional );\n\t\t\t\ttype = \"POST\";\n\t\t\t}\n\t\t}\n\n\t\tvar self = this;\n\n\t\t// Request the remote document\n\t\tjQuery.ajax({\n\t\t\turl: url,\n\t\t\ttype: type,\n\t\t\tdataType: \"html\",\n\t\t\tdata: params,\n\t\t\t// Complete callback (responseText is used internally)\n\t\t\tcomplete: function( jqXHR, status, responseText ) {\n\t\t\t\t// Store the response as specified by the jqXHR object\n\t\t\t\tresponseText = jqXHR.responseText;\n\t\t\t\t// If successful, inject the HTML into all the matched elements\n\t\t\t\tif ( jqXHR.isResolved() ) {\n\t\t\t\t\t// #4825: Get the actual response in case\n\t\t\t\t\t// a dataFilter is present in ajaxSettings\n\t\t\t\t\tjqXHR.done(function( r ) {\n\t\t\t\t\t\tresponseText = r;\n\t\t\t\t\t});\n\t\t\t\t\t// See if a selector was specified\n\t\t\t\t\tself.html( selector ?\n\t\t\t\t\t\t// Create a dummy div to hold the results\n\t\t\t\t\t\tjQuery(\"<div>\")\n\t\t\t\t\t\t\t// inject the contents of the document in, removing the scripts\n\t\t\t\t\t\t\t// to avoid any 'Permission Denied' errors in IE\n\t\t\t\t\t\t\t.append(responseText.replace(rscript, \"\"))\n\n\t\t\t\t\t\t\t// Locate the specified elements\n\t\t\t\t\t\t\t.find(selector) :\n\n\t\t\t\t\t\t// If not, just inject the full result\n\t\t\t\t\t\tresponseText );\n\t\t\t\t}\n\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tself.each( callback, [ responseText, status, jqXHR ] );\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\treturn this;\n\t},\n\n\tserialize: function() {\n\t\treturn jQuery.param( this.serializeArray() );\n\t},\n\n\tserializeArray: function() {\n\t\treturn this.map(function(){\n\t\t\treturn this.elements ? jQuery.makeArray( this.elements ) : this;\n\t\t})\n\t\t.filter(function(){\n\t\t\treturn this.name && !this.disabled &&\n\t\t\t\t( this.checked || rselectTextarea.test( this.nodeName ) ||\n\t\t\t\t\trinput.test( this.type ) );\n\t\t})\n\t\t.map(function( i, elem ){\n\t\t\tvar val = jQuery( this ).val();\n\n\t\t\treturn val == null ?\n\t\t\t\tnull :\n\t\t\t\tjQuery.isArray( val ) ?\n\t\t\t\t\tjQuery.map( val, function( val, i ){\n\t\t\t\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t\t\t\t}) :\n\t\t\t\t\t{ name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t}).get();\n\t}\n});\n\n// Attach a bunch of functions for handling common AJAX events\njQuery.each( \"ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend\".split( \" \" ), function( i, o ){\n\tjQuery.fn[ o ] = function( f ){\n\t\treturn this.bind( o, f );\n\t};\n});\n\njQuery.each( [ \"get\", \"post\" ], function( i, method ) {\n\tjQuery[ method ] = function( url, data, callback, type ) {\n\t\t// shift arguments if data argument was omitted\n\t\tif ( jQuery.isFunction( data ) ) {\n\t\t\ttype = type || callback;\n\t\t\tcallback = data;\n\t\t\tdata = undefined;\n\t\t}\n\n\t\treturn jQuery.ajax({\n\t\t\ttype: method,\n\t\t\turl: url,\n\t\t\tdata: data,\n\t\t\tsuccess: callback,\n\t\t\tdataType: type\n\t\t});\n\t};\n});\n\njQuery.extend({\n\n\tgetScript: function( url, callback ) {\n\t\treturn jQuery.get( url, undefined, callback, \"script\" );\n\t},\n\n\tgetJSON: function( url, data, callback ) {\n\t\treturn jQuery.get( url, data, callback, \"json\" );\n\t},\n\n\t// Creates a full fledged settings object into target\n\t// with both ajaxSettings and settings fields.\n\t// If target is omitted, writes into ajaxSettings.\n\tajaxSetup: function( target, settings ) {\n\t\tif ( settings ) {\n\t\t\t// Building a settings object\n\t\t\tajaxExtend( target, jQuery.ajaxSettings );\n\t\t} else {\n\t\t\t// Extending ajaxSettings\n\t\t\tsettings = target;\n\t\t\ttarget = jQuery.ajaxSettings;\n\t\t}\n\t\tajaxExtend( target, settings );\n\t\treturn target;\n\t},\n\n\tajaxSettings: {\n\t\turl: ajaxLocation,\n\t\tisLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),\n\t\tglobal: true,\n\t\ttype: \"GET\",\n\t\tcontentType: \"application/x-www-form-urlencoded\",\n\t\tprocessData: true,\n\t\tasync: true,\n\t\t/*\n\t\ttimeout: 0,\n\t\tdata: null,\n\t\tdataType: null,\n\t\tusername: null,\n\t\tpassword: null,\n\t\tcache: null,\n\t\ttraditional: false,\n\t\theaders: {},\n\t\t*/\n\n\t\taccepts: {\n\t\t\txml: \"application/xml, text/xml\",\n\t\t\thtml: \"text/html\",\n\t\t\ttext: \"text/plain\",\n\t\t\tjson: \"application/json, text/javascript\",\n\t\t\t\"*\": allTypes\n\t\t},\n\n\t\tcontents: {\n\t\t\txml: /xml/,\n\t\t\thtml: /html/,\n\t\t\tjson: /json/\n\t\t},\n\n\t\tresponseFields: {\n\t\t\txml: \"responseXML\",\n\t\t\ttext: \"responseText\"\n\t\t},\n\n\t\t// List of data converters\n\t\t// 1) key format is \"source_type destination_type\" (a single space in-between)\n\t\t// 2) the catchall symbol \"*\" can be used for source_type\n\t\tconverters: {\n\n\t\t\t// Convert anything to text\n\t\t\t\"* text\": window.String,\n\n\t\t\t// Text to html (true = no transformation)\n\t\t\t\"text html\": true,\n\n\t\t\t// Evaluate text as a json expression\n\t\t\t\"text json\": jQuery.parseJSON,\n\n\t\t\t// Parse text as xml\n\t\t\t\"text xml\": jQuery.parseXML\n\t\t},\n\n\t\t// For options that shouldn't be deep extended:\n\t\t// you can add your own custom options here if\n\t\t// and when you create one that shouldn't be\n\t\t// deep extended (see ajaxExtend)\n\t\tflatOptions: {\n\t\t\tcontext: true,\n\t\t\turl: true\n\t\t}\n\t},\n\n\tajaxPrefilter: addToPrefiltersOrTransports( prefilters ),\n\tajaxTransport: addToPrefiltersOrTransports( transports ),\n\n\t// Main method\n\tajax: function( url, options ) {\n\n\t\t// If url is an object, simulate pre-1.5 signature\n\t\tif ( typeof url === \"object\" ) {\n\t\t\toptions = url;\n\t\t\turl = undefined;\n\t\t}\n\n\t\t// Force options to be an object\n\t\toptions = options || {};\n\n\t\tvar // Create the final options object\n\t\t\ts = jQuery.ajaxSetup( {}, options ),\n\t\t\t// Callbacks context\n\t\t\tcallbackContext = s.context || s,\n\t\t\t// Context for global events\n\t\t\t// It's the callbackContext if one was provided in the options\n\t\t\t// and if it's a DOM node or a jQuery collection\n\t\t\tglobalEventContext = callbackContext !== s &&\n\t\t\t\t( callbackContext.nodeType || callbackContext instanceof jQuery ) ?\n\t\t\t\t\t\tjQuery( callbackContext ) : jQuery.event,\n\t\t\t// Deferreds\n\t\t\tdeferred = jQuery.Deferred(),\n\t\t\tcompleteDeferred = jQuery._Deferred(),\n\t\t\t// Status-dependent callbacks\n\t\t\tstatusCode = s.statusCode || {},\n\t\t\t// ifModified key\n\t\t\tifModifiedKey,\n\t\t\t// Headers (they are sent all at once)\n\t\t\trequestHeaders = {},\n\t\t\trequestHeadersNames = {},\n\t\t\t// Response headers\n\t\t\tresponseHeadersString,\n\t\t\tresponseHeaders,\n\t\t\t// transport\n\t\t\ttransport,\n\t\t\t// timeout handle\n\t\t\ttimeoutTimer,\n\t\t\t// Cross-domain detection vars\n\t\t\tparts,\n\t\t\t// The jqXHR state\n\t\t\tstate = 0,\n\t\t\t// To know if global events are to be dispatched\n\t\t\tfireGlobals,\n\t\t\t// Loop variable\n\t\t\ti,\n\t\t\t// Fake xhr\n\t\t\tjqXHR = {\n\n\t\t\t\treadyState: 0,\n\n\t\t\t\t// Caches the header\n\t\t\t\tsetRequestHeader: function( name, value ) {\n\t\t\t\t\tif ( !state ) {\n\t\t\t\t\t\tvar lname = name.toLowerCase();\n\t\t\t\t\t\tname = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;\n\t\t\t\t\t\trequestHeaders[ name ] = value;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Raw string\n\t\t\t\tgetAllResponseHeaders: function() {\n\t\t\t\t\treturn state === 2 ? responseHeadersString : null;\n\t\t\t\t},\n\n\t\t\t\t// Builds headers hashtable if needed\n\t\t\t\tgetResponseHeader: function( key ) {\n\t\t\t\t\tvar match;\n\t\t\t\t\tif ( state === 2 ) {\n\t\t\t\t\t\tif ( !responseHeaders ) {\n\t\t\t\t\t\t\tresponseHeaders = {};\n\t\t\t\t\t\t\twhile( ( match = rheaders.exec( responseHeadersString ) ) ) {\n\t\t\t\t\t\t\t\tresponseHeaders[ match[1].toLowerCase() ] = match[ 2 ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmatch = responseHeaders[ key.toLowerCase() ];\n\t\t\t\t\t}\n\t\t\t\t\treturn match === undefined ? null : match;\n\t\t\t\t},\n\n\t\t\t\t// Overrides response content-type header\n\t\t\t\toverrideMimeType: function( type ) {\n\t\t\t\t\tif ( !state ) {\n\t\t\t\t\t\ts.mimeType = type;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Cancel the request\n\t\t\t\tabort: function( statusText ) {\n\t\t\t\t\tstatusText = statusText || \"abort\";\n\t\t\t\t\tif ( transport ) {\n\t\t\t\t\t\ttransport.abort( statusText );\n\t\t\t\t\t}\n\t\t\t\t\tdone( 0, statusText );\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t};\n\n\t\t// Callback for when everything is done\n\t\t// It is defined here because jslint complains if it is declared\n\t\t// at the end of the function (which would be more logical and readable)\n\t\tfunction done( status, nativeStatusText, responses, headers ) {\n\n\t\t\t// Called once\n\t\t\tif ( state === 2 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// State is \"done\" now\n\t\t\tstate = 2;\n\n\t\t\t// Clear timeout if it exists\n\t\t\tif ( timeoutTimer ) {\n\t\t\t\tclearTimeout( timeoutTimer );\n\t\t\t}\n\n\t\t\t// Dereference transport for early garbage collection\n\t\t\t// (no matter how long the jqXHR object will be used)\n\t\t\ttransport = undefined;\n\n\t\t\t// Cache response headers\n\t\t\tresponseHeadersString = headers || \"\";\n\n\t\t\t// Set readyState\n\t\t\tjqXHR.readyState = status > 0 ? 4 : 0;\n\n\t\t\tvar isSuccess,\n\t\t\t\tsuccess,\n\t\t\t\terror,\n\t\t\t\tstatusText = nativeStatusText,\n\t\t\t\tresponse = responses ? ajaxHandleResponses( s, jqXHR, responses ) : undefined,\n\t\t\t\tlastModified,\n\t\t\t\tetag;\n\n\t\t\t// If successful, handle type chaining\n\t\t\tif ( status >= 200 && status < 300 || status === 304 ) {\n\n\t\t\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\t\t\tif ( s.ifModified ) {\n\n\t\t\t\t\tif ( ( lastModified = jqXHR.getResponseHeader( \"Last-Modified\" ) ) ) {\n\t\t\t\t\t\tjQuery.lastModified[ ifModifiedKey ] = lastModified;\n\t\t\t\t\t}\n\t\t\t\t\tif ( ( etag = jqXHR.getResponseHeader( \"Etag\" ) ) ) {\n\t\t\t\t\t\tjQuery.etag[ ifModifiedKey ] = etag;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// If not modified\n\t\t\t\tif ( status === 304 ) {\n\n\t\t\t\t\tstatusText = \"notmodified\";\n\t\t\t\t\tisSuccess = true;\n\n\t\t\t\t// If we have data\n\t\t\t\t} else {\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tsuccess = ajaxConvert( s, response );\n\t\t\t\t\t\tstatusText = \"success\";\n\t\t\t\t\t\tisSuccess = true;\n\t\t\t\t\t} catch(e) {\n\t\t\t\t\t\t// We have a parsererror\n\t\t\t\t\t\tstatusText = \"parsererror\";\n\t\t\t\t\t\terror = e;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// We extract error from statusText\n\t\t\t\t// then normalize statusText and status for non-aborts\n\t\t\t\terror = statusText;\n\t\t\t\tif( !statusText || status ) {\n\t\t\t\t\tstatusText = \"error\";\n\t\t\t\t\tif ( status < 0 ) {\n\t\t\t\t\t\tstatus = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Set data for the fake xhr object\n\t\t\tjqXHR.status = status;\n\t\t\tjqXHR.statusText = \"\" + ( nativeStatusText || statusText );\n\n\t\t\t// Success/Error\n\t\t\tif ( isSuccess ) {\n\t\t\t\tdeferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );\n\t\t\t} else {\n\t\t\t\tdeferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );\n\t\t\t}\n\n\t\t\t// Status-dependent callbacks\n\t\t\tjqXHR.statusCode( statusCode );\n\t\t\tstatusCode = undefined;\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajax\" + ( isSuccess ? \"Success\" : \"Error\" ),\n\t\t\t\t\t\t[ jqXHR, s, isSuccess ? success : error ] );\n\t\t\t}\n\n\t\t\t// Complete\n\t\t\tcompleteDeferred.resolveWith( callbackContext, [ jqXHR, statusText ] );\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxComplete\", [ jqXHR, s ] );\n\t\t\t\t// Handle the global AJAX counter\n\t\t\t\tif ( !( --jQuery.active ) ) {\n\t\t\t\t\tjQuery.event.trigger( \"ajaxStop\" );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Attach deferreds\n\t\tdeferred.promise( jqXHR );\n\t\tjqXHR.success = jqXHR.done;\n\t\tjqXHR.error = jqXHR.fail;\n\t\tjqXHR.complete = completeDeferred.done;\n\n\t\t// Status-dependent callbacks\n\t\tjqXHR.statusCode = function( map ) {\n\t\t\tif ( map ) {\n\t\t\t\tvar tmp;\n\t\t\t\tif ( state < 2 ) {\n\t\t\t\t\tfor( tmp in map ) {\n\t\t\t\t\t\tstatusCode[ tmp ] = [ statusCode[tmp], map[tmp] ];\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\ttmp = map[ jqXHR.status ];\n\t\t\t\t\tjqXHR.then( tmp, tmp );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn this;\n\t\t};\n\n\t\t// Remove hash character (#7531: and string promotion)\n\t\t// Add protocol if not provided (#5866: IE7 issue with protocol-less urls)\n\t\t// We also use the url parameter if available\n\t\ts.url = ( ( url || s.url ) + \"\" ).replace( rhash, \"\" ).replace( rprotocol, ajaxLocParts[ 1 ] + \"//\" );\n\n\t\t// Extract dataTypes list\n\t\ts.dataTypes = jQuery.trim( s.dataType || \"*\" ).toLowerCase().split( rspacesAjax );\n\n\t\t// Determine if a cross-domain request is in order\n\t\tif ( s.crossDomain == null ) {\n\t\t\tparts = rurl.exec( s.url.toLowerCase() );\n\t\t\ts.crossDomain = !!( parts &&\n\t\t\t\t( parts[ 1 ] != ajaxLocParts[ 1 ] || parts[ 2 ] != ajaxLocParts[ 2 ] ||\n\t\t\t\t\t( parts[ 3 ] || ( parts[ 1 ] === \"http:\" ? 80 : 443 ) ) !=\n\t\t\t\t\t\t( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === \"http:\" ? 80 : 443 ) ) )\n\t\t\t);\n\t\t}\n\n\t\t// Convert data if not already a string\n\t\tif ( s.data && s.processData && typeof s.data !== \"string\" ) {\n\t\t\ts.data = jQuery.param( s.data, s.traditional );\n\t\t}\n\n\t\t// Apply prefilters\n\t\tinspectPrefiltersOrTransports( prefilters, s, options, jqXHR );\n\n\t\t// If request was aborted inside a prefiler, stop there\n\t\tif ( state === 2 ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// We can fire global events as of now if asked to\n\t\tfireGlobals = s.global;\n\n\t\t// Uppercase the type\n\t\ts.type = s.type.toUpperCase();\n\n\t\t// Determine if request has content\n\t\ts.hasContent = !rnoContent.test( s.type );\n\n\t\t// Watch for a new set of requests\n\t\tif ( fireGlobals && jQuery.active++ === 0 ) {\n\t\t\tjQuery.event.trigger( \"ajaxStart\" );\n\t\t}\n\n\t\t// More options handling for requests with no content\n\t\tif ( !s.hasContent ) {\n\n\t\t\t// If data is available, append data to url\n\t\t\tif ( s.data ) {\n\t\t\t\ts.url += ( rquery.test( s.url ) ? \"&\" : \"?\" ) + s.data;\n\t\t\t\t// #9682: remove data so that it's not used in an eventual retry\n\t\t\t\tdelete s.data;\n\t\t\t}\n\n\t\t\t// Get ifModifiedKey before adding the anti-cache parameter\n\t\t\tifModifiedKey = s.url;\n\n\t\t\t// Add anti-cache in url if needed\n\t\t\tif ( s.cache === false ) {\n\n\t\t\t\tvar ts = jQuery.now(),\n\t\t\t\t\t// try replacing _= if it is there\n\t\t\t\t\tret = s.url.replace( rts, \"$1_=\" + ts );\n\n\t\t\t\t// if nothing was replaced, add timestamp to the end\n\t\t\t\ts.url = ret + ( (ret === s.url ) ? ( rquery.test( s.url ) ? \"&\" : \"?\" ) + \"_=\" + ts : \"\" );\n\t\t\t}\n\t\t}\n\n\t\t// Set the correct header, if data is being sent\n\t\tif ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {\n\t\t\tjqXHR.setRequestHeader( \"Content-Type\", s.contentType );\n\t\t}\n\n\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\tif ( s.ifModified ) {\n\t\t\tifModifiedKey = ifModifiedKey || s.url;\n\t\t\tif ( jQuery.lastModified[ ifModifiedKey ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-Modified-Since\", jQuery.lastModified[ ifModifiedKey ] );\n\t\t\t}\n\t\t\tif ( jQuery.etag[ ifModifiedKey ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-None-Match\", jQuery.etag[ ifModifiedKey ] );\n\t\t\t}\n\t\t}\n\n\t\t// Set the Accepts header for the server, depending on the dataType\n\t\tjqXHR.setRequestHeader(\n\t\t\t\"Accept\",\n\t\t\ts.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?\n\t\t\t\ts.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== \"*\" ? \", \" + allTypes + \"; q=0.01\" : \"\" ) :\n\t\t\t\ts.accepts[ \"*\" ]\n\t\t);\n\n\t\t// Check for headers option\n\t\tfor ( i in s.headers ) {\n\t\t\tjqXHR.setRequestHeader( i, s.headers[ i ] );\n\t\t}\n\n\t\t// Allow custom headers/mimetypes and early abort\n\t\tif ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {\n\t\t\t\t// Abort if not done already\n\t\t\t\tjqXHR.abort();\n\t\t\t\treturn false;\n\n\t\t}\n\n\t\t// Install callbacks on deferreds\n\t\tfor ( i in { success: 1, error: 1, complete: 1 } ) {\n\t\t\tjqXHR[ i ]( s[ i ] );\n\t\t}\n\n\t\t// Get transport\n\t\ttransport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );\n\n\t\t// If no transport, we auto-abort\n\t\tif ( !transport ) {\n\t\t\tdone( -1, \"No Transport\" );\n\t\t} else {\n\t\t\tjqXHR.readyState = 1;\n\t\t\t// Send global event\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxSend\", [ jqXHR, s ] );\n\t\t\t}\n\t\t\t// Timeout\n\t\t\tif ( s.async && s.timeout > 0 ) {\n\t\t\t\ttimeoutTimer = setTimeout( function(){\n\t\t\t\t\tjqXHR.abort( \"timeout\" );\n\t\t\t\t}, s.timeout );\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tstate = 1;\n\t\t\t\ttransport.send( requestHeaders, done );\n\t\t\t} catch (e) {\n\t\t\t\t// Propagate exception as error if not done\n\t\t\t\tif ( state < 2 ) {\n\t\t\t\t\tdone( -1, e );\n\t\t\t\t// Simply rethrow otherwise\n\t\t\t\t} else {\n\t\t\t\t\tjQuery.error( e );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn jqXHR;\n\t},\n\n\t// Serialize an array of form elements or a set of\n\t// key/values into a query string\n\tparam: function( a, traditional ) {\n\t\tvar s = [],\n\t\t\tadd = function( key, value ) {\n\t\t\t\t// If value is a function, invoke it and return its value\n\t\t\t\tvalue = jQuery.isFunction( value ) ? value() : value;\n\t\t\t\ts[ s.length ] = encodeURIComponent( key ) + \"=\" + encodeURIComponent( value );\n\t\t\t};\n\n\t\t// Set traditional to true for jQuery <= 1.3.2 behavior.\n\t\tif ( traditional === undefined ) {\n\t\t\ttraditional = jQuery.ajaxSettings.traditional;\n\t\t}\n\n\t\t// If an array was passed in, assume that it is an array of form elements.\n\t\tif ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {\n\t\t\t// Serialize the form elements\n\t\t\tjQuery.each( a, function() {\n\t\t\t\tadd( this.name, this.value );\n\t\t\t});\n\n\t\t} else {\n\t\t\t// If traditional, encode the \"old\" way (the way 1.3.2 or older\n\t\t\t// did it), otherwise encode params recursively.\n\t\t\tfor ( var prefix in a ) {\n\t\t\t\tbuildParams( prefix, a[ prefix ], traditional, add );\n\t\t\t}\n\t\t}\n\n\t\t// Return the resulting serialization\n\t\treturn s.join( \"&\" ).replace( r20, \"+\" );\n\t}\n});\n\nfunction buildParams( prefix, obj, traditional, add ) {\n\tif ( jQuery.isArray( obj ) ) {\n\t\t// Serialize array item.\n\t\tjQuery.each( obj, function( i, v ) {\n\t\t\tif ( traditional || rbracket.test( prefix ) ) {\n\t\t\t\t// Treat each array item as a scalar.\n\t\t\t\tadd( prefix, v );\n\n\t\t\t} else {\n\t\t\t\t// If array item is non-scalar (array or object), encode its\n\t\t\t\t// numeric index to resolve deserialization ambiguity issues.\n\t\t\t\t// Note that rack (as of 1.0.0) can't currently deserialize\n\t\t\t\t// nested arrays properly, and attempting to do so may cause\n\t\t\t\t// a server error. Possible fixes are to modify rack's\n\t\t\t\t// deserialization algorithm or to provide an option or flag\n\t\t\t\t// to force array serialization to be shallow.\n\t\t\t\tbuildParams( prefix + \"[\" + ( typeof v === \"object\" || jQuery.isArray(v) ? i : \"\" ) + \"]\", v, traditional, add );\n\t\t\t}\n\t\t});\n\n\t} else if ( !traditional && obj != null && typeof obj === \"object\" ) {\n\t\t// Serialize object item.\n\t\tfor ( var name in obj ) {\n\t\t\tbuildParams( prefix + \"[\" + name + \"]\", obj[ name ], traditional, add );\n\t\t}\n\n\t} else {\n\t\t// Serialize scalar item.\n\t\tadd( prefix, obj );\n\t}\n}\n\n// This is still on the jQuery object... for now\n// Want to move this to jQuery.ajax some day\njQuery.extend({\n\n\t// Counter for holding the number of active queries\n\tactive: 0,\n\n\t// Last-Modified header cache for next request\n\tlastModified: {},\n\tetag: {}\n\n});\n\n/* Handles responses to an ajax request:\n * - sets all responseXXX fields accordingly\n * - finds the right dataType (mediates between content-type and expected dataType)\n * - returns the corresponding response\n */\nfunction ajaxHandleResponses( s, jqXHR, responses ) {\n\n\tvar contents = s.contents,\n\t\tdataTypes = s.dataTypes,\n\t\tresponseFields = s.responseFields,\n\t\tct,\n\t\ttype,\n\t\tfinalDataType,\n\t\tfirstDataType;\n\n\t// Fill responseXXX fields\n\tfor( type in responseFields ) {\n\t\tif ( type in responses ) {\n\t\t\tjqXHR[ responseFields[type] ] = responses[ type ];\n\t\t}\n\t}\n\n\t// Remove auto dataType and get content-type in the process\n\twhile( dataTypes[ 0 ] === \"*\" ) {\n\t\tdataTypes.shift();\n\t\tif ( ct === undefined ) {\n\t\t\tct = s.mimeType || jqXHR.getResponseHeader( \"content-type\" );\n\t\t}\n\t}\n\n\t// Check if we're dealing with a known content-type\n\tif ( ct ) {\n\t\tfor ( type in contents ) {\n\t\t\tif ( contents[ type ] && contents[ type ].test( ct ) ) {\n\t\t\t\tdataTypes.unshift( type );\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check to see if we have a response for the expected dataType\n\tif ( dataTypes[ 0 ] in responses ) {\n\t\tfinalDataType = dataTypes[ 0 ];\n\t} else {\n\t\t// Try convertible dataTypes\n\t\tfor ( type in responses ) {\n\t\t\tif ( !dataTypes[ 0 ] || s.converters[ type + \" \" + dataTypes[0] ] ) {\n\t\t\t\tfinalDataType = type;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( !firstDataType ) {\n\t\t\t\tfirstDataType = type;\n\t\t\t}\n\t\t}\n\t\t// Or just use first one\n\t\tfinalDataType = finalDataType || firstDataType;\n\t}\n\n\t// If we found a dataType\n\t// We add the dataType to the list if needed\n\t// and return the corresponding response\n\tif ( finalDataType ) {\n\t\tif ( finalDataType !== dataTypes[ 0 ] ) {\n\t\t\tdataTypes.unshift( finalDataType );\n\t\t}\n\t\treturn responses[ finalDataType ];\n\t}\n}\n\n// Chain conversions given the request and the original response\nfunction ajaxConvert( s, response ) {\n\n\t// Apply the dataFilter if provided\n\tif ( s.dataFilter ) {\n\t\tresponse = s.dataFilter( response, s.dataType );\n\t}\n\n\tvar dataTypes = s.dataTypes,\n\t\tconverters = {},\n\t\ti,\n\t\tkey,\n\t\tlength = dataTypes.length,\n\t\ttmp,\n\t\t// Current and previous dataTypes\n\t\tcurrent = dataTypes[ 0 ],\n\t\tprev,\n\t\t// Conversion expression\n\t\tconversion,\n\t\t// Conversion function\n\t\tconv,\n\t\t// Conversion functions (transitive conversion)\n\t\tconv1,\n\t\tconv2;\n\n\t// For each dataType in the chain\n\tfor( i = 1; i < length; i++ ) {\n\n\t\t// Create converters map\n\t\t// with lowercased keys\n\t\tif ( i === 1 ) {\n\t\t\tfor( key in s.converters ) {\n\t\t\t\tif( typeof key === \"string\" ) {\n\t\t\t\t\tconverters[ key.toLowerCase() ] = s.converters[ key ];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Get the dataTypes\n\t\tprev = current;\n\t\tcurrent = dataTypes[ i ];\n\n\t\t// If current is auto dataType, update it to prev\n\t\tif( current === \"*\" ) {\n\t\t\tcurrent = prev;\n\t\t// If no auto and dataTypes are actually different\n\t\t} else if ( prev !== \"*\" && prev !== current ) {\n\n\t\t\t// Get the converter\n\t\t\tconversion = prev + \" \" + current;\n\t\t\tconv = converters[ conversion ] || converters[ \"* \" + current ];\n\n\t\t\t// If there is no direct converter, search transitively\n\t\t\tif ( !conv ) {\n\t\t\t\tconv2 = undefined;\n\t\t\t\tfor( conv1 in converters ) {\n\t\t\t\t\ttmp = conv1.split( \" \" );\n\t\t\t\t\tif ( tmp[ 0 ] === prev || tmp[ 0 ] === \"*\" ) {\n\t\t\t\t\t\tconv2 = converters[ tmp[1] + \" \" + current ];\n\t\t\t\t\t\tif ( conv2 ) {\n\t\t\t\t\t\t\tconv1 = converters[ conv1 ];\n\t\t\t\t\t\t\tif ( conv1 === true ) {\n\t\t\t\t\t\t\t\tconv = conv2;\n\t\t\t\t\t\t\t} else if ( conv2 === true ) {\n\t\t\t\t\t\t\t\tconv = conv1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// If we found no converter, dispatch an error\n\t\t\tif ( !( conv || conv2 ) ) {\n\t\t\t\tjQuery.error( \"No conversion from \" + conversion.replace(\" \",\" to \") );\n\t\t\t}\n\t\t\t// If found converter is not an equivalence\n\t\t\tif ( conv !== true ) {\n\t\t\t\t// Convert with 1 or 2 converters accordingly\n\t\t\t\tresponse = conv ? conv( response ) : conv2( conv1(response) );\n\t\t\t}\n\t\t}\n\t}\n\treturn response;\n}\n\n\n\n\nvar jsc = jQuery.now(),\n\tjsre = /(\\=)\\?(&|$)|\\?\\?/i;\n\n// Default jsonp settings\njQuery.ajaxSetup({\n\tjsonp: \"callback\",\n\tjsonpCallback: function() {\n\t\treturn jQuery.expando + \"_\" + ( jsc++ );\n\t}\n});\n\n// Detect, normalize options and install callbacks for jsonp requests\njQuery.ajaxPrefilter( \"json jsonp\", function( s, originalSettings, jqXHR ) {\n\n\tvar inspectData = s.contentType === \"application/x-www-form-urlencoded\" &&\n\t\t( typeof s.data === \"string\" );\n\n\tif ( s.dataTypes[ 0 ] === \"jsonp\" ||\n\t\ts.jsonp !== false && ( jsre.test( s.url ) ||\n\t\t\t\tinspectData && jsre.test( s.data ) ) ) {\n\n\t\tvar responseContainer,\n\t\t\tjsonpCallback = s.jsonpCallback =\n\t\t\t\tjQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback,\n\t\t\tprevious = window[ jsonpCallback ],\n\t\t\turl = s.url,\n\t\t\tdata = s.data,\n\t\t\treplace = \"$1\" + jsonpCallback + \"$2\";\n\n\t\tif ( s.jsonp !== false ) {\n\t\t\turl = url.replace( jsre, replace );\n\t\t\tif ( s.url === url ) {\n\t\t\t\tif ( inspectData ) {\n\t\t\t\t\tdata = data.replace( jsre, replace );\n\t\t\t\t}\n\t\t\t\tif ( s.data === data ) {\n\t\t\t\t\t// Add callback manually\n\t\t\t\t\turl += (/\\?/.test( url ) ? \"&\" : \"?\") + s.jsonp + \"=\" + jsonpCallback;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\ts.url = url;\n\t\ts.data = data;\n\n\t\t// Install callback\n\t\twindow[ jsonpCallback ] = function( response ) {\n\t\t\tresponseContainer = [ response ];\n\t\t};\n\n\t\t// Clean-up function\n\t\tjqXHR.always(function() {\n\t\t\t// Set callback back to previous value\n\t\t\twindow[ jsonpCallback ] = previous;\n\t\t\t// Call if it was a function and we have a response\n\t\t\tif ( responseContainer && jQuery.isFunction( previous ) ) {\n\t\t\t\twindow[ jsonpCallback ]( responseContainer[ 0 ] );\n\t\t\t}\n\t\t});\n\n\t\t// Use data converter to retrieve json after script execution\n\t\ts.converters[\"script json\"] = function() {\n\t\t\tif ( !responseContainer ) {\n\t\t\t\tjQuery.error( jsonpCallback + \" was not called\" );\n\t\t\t}\n\t\t\treturn responseContainer[ 0 ];\n\t\t};\n\n\t\t// force json dataType\n\t\ts.dataTypes[ 0 ] = \"json\";\n\n\t\t// Delegate to script\n\t\treturn \"script\";\n\t}\n});\n\n\n\n\n// Install script dataType\njQuery.ajaxSetup({\n\taccepts: {\n\t\tscript: \"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript\"\n\t},\n\tcontents: {\n\t\tscript: /javascript|ecmascript/\n\t},\n\tconverters: {\n\t\t\"text script\": function( text ) {\n\t\t\tjQuery.globalEval( text );\n\t\t\treturn text;\n\t\t}\n\t}\n});\n\n// Handle cache's special case and global\njQuery.ajaxPrefilter( \"script\", function( s ) {\n\tif ( s.cache === undefined ) {\n\t\ts.cache = false;\n\t}\n\tif ( s.crossDomain ) {\n\t\ts.type = \"GET\";\n\t\ts.global = false;\n\t}\n});\n\n// Bind script tag hack transport\njQuery.ajaxTransport( \"script\", function(s) {\n\n\t// This transport only deals with cross domain requests\n\tif ( s.crossDomain ) {\n\n\t\tvar script,\n\t\t\thead = document.head || document.getElementsByTagName( \"head\" )[0] || document.documentElement;\n\n\t\treturn {\n\n\t\t\tsend: function( _, callback ) {\n\n\t\t\t\tscript = document.createElement( \"script\" );\n\n\t\t\t\tscript.async = \"async\";\n\n\t\t\t\tif ( s.scriptCharset ) {\n\t\t\t\t\tscript.charset = s.scriptCharset;\n\t\t\t\t}\n\n\t\t\t\tscript.src = s.url;\n\n\t\t\t\t// Attach handlers for all browsers\n\t\t\t\tscript.onload = script.onreadystatechange = function( _, isAbort ) {\n\n\t\t\t\t\tif ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {\n\n\t\t\t\t\t\t// Handle memory leak in IE\n\t\t\t\t\t\tscript.onload = script.onreadystatechange = null;\n\n\t\t\t\t\t\t// Remove the script\n\t\t\t\t\t\tif ( head && script.parentNode ) {\n\t\t\t\t\t\t\thead.removeChild( script );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Dereference the script\n\t\t\t\t\t\tscript = undefined;\n\n\t\t\t\t\t\t// Callback if not abort\n\t\t\t\t\t\tif ( !isAbort ) {\n\t\t\t\t\t\t\tcallback( 200, \"success\" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\t// Use insertBefore instead of appendChild  to circumvent an IE6 bug.\n\t\t\t\t// This arises when a base node is used (#2709 and #4378).\n\t\t\t\thead.insertBefore( script, head.firstChild );\n\t\t\t},\n\n\t\t\tabort: function() {\n\t\t\t\tif ( script ) {\n\t\t\t\t\tscript.onload( 0, 1 );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n});\n\n\n\n\nvar // #5280: Internet Explorer will keep connections alive if we don't abort on unload\n\txhrOnUnloadAbort = window.ActiveXObject ? function() {\n\t\t// Abort all pending requests\n\t\tfor ( var key in xhrCallbacks ) {\n\t\t\txhrCallbacks[ key ]( 0, 1 );\n\t\t}\n\t} : false,\n\txhrId = 0,\n\txhrCallbacks;\n\n// Functions to create xhrs\nfunction createStandardXHR() {\n\ttry {\n\t\treturn new window.XMLHttpRequest();\n\t} catch( e ) {}\n}\n\nfunction createActiveXHR() {\n\ttry {\n\t\treturn new window.ActiveXObject( \"Microsoft.XMLHTTP\" );\n\t} catch( e ) {}\n}\n\n// Create the request object\n// (This is still attached to ajaxSettings for backward compatibility)\njQuery.ajaxSettings.xhr = window.ActiveXObject ?\n\t/* Microsoft failed to properly\n\t * implement the XMLHttpRequest in IE7 (can't request local files),\n\t * so we use the ActiveXObject when it is available\n\t * Additionally XMLHttpRequest can be disabled in IE7/IE8 so\n\t * we need a fallback.\n\t */\n\tfunction() {\n\t\treturn !this.isLocal && createStandardXHR() || createActiveXHR();\n\t} :\n\t// For all other browsers, use the standard XMLHttpRequest object\n\tcreateStandardXHR;\n\n// Determine support properties\n(function( xhr ) {\n\tjQuery.extend( jQuery.support, {\n\t\tajax: !!xhr,\n\t\tcors: !!xhr && ( \"withCredentials\" in xhr )\n\t});\n})( jQuery.ajaxSettings.xhr() );\n\n// Create transport if the browser can provide an xhr\nif ( jQuery.support.ajax ) {\n\n\tjQuery.ajaxTransport(function( s ) {\n\t\t// Cross domain only allowed if supported through XMLHttpRequest\n\t\tif ( !s.crossDomain || jQuery.support.cors ) {\n\n\t\t\tvar callback;\n\n\t\t\treturn {\n\t\t\t\tsend: function( headers, complete ) {\n\n\t\t\t\t\t// Get a new xhr\n\t\t\t\t\tvar xhr = s.xhr(),\n\t\t\t\t\t\thandle,\n\t\t\t\t\t\ti;\n\n\t\t\t\t\t// Open the socket\n\t\t\t\t\t// Passing null username, generates a login popup on Opera (#2865)\n\t\t\t\t\tif ( s.username ) {\n\t\t\t\t\t\txhr.open( s.type, s.url, s.async, s.username, s.password );\n\t\t\t\t\t} else {\n\t\t\t\t\t\txhr.open( s.type, s.url, s.async );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Apply custom fields if provided\n\t\t\t\t\tif ( s.xhrFields ) {\n\t\t\t\t\t\tfor ( i in s.xhrFields ) {\n\t\t\t\t\t\t\txhr[ i ] = s.xhrFields[ i ];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Override mime type if needed\n\t\t\t\t\tif ( s.mimeType && xhr.overrideMimeType ) {\n\t\t\t\t\t\txhr.overrideMimeType( s.mimeType );\n\t\t\t\t\t}\n\n\t\t\t\t\t// X-Requested-With header\n\t\t\t\t\t// For cross-domain requests, seeing as conditions for a preflight are\n\t\t\t\t\t// akin to a jigsaw puzzle, we simply never set it to be sure.\n\t\t\t\t\t// (it can always be set on a per-request basis or even using ajaxSetup)\n\t\t\t\t\t// For same-domain requests, won't change header if already provided.\n\t\t\t\t\tif ( !s.crossDomain && !headers[\"X-Requested-With\"] ) {\n\t\t\t\t\t\theaders[ \"X-Requested-With\" ] = \"XMLHttpRequest\";\n\t\t\t\t\t}\n\n\t\t\t\t\t// Need an extra try/catch for cross domain requests in Firefox 3\n\t\t\t\t\ttry {\n\t\t\t\t\t\tfor ( i in headers ) {\n\t\t\t\t\t\t\txhr.setRequestHeader( i, headers[ i ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch( _ ) {}\n\n\t\t\t\t\t// Do send the request\n\t\t\t\t\t// This may raise an exception which is actually\n\t\t\t\t\t// handled in jQuery.ajax (so no try/catch here)\n\t\t\t\t\txhr.send( ( s.hasContent && s.data ) || null );\n\n\t\t\t\t\t// Listener\n\t\t\t\t\tcallback = function( _, isAbort ) {\n\n\t\t\t\t\t\tvar status,\n\t\t\t\t\t\t\tstatusText,\n\t\t\t\t\t\t\tresponseHeaders,\n\t\t\t\t\t\t\tresponses,\n\t\t\t\t\t\t\txml;\n\n\t\t\t\t\t\t// Firefox throws exceptions when accessing properties\n\t\t\t\t\t\t// of an xhr when a network error occured\n\t\t\t\t\t\t// http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)\n\t\t\t\t\t\ttry {\n\n\t\t\t\t\t\t\t// Was never called and is aborted or complete\n\t\t\t\t\t\t\tif ( callback && ( isAbort || xhr.readyState === 4 ) ) {\n\n\t\t\t\t\t\t\t\t// Only called once\n\t\t\t\t\t\t\t\tcallback = undefined;\n\n\t\t\t\t\t\t\t\t// Do not keep as active anymore\n\t\t\t\t\t\t\t\tif ( handle ) {\n\t\t\t\t\t\t\t\t\txhr.onreadystatechange = jQuery.noop;\n\t\t\t\t\t\t\t\t\tif ( xhrOnUnloadAbort ) {\n\t\t\t\t\t\t\t\t\t\tdelete xhrCallbacks[ handle ];\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// If it's an abort\n\t\t\t\t\t\t\t\tif ( isAbort ) {\n\t\t\t\t\t\t\t\t\t// Abort it manually if needed\n\t\t\t\t\t\t\t\t\tif ( xhr.readyState !== 4 ) {\n\t\t\t\t\t\t\t\t\t\txhr.abort();\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tstatus = xhr.status;\n\t\t\t\t\t\t\t\t\tresponseHeaders = xhr.getAllResponseHeaders();\n\t\t\t\t\t\t\t\t\tresponses = {};\n\t\t\t\t\t\t\t\t\txml = xhr.responseXML;\n\n\t\t\t\t\t\t\t\t\t// Construct response list\n\t\t\t\t\t\t\t\t\tif ( xml && xml.documentElement /* #4958 */ ) {\n\t\t\t\t\t\t\t\t\t\tresponses.xml = xml;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tresponses.text = xhr.responseText;\n\n\t\t\t\t\t\t\t\t\t// Firefox throws an exception when accessing\n\t\t\t\t\t\t\t\t\t// statusText for faulty cross-domain requests\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\tstatusText = xhr.statusText;\n\t\t\t\t\t\t\t\t\t} catch( e ) {\n\t\t\t\t\t\t\t\t\t\t// We normalize with Webkit giving an empty statusText\n\t\t\t\t\t\t\t\t\t\tstatusText = \"\";\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Filter status for non standard behaviors\n\n\t\t\t\t\t\t\t\t\t// If the request is local and we have data: assume a success\n\t\t\t\t\t\t\t\t\t// (success with no data won't get notified, that's the best we\n\t\t\t\t\t\t\t\t\t// can do given current implementations)\n\t\t\t\t\t\t\t\t\tif ( !status && s.isLocal && !s.crossDomain ) {\n\t\t\t\t\t\t\t\t\t\tstatus = responses.text ? 200 : 404;\n\t\t\t\t\t\t\t\t\t// IE - #1450: sometimes returns 1223 when it should be 204\n\t\t\t\t\t\t\t\t\t} else if ( status === 1223 ) {\n\t\t\t\t\t\t\t\t\t\tstatus = 204;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} catch( firefoxAccessException ) {\n\t\t\t\t\t\t\tif ( !isAbort ) {\n\t\t\t\t\t\t\t\tcomplete( -1, firefoxAccessException );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Call complete if needed\n\t\t\t\t\t\tif ( responses ) {\n\t\t\t\t\t\t\tcomplete( status, statusText, responses, responseHeaders );\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\n\t\t\t\t\t// if we're in sync mode or it's in cache\n\t\t\t\t\t// and has been retrieved directly (IE6 & IE7)\n\t\t\t\t\t// we need to manually fire the callback\n\t\t\t\t\tif ( !s.async || xhr.readyState === 4 ) {\n\t\t\t\t\t\tcallback();\n\t\t\t\t\t} else {\n\t\t\t\t\t\thandle = ++xhrId;\n\t\t\t\t\t\tif ( xhrOnUnloadAbort ) {\n\t\t\t\t\t\t\t// Create the active xhrs callbacks list if needed\n\t\t\t\t\t\t\t// and attach the unload handler\n\t\t\t\t\t\t\tif ( !xhrCallbacks ) {\n\t\t\t\t\t\t\t\txhrCallbacks = {};\n\t\t\t\t\t\t\t\tjQuery( window ).unload( xhrOnUnloadAbort );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// Add to list of active xhrs callbacks\n\t\t\t\t\t\t\txhrCallbacks[ handle ] = callback;\n\t\t\t\t\t\t}\n\t\t\t\t\t\txhr.onreadystatechange = callback;\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\t\tabort: function() {\n\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\tcallback(0,1);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t});\n}\n\n\n\n\nvar elemdisplay = {},\n\tiframe, iframeDoc,\n\trfxtypes = /^(?:toggle|show|hide)$/,\n\trfxnum = /^([+\\-]=)?([\\d+.\\-]+)([a-z%]*)$/i,\n\ttimerId,\n\tfxAttrs = [\n\t\t// height animations\n\t\t[ \"height\", \"marginTop\", \"marginBottom\", \"paddingTop\", \"paddingBottom\" ],\n\t\t// width animations\n\t\t[ \"width\", \"marginLeft\", \"marginRight\", \"paddingLeft\", \"paddingRight\" ],\n\t\t// opacity animations\n\t\t[ \"opacity\" ]\n\t],\n\tfxNow;\n\njQuery.fn.extend({\n\tshow: function( speed, easing, callback ) {\n\t\tvar elem, display;\n\n\t\tif ( speed || speed === 0 ) {\n\t\t\treturn this.animate( genFx(\"show\", 3), speed, easing, callback);\n\n\t\t} else {\n\t\t\tfor ( var i = 0, j = this.length; i < j; i++ ) {\n\t\t\t\telem = this[i];\n\n\t\t\t\tif ( elem.style ) {\n\t\t\t\t\tdisplay = elem.style.display;\n\n\t\t\t\t\t// Reset the inline display of this element to learn if it is\n\t\t\t\t\t// being hidden by cascaded rules or not\n\t\t\t\t\tif ( !jQuery._data(elem, \"olddisplay\") && display === \"none\" ) {\n\t\t\t\t\t\tdisplay = elem.style.display = \"\";\n\t\t\t\t\t}\n\n\t\t\t\t\t// Set elements which have been overridden with display: none\n\t\t\t\t\t// in a stylesheet to whatever the default browser style is\n\t\t\t\t\t// for such an element\n\t\t\t\t\tif ( display === \"\" && jQuery.css( elem, \"display\" ) === \"none\" ) {\n\t\t\t\t\t\tjQuery._data(elem, \"olddisplay\", defaultDisplay(elem.nodeName));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Set the display of most of the elements in a second loop\n\t\t\t// to avoid the constant reflow\n\t\t\tfor ( i = 0; i < j; i++ ) {\n\t\t\t\telem = this[i];\n\n\t\t\t\tif ( elem.style ) {\n\t\t\t\t\tdisplay = elem.style.display;\n\n\t\t\t\t\tif ( display === \"\" || display === \"none\" ) {\n\t\t\t\t\t\telem.style.display = jQuery._data(elem, \"olddisplay\") || \"\";\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn this;\n\t\t}\n\t},\n\n\thide: function( speed, easing, callback ) {\n\t\tif ( speed || speed === 0 ) {\n\t\t\treturn this.animate( genFx(\"hide\", 3), speed, easing, callback);\n\n\t\t} else {\n\t\t\tfor ( var i = 0, j = this.length; i < j; i++ ) {\n\t\t\t\tif ( this[i].style ) {\n\t\t\t\t\tvar display = jQuery.css( this[i], \"display\" );\n\n\t\t\t\t\tif ( display !== \"none\" && !jQuery._data( this[i], \"olddisplay\" ) ) {\n\t\t\t\t\t\tjQuery._data( this[i], \"olddisplay\", display );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Set the display of the elements in a second loop\n\t\t\t// to avoid the constant reflow\n\t\t\tfor ( i = 0; i < j; i++ ) {\n\t\t\t\tif ( this[i].style ) {\n\t\t\t\t\tthis[i].style.display = \"none\";\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn this;\n\t\t}\n\t},\n\n\t// Save the old toggle function\n\t_toggle: jQuery.fn.toggle,\n\n\ttoggle: function( fn, fn2, callback ) {\n\t\tvar bool = typeof fn === \"boolean\";\n\n\t\tif ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {\n\t\t\tthis._toggle.apply( this, arguments );\n\n\t\t} else if ( fn == null || bool ) {\n\t\t\tthis.each(function() {\n\t\t\t\tvar state = bool ? fn : jQuery(this).is(\":hidden\");\n\t\t\t\tjQuery(this)[ state ? \"show\" : \"hide\" ]();\n\t\t\t});\n\n\t\t} else {\n\t\t\tthis.animate(genFx(\"toggle\", 3), fn, fn2, callback);\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tfadeTo: function( speed, to, easing, callback ) {\n\t\treturn this.filter(\":hidden\").css(\"opacity\", 0).show().end()\n\t\t\t\t\t.animate({opacity: to}, speed, easing, callback);\n\t},\n\n\tanimate: function( prop, speed, easing, callback ) {\n\t\tvar optall = jQuery.speed(speed, easing, callback);\n\n\t\tif ( jQuery.isEmptyObject( prop ) ) {\n\t\t\treturn this.each( optall.complete, [ false ] );\n\t\t}\n\n\t\t// Do not change referenced properties as per-property easing will be lost\n\t\tprop = jQuery.extend( {}, prop );\n\n\t\treturn this[ optall.queue === false ? \"each\" : \"queue\" ](function() {\n\t\t\t// XXX 'this' does not always have a nodeName when running the\n\t\t\t// test suite\n\n\t\t\tif ( optall.queue === false ) {\n\t\t\t\tjQuery._mark( this );\n\t\t\t}\n\n\t\t\tvar opt = jQuery.extend( {}, optall ),\n\t\t\t\tisElement = this.nodeType === 1,\n\t\t\t\thidden = isElement && jQuery(this).is(\":hidden\"),\n\t\t\t\tname, val, p,\n\t\t\t\tdisplay, e,\n\t\t\t\tparts, start, end, unit;\n\n\t\t\t// will store per property easing and be used to determine when an animation is complete\n\t\t\topt.animatedProperties = {};\n\n\t\t\tfor ( p in prop ) {\n\n\t\t\t\t// property name normalization\n\t\t\t\tname = jQuery.camelCase( p );\n\t\t\t\tif ( p !== name ) {\n\t\t\t\t\tprop[ name ] = prop[ p ];\n\t\t\t\t\tdelete prop[ p ];\n\t\t\t\t}\n\n\t\t\t\tval = prop[ name ];\n\n\t\t\t\t// easing resolution: per property > opt.specialEasing > opt.easing > 'swing' (default)\n\t\t\t\tif ( jQuery.isArray( val ) ) {\n\t\t\t\t\topt.animatedProperties[ name ] = val[ 1 ];\n\t\t\t\t\tval = prop[ name ] = val[ 0 ];\n\t\t\t\t} else {\n\t\t\t\t\topt.animatedProperties[ name ] = opt.specialEasing && opt.specialEasing[ name ] || opt.easing || 'swing';\n\t\t\t\t}\n\n\t\t\t\tif ( val === \"hide\" && hidden || val === \"show\" && !hidden ) {\n\t\t\t\t\treturn opt.complete.call( this );\n\t\t\t\t}\n\n\t\t\t\tif ( isElement && ( name === \"height\" || name === \"width\" ) ) {\n\t\t\t\t\t// Make sure that nothing sneaks out\n\t\t\t\t\t// Record all 3 overflow attributes because IE does not\n\t\t\t\t\t// change the overflow attribute when overflowX and\n\t\t\t\t\t// overflowY are set to the same value\n\t\t\t\t\topt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ];\n\n\t\t\t\t\t// Set display property to inline-block for height/width\n\t\t\t\t\t// animations on inline elements that are having width/height\n\t\t\t\t\t// animated\n\t\t\t\t\tif ( jQuery.css( this, \"display\" ) === \"inline\" &&\n\t\t\t\t\t\t\tjQuery.css( this, \"float\" ) === \"none\" ) {\n\t\t\t\t\t\tif ( !jQuery.support.inlineBlockNeedsLayout ) {\n\t\t\t\t\t\t\tthis.style.display = \"inline-block\";\n\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tdisplay = defaultDisplay( this.nodeName );\n\n\t\t\t\t\t\t\t// inline-level elements accept inline-block;\n\t\t\t\t\t\t\t// block-level elements need to be inline with layout\n\t\t\t\t\t\t\tif ( display === \"inline\" ) {\n\t\t\t\t\t\t\t\tthis.style.display = \"inline-block\";\n\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.style.display = \"inline\";\n\t\t\t\t\t\t\t\tthis.style.zoom = 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( opt.overflow != null ) {\n\t\t\t\tthis.style.overflow = \"hidden\";\n\t\t\t}\n\n\t\t\tfor ( p in prop ) {\n\t\t\t\te = new jQuery.fx( this, opt, p );\n\t\t\t\tval = prop[ p ];\n\n\t\t\t\tif ( rfxtypes.test(val) ) {\n\t\t\t\t\te[ val === \"toggle\" ? hidden ? \"show\" : \"hide\" : val ]();\n\n\t\t\t\t} else {\n\t\t\t\t\tparts = rfxnum.exec( val );\n\t\t\t\t\tstart = e.cur();\n\n\t\t\t\t\tif ( parts ) {\n\t\t\t\t\t\tend = parseFloat( parts[2] );\n\t\t\t\t\t\tunit = parts[3] || ( jQuery.cssNumber[ p ] ? \"\" : \"px\" );\n\n\t\t\t\t\t\t// We need to compute starting value\n\t\t\t\t\t\tif ( unit !== \"px\" ) {\n\t\t\t\t\t\t\tjQuery.style( this, p, (end || 1) + unit);\n\t\t\t\t\t\t\tstart = ((end || 1) / e.cur()) * start;\n\t\t\t\t\t\t\tjQuery.style( this, p, start + unit);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// If a +=/-= token was provided, we're doing a relative animation\n\t\t\t\t\t\tif ( parts[1] ) {\n\t\t\t\t\t\t\tend = ( (parts[ 1 ] === \"-=\" ? -1 : 1) * end ) + start;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\te.custom( start, end, unit );\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\te.custom( start, val, \"\" );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// For JS strict compliance\n\t\t\treturn true;\n\t\t});\n\t},\n\n\tstop: function( clearQueue, gotoEnd ) {\n\t\tif ( clearQueue ) {\n\t\t\tthis.queue([]);\n\t\t}\n\n\t\tthis.each(function() {\n\t\t\tvar timers = jQuery.timers,\n\t\t\t\ti = timers.length;\n\t\t\t// clear marker counters if we know they won't be\n\t\t\tif ( !gotoEnd ) {\n\t\t\t\tjQuery._unmark( true, this );\n\t\t\t}\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( timers[i].elem === this ) {\n\t\t\t\t\tif (gotoEnd) {\n\t\t\t\t\t\t// force the next step to be the last\n\t\t\t\t\t\ttimers[i](true);\n\t\t\t\t\t}\n\n\t\t\t\t\ttimers.splice(i, 1);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\t// start the next in the queue if the last step wasn't forced\n\t\tif ( !gotoEnd ) {\n\t\t\tthis.dequeue();\n\t\t}\n\n\t\treturn this;\n\t}\n\n});\n\n// Animations created synchronously will run synchronously\nfunction createFxNow() {\n\tsetTimeout( clearFxNow, 0 );\n\treturn ( fxNow = jQuery.now() );\n}\n\nfunction clearFxNow() {\n\tfxNow = undefined;\n}\n\n// Generate parameters to create a standard animation\nfunction genFx( type, num ) {\n\tvar obj = {};\n\n\tjQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() {\n\t\tobj[ this ] = type;\n\t});\n\n\treturn obj;\n}\n\n// Generate shortcuts for custom animations\njQuery.each({\n\tslideDown: genFx(\"show\", 1),\n\tslideUp: genFx(\"hide\", 1),\n\tslideToggle: genFx(\"toggle\", 1),\n\tfadeIn: { opacity: \"show\" },\n\tfadeOut: { opacity: \"hide\" },\n\tfadeToggle: { opacity: \"toggle\" }\n}, function( name, props ) {\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn this.animate( props, speed, easing, callback );\n\t};\n});\n\njQuery.extend({\n\tspeed: function( speed, easing, fn ) {\n\t\tvar opt = speed && typeof speed === \"object\" ? jQuery.extend({}, speed) : {\n\t\t\tcomplete: fn || !fn && easing ||\n\t\t\t\tjQuery.isFunction( speed ) && speed,\n\t\t\tduration: speed,\n\t\t\teasing: fn && easing || easing && !jQuery.isFunction(easing) && easing\n\t\t};\n\n\t\topt.duration = jQuery.fx.off ? 0 : typeof opt.duration === \"number\" ? opt.duration :\n\t\t\topt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default;\n\n\t\t// Queueing\n\t\topt.old = opt.complete;\n\t\topt.complete = function( noUnmark ) {\n\t\t\tif ( jQuery.isFunction( opt.old ) ) {\n\t\t\t\topt.old.call( this );\n\t\t\t}\n\n\t\t\tif ( opt.queue !== false ) {\n\t\t\t\tjQuery.dequeue( this );\n\t\t\t} else if ( noUnmark !== false ) {\n\t\t\t\tjQuery._unmark( this );\n\t\t\t}\n\t\t};\n\n\t\treturn opt;\n\t},\n\n\teasing: {\n\t\tlinear: function( p, n, firstNum, diff ) {\n\t\t\treturn firstNum + diff * p;\n\t\t},\n\t\tswing: function( p, n, firstNum, diff ) {\n\t\t\treturn ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;\n\t\t}\n\t},\n\n\ttimers: [],\n\n\tfx: function( elem, options, prop ) {\n\t\tthis.options = options;\n\t\tthis.elem = elem;\n\t\tthis.prop = prop;\n\n\t\toptions.orig = options.orig || {};\n\t}\n\n});\n\njQuery.fx.prototype = {\n\t// Simple function for setting a style value\n\tupdate: function() {\n\t\tif ( this.options.step ) {\n\t\t\tthis.options.step.call( this.elem, this.now, this );\n\t\t}\n\n\t\t(jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );\n\t},\n\n\t// Get the current size\n\tcur: function() {\n\t\tif ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {\n\t\t\treturn this.elem[ this.prop ];\n\t\t}\n\n\t\tvar parsed,\n\t\t\tr = jQuery.css( this.elem, this.prop );\n\t\t// Empty strings, null, undefined and \"auto\" are converted to 0,\n\t\t// complex values such as \"rotate(1rad)\" are returned as is,\n\t\t// simple values such as \"10px\" are parsed to Float.\n\t\treturn isNaN( parsed = parseFloat( r ) ) ? !r || r === \"auto\" ? 0 : r : parsed;\n\t},\n\n\t// Start an animation from one number to another\n\tcustom: function( from, to, unit ) {\n\t\tvar self = this,\n\t\t\tfx = jQuery.fx;\n\n\t\tthis.startTime = fxNow || createFxNow();\n\t\tthis.start = from;\n\t\tthis.end = to;\n\t\tthis.unit = unit || this.unit || ( jQuery.cssNumber[ this.prop ] ? \"\" : \"px\" );\n\t\tthis.now = this.start;\n\t\tthis.pos = this.state = 0;\n\n\t\tfunction t( gotoEnd ) {\n\t\t\treturn self.step(gotoEnd);\n\t\t}\n\n\t\tt.elem = this.elem;\n\n\t\tif ( t() && jQuery.timers.push(t) && !timerId ) {\n\t\t\ttimerId = setInterval( fx.tick, fx.interval );\n\t\t}\n\t},\n\n\t// Simple 'show' function\n\tshow: function() {\n\t\t// Remember where we started, so that we can go back to it later\n\t\tthis.options.orig[this.prop] = jQuery.style( this.elem, this.prop );\n\t\tthis.options.show = true;\n\n\t\t// Begin the animation\n\t\t// Make sure that we start at a small width/height to avoid any\n\t\t// flash of content\n\t\tthis.custom(this.prop === \"width\" || this.prop === \"height\" ? 1 : 0, this.cur());\n\n\t\t// Start by showing the element\n\t\tjQuery( this.elem ).show();\n\t},\n\n\t// Simple 'hide' function\n\thide: function() {\n\t\t// Remember where we started, so that we can go back to it later\n\t\tthis.options.orig[this.prop] = jQuery.style( this.elem, this.prop );\n\t\tthis.options.hide = true;\n\n\t\t// Begin the animation\n\t\tthis.custom(this.cur(), 0);\n\t},\n\n\t// Each step of an animation\n\tstep: function( gotoEnd ) {\n\t\tvar t = fxNow || createFxNow(),\n\t\t\tdone = true,\n\t\t\telem = this.elem,\n\t\t\toptions = this.options,\n\t\t\ti, n;\n\n\t\tif ( gotoEnd || t >= options.duration + this.startTime ) {\n\t\t\tthis.now = this.end;\n\t\t\tthis.pos = this.state = 1;\n\t\t\tthis.update();\n\n\t\t\toptions.animatedProperties[ this.prop ] = true;\n\n\t\t\tfor ( i in options.animatedProperties ) {\n\t\t\t\tif ( options.animatedProperties[i] !== true ) {\n\t\t\t\t\tdone = false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( done ) {\n\t\t\t\t// Reset the overflow\n\t\t\t\tif ( options.overflow != null && !jQuery.support.shrinkWrapBlocks ) {\n\n\t\t\t\t\tjQuery.each( [ \"\", \"X\", \"Y\" ], function (index, value) {\n\t\t\t\t\t\telem.style[ \"overflow\" + value ] = options.overflow[index];\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\t// Hide the element if the \"hide\" operation was done\n\t\t\t\tif ( options.hide ) {\n\t\t\t\t\tjQuery(elem).hide();\n\t\t\t\t}\n\n\t\t\t\t// Reset the properties, if the item has been hidden or shown\n\t\t\t\tif ( options.hide || options.show ) {\n\t\t\t\t\tfor ( var p in options.animatedProperties ) {\n\t\t\t\t\t\tjQuery.style( elem, p, options.orig[p] );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Execute the complete function\n\t\t\t\toptions.complete.call( elem );\n\t\t\t}\n\n\t\t\treturn false;\n\n\t\t} else {\n\t\t\t// classical easing cannot be used with an Infinity duration\n\t\t\tif ( options.duration == Infinity ) {\n\t\t\t\tthis.now = t;\n\t\t\t} else {\n\t\t\t\tn = t - this.startTime;\n\t\t\t\tthis.state = n / options.duration;\n\n\t\t\t\t// Perform the easing function, defaults to swing\n\t\t\t\tthis.pos = jQuery.easing[ options.animatedProperties[ this.prop ] ]( this.state, n, 0, 1, options.duration );\n\t\t\t\tthis.now = this.start + ((this.end - this.start) * this.pos);\n\t\t\t}\n\t\t\t// Perform the next step of the animation\n\t\t\tthis.update();\n\t\t}\n\n\t\treturn true;\n\t}\n};\n\njQuery.extend( jQuery.fx, {\n\ttick: function() {\n\t\tfor ( var timers = jQuery.timers, i = 0 ; i < timers.length ; ++i ) {\n\t\t\tif ( !timers[i]() ) {\n\t\t\t\ttimers.splice(i--, 1);\n\t\t\t}\n\t\t}\n\n\t\tif ( !timers.length ) {\n\t\t\tjQuery.fx.stop();\n\t\t}\n\t},\n\n\tinterval: 13,\n\n\tstop: function() {\n\t\tclearInterval( timerId );\n\t\ttimerId = null;\n\t},\n\n\tspeeds: {\n\t\tslow: 600,\n\t\tfast: 200,\n\t\t// Default speed\n\t\t_default: 400\n\t},\n\n\tstep: {\n\t\topacity: function( fx ) {\n\t\t\tjQuery.style( fx.elem, \"opacity\", fx.now );\n\t\t},\n\n\t\t_default: function( fx ) {\n\t\t\tif ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {\n\t\t\t\tfx.elem.style[ fx.prop ] = (fx.prop === \"width\" || fx.prop === \"height\" ? Math.max(0, fx.now) : fx.now) + fx.unit;\n\t\t\t} else {\n\t\t\t\tfx.elem[ fx.prop ] = fx.now;\n\t\t\t}\n\t\t}\n\t}\n});\n\nif ( jQuery.expr && jQuery.expr.filters ) {\n\tjQuery.expr.filters.animated = function( elem ) {\n\t\treturn jQuery.grep(jQuery.timers, function( fn ) {\n\t\t\treturn elem === fn.elem;\n\t\t}).length;\n\t};\n}\n\n// Try to restore the default display value of an element\nfunction defaultDisplay( nodeName ) {\n\n\tif ( !elemdisplay[ nodeName ] ) {\n\n\t\tvar body = document.body,\n\t\t\telem = jQuery( \"<\" + nodeName + \">\" ).appendTo( body ),\n\t\t\tdisplay = elem.css( \"display\" );\n\n\t\telem.remove();\n\n\t\t// If the simple way fails,\n\t\t// get element's real default display by attaching it to a temp iframe\n\t\tif ( display === \"none\" || display === \"\" ) {\n\t\t\t// No iframe to use yet, so create it\n\t\t\tif ( !iframe ) {\n\t\t\t\tiframe = document.createElement( \"iframe\" );\n\t\t\t\tiframe.frameBorder = iframe.width = iframe.height = 0;\n\t\t\t}\n\n\t\t\tbody.appendChild( iframe );\n\n\t\t\t// Create a cacheable copy of the iframe document on first call.\n\t\t\t// IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML\n\t\t\t// document to it; WebKit & Firefox won't allow reusing the iframe document.\n\t\t\tif ( !iframeDoc || !iframe.createElement ) {\n\t\t\t\tiframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document;\n\t\t\t\tiframeDoc.write( ( document.compatMode === \"CSS1Compat\" ? \"<!doctype html>\" : \"\" ) + \"<html><body>\" );\n\t\t\t\tiframeDoc.close();\n\t\t\t}\n\n\t\t\telem = iframeDoc.createElement( nodeName );\n\n\t\t\tiframeDoc.body.appendChild( elem );\n\n\t\t\tdisplay = jQuery.css( elem, \"display\" );\n\n\t\t\tbody.removeChild( iframe );\n\t\t}\n\n\t\t// Store the correct default display\n\t\telemdisplay[ nodeName ] = display;\n\t}\n\n\treturn elemdisplay[ nodeName ];\n}\n\n\n\n\nvar rtable = /^t(?:able|d|h)$/i,\n\trroot = /^(?:body|html)$/i;\n\nif ( \"getBoundingClientRect\" in document.documentElement ) {\n\tjQuery.fn.offset = function( options ) {\n\t\tvar elem = this[0], box;\n\n\t\tif ( options ) {\n\t\t\treturn this.each(function( i ) {\n\t\t\t\tjQuery.offset.setOffset( this, options, i );\n\t\t\t});\n\t\t}\n\n\t\tif ( !elem || !elem.ownerDocument ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tif ( elem === elem.ownerDocument.body ) {\n\t\t\treturn jQuery.offset.bodyOffset( elem );\n\t\t}\n\n\t\ttry {\n\t\t\tbox = elem.getBoundingClientRect();\n\t\t} catch(e) {}\n\n\t\tvar doc = elem.ownerDocument,\n\t\t\tdocElem = doc.documentElement;\n\n\t\t// Make sure we're not dealing with a disconnected DOM node\n\t\tif ( !box || !jQuery.contains( docElem, elem ) ) {\n\t\t\treturn box ? { top: box.top, left: box.left } : { top: 0, left: 0 };\n\t\t}\n\n\t\tvar body = doc.body,\n\t\t\twin = getWindow(doc),\n\t\t\tclientTop  = docElem.clientTop  || body.clientTop  || 0,\n\t\t\tclientLeft = docElem.clientLeft || body.clientLeft || 0,\n\t\t\tscrollTop  = win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop  || body.scrollTop,\n\t\t\tscrollLeft = win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft,\n\t\t\ttop  = box.top  + scrollTop  - clientTop,\n\t\t\tleft = box.left + scrollLeft - clientLeft;\n\n\t\treturn { top: top, left: left };\n\t};\n\n} else {\n\tjQuery.fn.offset = function( options ) {\n\t\tvar elem = this[0];\n\n\t\tif ( options ) {\n\t\t\treturn this.each(function( i ) {\n\t\t\t\tjQuery.offset.setOffset( this, options, i );\n\t\t\t});\n\t\t}\n\n\t\tif ( !elem || !elem.ownerDocument ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tif ( elem === elem.ownerDocument.body ) {\n\t\t\treturn jQuery.offset.bodyOffset( elem );\n\t\t}\n\n\t\tjQuery.offset.initialize();\n\n\t\tvar computedStyle,\n\t\t\toffsetParent = elem.offsetParent,\n\t\t\tprevOffsetParent = elem,\n\t\t\tdoc = elem.ownerDocument,\n\t\t\tdocElem = doc.documentElement,\n\t\t\tbody = doc.body,\n\t\t\tdefaultView = doc.defaultView,\n\t\t\tprevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,\n\t\t\ttop = elem.offsetTop,\n\t\t\tleft = elem.offsetLeft;\n\n\t\twhile ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {\n\t\t\tif ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === \"fixed\" ) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcomputedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;\n\t\t\ttop  -= elem.scrollTop;\n\t\t\tleft -= elem.scrollLeft;\n\n\t\t\tif ( elem === offsetParent ) {\n\t\t\t\ttop  += elem.offsetTop;\n\t\t\t\tleft += elem.offsetLeft;\n\n\t\t\t\tif ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) {\n\t\t\t\t\ttop  += parseFloat( computedStyle.borderTopWidth  ) || 0;\n\t\t\t\t\tleft += parseFloat( computedStyle.borderLeftWidth ) || 0;\n\t\t\t\t}\n\n\t\t\t\tprevOffsetParent = offsetParent;\n\t\t\t\toffsetParent = elem.offsetParent;\n\t\t\t}\n\n\t\t\tif ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== \"visible\" ) {\n\t\t\t\ttop  += parseFloat( computedStyle.borderTopWidth  ) || 0;\n\t\t\t\tleft += parseFloat( computedStyle.borderLeftWidth ) || 0;\n\t\t\t}\n\n\t\t\tprevComputedStyle = computedStyle;\n\t\t}\n\n\t\tif ( prevComputedStyle.position === \"relative\" || prevComputedStyle.position === \"static\" ) {\n\t\t\ttop  += body.offsetTop;\n\t\t\tleft += body.offsetLeft;\n\t\t}\n\n\t\tif ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === \"fixed\" ) {\n\t\t\ttop  += Math.max( docElem.scrollTop, body.scrollTop );\n\t\t\tleft += Math.max( docElem.scrollLeft, body.scrollLeft );\n\t\t}\n\n\t\treturn { top: top, left: left };\n\t};\n}\n\njQuery.offset = {\n\tinitialize: function() {\n\t\tvar body = document.body, container = document.createElement(\"div\"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.css(body, \"marginTop\") ) || 0,\n\t\t\thtml = \"<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>\";\n\n\t\tjQuery.extend( container.style, { position: \"absolute\", top: 0, left: 0, margin: 0, border: 0, width: \"1px\", height: \"1px\", visibility: \"hidden\" } );\n\n\t\tcontainer.innerHTML = html;\n\t\tbody.insertBefore( container, body.firstChild );\n\t\tinnerDiv = container.firstChild;\n\t\tcheckDiv = innerDiv.firstChild;\n\t\ttd = innerDiv.nextSibling.firstChild.firstChild;\n\n\t\tthis.doesNotAddBorder = (checkDiv.offsetTop !== 5);\n\t\tthis.doesAddBorderForTableAndCells = (td.offsetTop === 5);\n\n\t\tcheckDiv.style.position = \"fixed\";\n\t\tcheckDiv.style.top = \"20px\";\n\n\t\t// safari subtracts parent border width here which is 5px\n\t\tthis.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15);\n\t\tcheckDiv.style.position = checkDiv.style.top = \"\";\n\n\t\tinnerDiv.style.overflow = \"hidden\";\n\t\tinnerDiv.style.position = \"relative\";\n\n\t\tthis.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);\n\n\t\tthis.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);\n\n\t\tbody.removeChild( container );\n\t\tjQuery.offset.initialize = jQuery.noop;\n\t},\n\n\tbodyOffset: function( body ) {\n\t\tvar top = body.offsetTop,\n\t\t\tleft = body.offsetLeft;\n\n\t\tjQuery.offset.initialize();\n\n\t\tif ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) {\n\t\t\ttop  += parseFloat( jQuery.css(body, \"marginTop\") ) || 0;\n\t\t\tleft += parseFloat( jQuery.css(body, \"marginLeft\") ) || 0;\n\t\t}\n\n\t\treturn { top: top, left: left };\n\t},\n\n\tsetOffset: function( elem, options, i ) {\n\t\tvar position = jQuery.css( elem, \"position\" );\n\n\t\t// set position first, in-case top/left are set even on static elem\n\t\tif ( position === \"static\" ) {\n\t\t\telem.style.position = \"relative\";\n\t\t}\n\n\t\tvar curElem = jQuery( elem ),\n\t\t\tcurOffset = curElem.offset(),\n\t\t\tcurCSSTop = jQuery.css( elem, \"top\" ),\n\t\t\tcurCSSLeft = jQuery.css( elem, \"left\" ),\n\t\t\tcalculatePosition = (position === \"absolute\" || position === \"fixed\") && jQuery.inArray(\"auto\", [curCSSTop, curCSSLeft]) > -1,\n\t\t\tprops = {}, curPosition = {}, curTop, curLeft;\n\n\t\t// need to be able to calculate position if either top or left is auto and position is either absolute or fixed\n\t\tif ( calculatePosition ) {\n\t\t\tcurPosition = curElem.position();\n\t\t\tcurTop = curPosition.top;\n\t\t\tcurLeft = curPosition.left;\n\t\t} else {\n\t\t\tcurTop = parseFloat( curCSSTop ) || 0;\n\t\t\tcurLeft = parseFloat( curCSSLeft ) || 0;\n\t\t}\n\n\t\tif ( jQuery.isFunction( options ) ) {\n\t\t\toptions = options.call( elem, i, curOffset );\n\t\t}\n\n\t\tif (options.top != null) {\n\t\t\tprops.top = (options.top - curOffset.top) + curTop;\n\t\t}\n\t\tif (options.left != null) {\n\t\t\tprops.left = (options.left - curOffset.left) + curLeft;\n\t\t}\n\n\t\tif ( \"using\" in options ) {\n\t\t\toptions.using.call( elem, props );\n\t\t} else {\n\t\t\tcurElem.css( props );\n\t\t}\n\t}\n};\n\n\njQuery.fn.extend({\n\tposition: function() {\n\t\tif ( !this[0] ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar elem = this[0],\n\n\t\t// Get *real* offsetParent\n\t\toffsetParent = this.offsetParent(),\n\n\t\t// Get correct offsets\n\t\toffset       = this.offset(),\n\t\tparentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();\n\n\t\t// Subtract element margins\n\t\t// note: when an element has margin: auto the offsetLeft and marginLeft\n\t\t// are the same in Safari causing offset.left to incorrectly be 0\n\t\toffset.top  -= parseFloat( jQuery.css(elem, \"marginTop\") ) || 0;\n\t\toffset.left -= parseFloat( jQuery.css(elem, \"marginLeft\") ) || 0;\n\n\t\t// Add offsetParent borders\n\t\tparentOffset.top  += parseFloat( jQuery.css(offsetParent[0], \"borderTopWidth\") ) || 0;\n\t\tparentOffset.left += parseFloat( jQuery.css(offsetParent[0], \"borderLeftWidth\") ) || 0;\n\n\t\t// Subtract the two offsets\n\t\treturn {\n\t\t\ttop:  offset.top  - parentOffset.top,\n\t\t\tleft: offset.left - parentOffset.left\n\t\t};\n\t},\n\n\toffsetParent: function() {\n\t\treturn this.map(function() {\n\t\t\tvar offsetParent = this.offsetParent || document.body;\n\t\t\twhile ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, \"position\") === \"static\") ) {\n\t\t\t\toffsetParent = offsetParent.offsetParent;\n\t\t\t}\n\t\t\treturn offsetParent;\n\t\t});\n\t}\n});\n\n\n// Create scrollLeft and scrollTop methods\njQuery.each( [\"Left\", \"Top\"], function( i, name ) {\n\tvar method = \"scroll\" + name;\n\n\tjQuery.fn[ method ] = function( val ) {\n\t\tvar elem, win;\n\n\t\tif ( val === undefined ) {\n\t\t\telem = this[ 0 ];\n\n\t\t\tif ( !elem ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\twin = getWindow( elem );\n\n\t\t\t// Return the scroll offset\n\t\t\treturn win ? (\"pageXOffset\" in win) ? win[ i ? \"pageYOffset\" : \"pageXOffset\" ] :\n\t\t\t\tjQuery.support.boxModel && win.document.documentElement[ method ] ||\n\t\t\t\t\twin.document.body[ method ] :\n\t\t\t\telem[ method ];\n\t\t}\n\n\t\t// Set the scroll offset\n\t\treturn this.each(function() {\n\t\t\twin = getWindow( this );\n\n\t\t\tif ( win ) {\n\t\t\t\twin.scrollTo(\n\t\t\t\t\t!i ? val : jQuery( win ).scrollLeft(),\n\t\t\t\t\t i ? val : jQuery( win ).scrollTop()\n\t\t\t\t);\n\n\t\t\t} else {\n\t\t\t\tthis[ method ] = val;\n\t\t\t}\n\t\t});\n\t};\n});\n\nfunction getWindow( elem ) {\n\treturn jQuery.isWindow( elem ) ?\n\t\telem :\n\t\telem.nodeType === 9 ?\n\t\t\telem.defaultView || elem.parentWindow :\n\t\t\tfalse;\n}\n\n\n\n\n// Create width, height, innerHeight, innerWidth, outerHeight and outerWidth methods\njQuery.each([ \"Height\", \"Width\" ], function( i, name ) {\n\n\tvar type = name.toLowerCase();\n\n\t// innerHeight and innerWidth\n\tjQuery.fn[ \"inner\" + name ] = function() {\n\t\tvar elem = this[0];\n\t\treturn elem && elem.style ?\n\t\t\tparseFloat( jQuery.css( elem, type, \"padding\" ) ) :\n\t\t\tnull;\n\t};\n\n\t// outerHeight and outerWidth\n\tjQuery.fn[ \"outer\" + name ] = function( margin ) {\n\t\tvar elem = this[0];\n\t\treturn elem && elem.style ?\n\t\t\tparseFloat( jQuery.css( elem, type, margin ? \"margin\" : \"border\" ) ) :\n\t\t\tnull;\n\t};\n\n\tjQuery.fn[ type ] = function( size ) {\n\t\t// Get window width or height\n\t\tvar elem = this[0];\n\t\tif ( !elem ) {\n\t\t\treturn size == null ? null : this;\n\t\t}\n\n\t\tif ( jQuery.isFunction( size ) ) {\n\t\t\treturn this.each(function( i ) {\n\t\t\t\tvar self = jQuery( this );\n\t\t\t\tself[ type ]( size.call( this, i, self[ type ]() ) );\n\t\t\t});\n\t\t}\n\n\t\tif ( jQuery.isWindow( elem ) ) {\n\t\t\t// Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode\n\t\t\t// 3rd condition allows Nokia support, as it supports the docElem prop but not CSS1Compat\n\t\t\tvar docElemProp = elem.document.documentElement[ \"client\" + name ],\n\t\t\t\tbody = elem.document.body;\n\t\t\treturn elem.document.compatMode === \"CSS1Compat\" && docElemProp ||\n\t\t\t\tbody && body[ \"client\" + name ] || docElemProp;\n\n\t\t// Get document width or height\n\t\t} else if ( elem.nodeType === 9 ) {\n\t\t\t// Either scroll[Width/Height] or offset[Width/Height], whichever is greater\n\t\t\treturn Math.max(\n\t\t\t\telem.documentElement[\"client\" + name],\n\t\t\t\telem.body[\"scroll\" + name], elem.documentElement[\"scroll\" + name],\n\t\t\t\telem.body[\"offset\" + name], elem.documentElement[\"offset\" + name]\n\t\t\t);\n\n\t\t// Get or set width or height on the element\n\t\t} else if ( size === undefined ) {\n\t\t\tvar orig = jQuery.css( elem, type ),\n\t\t\t\tret = parseFloat( orig );\n\n\t\t\treturn jQuery.isNaN( ret ) ? orig : ret;\n\n\t\t// Set the width or height on the element (default to pixels if value is unitless)\n\t\t} else {\n\t\t\treturn this.css( type, typeof size === \"string\" ? size : size + \"px\" );\n\t\t}\n\t};\n\n});\n\n\n// Expose jQuery to the global object\nwindow.jQuery = window.$ = jQuery;\n})(window);\n"
  },
  {
    "path": "tests/qunit.css",
    "content": "/**\n * QUnit 1.2.0pre - A JavaScript Unit Testing Framework\n *\n * http://docs.jquery.com/QUnit\n *\n * Copyright (c) 2011 John Resig, Jörn Zaefferer\n * Dual licensed under the MIT (MIT-LICENSE.txt)\n * or GPL (GPL-LICENSE.txt) licenses.\n */\n\n/** Font Family and Sizes */\n\n#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult {\n\tfont-family: \"Helvetica Neue Light\", \"HelveticaNeue-Light\", \"Helvetica Neue\", Calibri, Helvetica, Arial, sans-serif;\n}\n\n#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; }\n#qunit-tests { font-size: smaller; }\n\n\n/** Resets */\n\n#qunit-tests, #qunit-tests ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult {\n\tmargin: 0;\n\tpadding: 0;\n}\n\n\n/** Header */\n\n#qunit-header {\n\tpadding: 0.5em 0 0.5em 1em;\n\n\tcolor: #8699a4;\n\tbackground-color: #0d3349;\n\n\tfont-size: 1.5em;\n\tline-height: 1em;\n\tfont-weight: normal;\n\n\tborder-radius: 15px 15px 0 0;\n\t-moz-border-radius: 15px 15px 0 0;\n\t-webkit-border-top-right-radius: 15px;\n\t-webkit-border-top-left-radius: 15px;\n}\n\n#qunit-header a {\n\ttext-decoration: none;\n\tcolor: #c2ccd1;\n}\n\n#qunit-header a:hover,\n#qunit-header a:focus {\n\tcolor: #fff;\n}\n\n#qunit-banner {\n\theight: 5px;\n}\n\n#qunit-testrunner-toolbar {\n\tpadding: 0.5em 0 0.5em 2em;\n\tcolor: #5E740B;\n\tbackground-color: #eee;\n}\n\n#qunit-userAgent {\n\tpadding: 0.5em 0 0.5em 2.5em;\n\tbackground-color: #2b81af;\n\tcolor: #fff;\n\ttext-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;\n}\n\n\n/** Tests: Pass/Fail */\n\n#qunit-tests {\n\tlist-style-position: inside;\n}\n\n#qunit-tests li {\n\tpadding: 0.4em 0.5em 0.4em 2.5em;\n\tborder-bottom: 1px solid #fff;\n\tlist-style-position: inside;\n}\n\n#qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running  {\n\tdisplay: none;\n}\n\n#qunit-tests li strong {\n\tcursor: pointer;\n}\n\n#qunit-tests li a {\n\tpadding: 0.5em;\n\tcolor: #c2ccd1;\n\ttext-decoration: none;\n}\n#qunit-tests li a:hover,\n#qunit-tests li a:focus {\n\tcolor: #000;\n}\n\n#qunit-tests ol {\n\tmargin-top: 0.5em;\n\tpadding: 0.5em;\n\n\tbackground-color: #fff;\n\n\tborder-radius: 15px;\n\t-moz-border-radius: 15px;\n\t-webkit-border-radius: 15px;\n\n\tbox-shadow: inset 0px 2px 13px #999;\n\t-moz-box-shadow: inset 0px 2px 13px #999;\n\t-webkit-box-shadow: inset 0px 2px 13px #999;\n}\n\n#qunit-tests table {\n\tborder-collapse: collapse;\n\tmargin-top: .2em;\n}\n\n#qunit-tests th {\n\ttext-align: right;\n\tvertical-align: top;\n\tpadding: 0 .5em 0 0;\n}\n\n#qunit-tests td {\n\tvertical-align: top;\n}\n\n#qunit-tests pre {\n\tmargin: 0;\n\twhite-space: pre-wrap;\n\tword-wrap: break-word;\n}\n\n#qunit-tests del {\n\tbackground-color: #e0f2be;\n\tcolor: #374e0c;\n\ttext-decoration: none;\n}\n\n#qunit-tests ins {\n\tbackground-color: #ffcaca;\n\tcolor: #500;\n\ttext-decoration: none;\n}\n\n/*** Test Counts */\n\n#qunit-tests b.counts                       { color: black; }\n#qunit-tests b.passed                       { color: #5E740B; }\n#qunit-tests b.failed                       { color: #710909; }\n\n#qunit-tests li li {\n\tmargin: 0.5em;\n\tpadding: 0.4em 0.5em 0.4em 0.5em;\n\tbackground-color: #fff;\n\tborder-bottom: none;\n\tlist-style-position: inside;\n}\n\n/*** Passing Styles */\n\n#qunit-tests li li.pass {\n\tcolor: #5E740B;\n\tbackground-color: #fff;\n\tborder-left: 26px solid #C6E746;\n}\n\n#qunit-tests .pass                          { color: #528CE0; background-color: #D2E0E6; }\n#qunit-tests .pass .test-name               { color: #366097; }\n\n#qunit-tests .pass .test-actual,\n#qunit-tests .pass .test-expected           { color: #999999; }\n\n#qunit-banner.qunit-pass                    { background-color: #C6E746; }\n\n/*** Failing Styles */\n\n#qunit-tests li li.fail {\n\tcolor: #710909;\n\tbackground-color: #fff;\n\tborder-left: 26px solid #EE5757;\n\twhite-space: pre;\n}\n\n#qunit-tests > li:last-child {\n\tborder-radius: 0 0 15px 15px;\n\t-moz-border-radius: 0 0 15px 15px;\n\t-webkit-border-bottom-right-radius: 15px;\n\t-webkit-border-bottom-left-radius: 15px;\n}\n\n#qunit-tests .fail                          { color: #000000; background-color: #EE5757; }\n#qunit-tests .fail .test-name,\n#qunit-tests .fail .module-name             { color: #000000; }\n\n#qunit-tests .fail .test-actual             { color: #EE5757; }\n#qunit-tests .fail .test-expected           { color: green;   }\n\n#qunit-banner.qunit-fail                    { background-color: #EE5757; }\n\n\n/** Result */\n\n#qunit-testresult {\n\tpadding: 0.5em 0.5em 0.5em 2.5em;\n\n\tcolor: #2b81af;\n\tbackground-color: #D2E0E6;\n\n\tborder-bottom: 1px solid white;\n}\n\n/** Fixture */\n\n#qunit-fixture {\n\tposition: absolute;\n\ttop: -10000px;\n\tleft: -10000px;\n}\n"
  },
  {
    "path": "tests/qunit.js",
    "content": "/**\n * QUnit 1.2.0pre - A JavaScript Unit Testing Framework\n *\n * http://docs.jquery.com/QUnit\n *\n * Copyright (c) 2011 John Resig, Jörn Zaefferer\n * Dual licensed under the MIT (MIT-LICENSE.txt)\n * or GPL (GPL-LICENSE.txt) licenses.\n */\n\n(function(window) {\n\nvar defined = {\n\tsetTimeout: typeof window.setTimeout !== \"undefined\",\n\tsessionStorage: (function() {\n\t\ttry {\n\t\t\treturn !!sessionStorage.getItem;\n\t\t} catch(e) {\n\t\t\treturn false;\n\t\t}\n\t})()\n};\n\nvar\ttestId = 0,\n\ttoString = Object.prototype.toString,\n\thasOwn = Object.prototype.hasOwnProperty;\n\nvar Test = function(name, testName, expected, testEnvironmentArg, async, callback) {\n\tthis.name = name;\n\tthis.testName = testName;\n\tthis.expected = expected;\n\tthis.testEnvironmentArg = testEnvironmentArg;\n\tthis.async = async;\n\tthis.callback = callback;\n\tthis.assertions = [];\n};\nTest.prototype = {\n\tinit: function() {\n\t\tvar tests = id(\"qunit-tests\");\n\t\tif (tests) {\n\t\t\tvar b = document.createElement(\"strong\");\n\t\t\t\tb.innerHTML = \"Running \" + this.name;\n\t\t\tvar li = document.createElement(\"li\");\n\t\t\t\tli.appendChild( b );\n\t\t\t\tli.className = \"running\";\n\t\t\t\tli.id = this.id = \"test-output\" + testId++;\n\t\t\ttests.appendChild( li );\n\t\t}\n\t},\n\tsetup: function() {\n\t\tif (this.module != config.previousModule) {\n\t\t\tif ( config.previousModule ) {\n\t\t\t\trunLoggingCallbacks('moduleDone', QUnit, {\n\t\t\t\t\tname: config.previousModule,\n\t\t\t\t\tfailed: config.moduleStats.bad,\n\t\t\t\t\tpassed: config.moduleStats.all - config.moduleStats.bad,\n\t\t\t\t\ttotal: config.moduleStats.all\n\t\t\t\t} );\n\t\t\t}\n\t\t\tconfig.previousModule = this.module;\n\t\t\tconfig.moduleStats = { all: 0, bad: 0 };\n\t\t\trunLoggingCallbacks( 'moduleStart', QUnit, {\n\t\t\t\tname: this.module\n\t\t\t} );\n\t\t}\n\n\t\tconfig.current = this;\n\t\tthis.testEnvironment = extend({\n\t\t\tsetup: function() {},\n\t\t\tteardown: function() {}\n\t\t}, this.moduleTestEnvironment);\n\t\tif (this.testEnvironmentArg) {\n\t\t\textend(this.testEnvironment, this.testEnvironmentArg);\n\t\t}\n\n\t\trunLoggingCallbacks( 'testStart', QUnit, {\n\t\t\tname: this.testName,\n\t\t\tmodule: this.module\n\t\t});\n\n\t\t// allow utility functions to access the current test environment\n\t\t// TODO why??\n\t\tQUnit.current_testEnvironment = this.testEnvironment;\n\n\t\ttry {\n\t\t\tif ( !config.pollution ) {\n\t\t\t\tsaveGlobal();\n\t\t\t}\n\n\t\t\tthis.testEnvironment.setup.call(this.testEnvironment);\n\t\t} catch(e) {\n\t\t\tQUnit.ok( false, \"Setup failed on \" + this.testName + \": \" + e.message );\n\t\t}\n\t},\n\trun: function() {\n\t\tconfig.current = this;\n\t\tif ( this.async ) {\n\t\t\tQUnit.stop();\n\t\t}\n\n\t\tif ( config.notrycatch ) {\n\t\t\tthis.callback.call(this.testEnvironment);\n\t\t\treturn;\n\t\t}\n\t\ttry {\n\t\t\tthis.callback.call(this.testEnvironment);\n\t\t} catch(e) {\n\t\t\tfail(\"Test \" + this.testName + \" died, exception and test follows\", e, this.callback);\n\t\t\tQUnit.ok( false, \"Died on test #\" + (this.assertions.length + 1) + \": \" + e.message + \" - \" + QUnit.jsDump.parse(e) );\n\t\t\t// else next test will carry the responsibility\n\t\t\tsaveGlobal();\n\n\t\t\t// Restart the tests if they're blocking\n\t\t\tif ( config.blocking ) {\n\t\t\t\tQUnit.start();\n\t\t\t}\n\t\t}\n\t},\n\tteardown: function() {\n\t\tconfig.current = this;\n\t\ttry {\n\t\t\tthis.testEnvironment.teardown.call(this.testEnvironment);\n\t\t\tcheckPollution();\n\t\t} catch(e) {\n\t\t\tQUnit.ok( false, \"Teardown failed on \" + this.testName + \": \" + e.message );\n\t\t}\n\t},\n\tfinish: function() {\n\t\tconfig.current = this;\n\t\tif ( this.expected != null && this.expected != this.assertions.length ) {\n\t\t\tQUnit.ok( false, \"Expected \" + this.expected + \" assertions, but \" + this.assertions.length + \" were run\" );\n\t\t}\n\n\t\tvar good = 0, bad = 0,\n\t\t\ttests = id(\"qunit-tests\");\n\n\t\tconfig.stats.all += this.assertions.length;\n\t\tconfig.moduleStats.all += this.assertions.length;\n\n\t\tif ( tests ) {\n\t\t\tvar ol = document.createElement(\"ol\");\n\n\t\t\tfor ( var i = 0; i < this.assertions.length; i++ ) {\n\t\t\t\tvar assertion = this.assertions[i];\n\n\t\t\t\tvar li = document.createElement(\"li\");\n\t\t\t\tli.className = assertion.result ? \"pass\" : \"fail\";\n\t\t\t\tli.innerHTML = assertion.message || (assertion.result ? \"okay\" : \"failed\");\n\t\t\t\tol.appendChild( li );\n\n\t\t\t\tif ( assertion.result ) {\n\t\t\t\t\tgood++;\n\t\t\t\t} else {\n\t\t\t\t\tbad++;\n\t\t\t\t\tconfig.stats.bad++;\n\t\t\t\t\tconfig.moduleStats.bad++;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// store result when possible\n\t\t\tif ( QUnit.config.reorder && defined.sessionStorage ) {\n\t\t\t\tif (bad) {\n\t\t\t\t\tsessionStorage.setItem(\"qunit-\" + this.module + \"-\" + this.testName, bad);\n\t\t\t\t} else {\n\t\t\t\t\tsessionStorage.removeItem(\"qunit-\" + this.module + \"-\" + this.testName);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (bad == 0) {\n\t\t\t\tol.style.display = \"none\";\n\t\t\t}\n\n\t\t\tvar b = document.createElement(\"strong\");\n\t\t\tb.innerHTML = this.name + \" <b class='counts'>(<b class='failed'>\" + bad + \"</b>, <b class='passed'>\" + good + \"</b>, \" + this.assertions.length + \")</b>\";\n\n\t\t\tvar a = document.createElement(\"a\");\n\t\t\ta.innerHTML = \"Rerun\";\n\t\t\ta.href = QUnit.url({ filter: getText([b]).replace(/\\([^)]+\\)$/, \"\").replace(/(^\\s*|\\s*$)/g, \"\") });\n\n\t\t\taddEvent(b, \"click\", function() {\n\t\t\t\tvar next = b.nextSibling.nextSibling,\n\t\t\t\t\tdisplay = next.style.display;\n\t\t\t\tnext.style.display = display === \"none\" ? \"block\" : \"none\";\n\t\t\t});\n\n\t\t\taddEvent(b, \"dblclick\", function(e) {\n\t\t\t\tvar target = e && e.target ? e.target : window.event.srcElement;\n\t\t\t\tif ( target.nodeName.toLowerCase() == \"span\" || target.nodeName.toLowerCase() == \"b\" ) {\n\t\t\t\t\ttarget = target.parentNode;\n\t\t\t\t}\n\t\t\t\tif ( window.location && target.nodeName.toLowerCase() === \"strong\" ) {\n\t\t\t\t\twindow.location = QUnit.url({ filter: getText([target]).replace(/\\([^)]+\\)$/, \"\").replace(/(^\\s*|\\s*$)/g, \"\") });\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tvar li = id(this.id);\n\t\t\tli.className = bad ? \"fail\" : \"pass\";\n\t\t\tli.removeChild( li.firstChild );\n\t\t\tli.appendChild( b );\n\t\t\tli.appendChild( a );\n\t\t\tli.appendChild( ol );\n\n\t\t} else {\n\t\t\tfor ( var i = 0; i < this.assertions.length; i++ ) {\n\t\t\t\tif ( !this.assertions[i].result ) {\n\t\t\t\t\tbad++;\n\t\t\t\t\tconfig.stats.bad++;\n\t\t\t\t\tconfig.moduleStats.bad++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\ttry {\n\t\t\tQUnit.reset();\n\t\t} catch(e) {\n\t\t\tfail(\"reset() failed, following Test \" + this.testName + \", exception and reset fn follows\", e, QUnit.reset);\n\t\t}\n\n\t\trunLoggingCallbacks( 'testDone', QUnit, {\n\t\t\tname: this.testName,\n\t\t\tmodule: this.module,\n\t\t\tfailed: bad,\n\t\t\tpassed: this.assertions.length - bad,\n\t\t\ttotal: this.assertions.length\n\t\t} );\n\t},\n\n\tqueue: function() {\n\t\tvar test = this;\n\t\tsynchronize(function() {\n\t\t\ttest.init();\n\t\t});\n\t\tfunction run() {\n\t\t\t// each of these can by async\n\t\t\tsynchronize(function() {\n\t\t\t\ttest.setup();\n\t\t\t});\n\t\t\tsynchronize(function() {\n\t\t\t\ttest.run();\n\t\t\t});\n\t\t\tsynchronize(function() {\n\t\t\t\ttest.teardown();\n\t\t\t});\n\t\t\tsynchronize(function() {\n\t\t\t\ttest.finish();\n\t\t\t});\n\t\t}\n\t\t// defer when previous test run passed, if storage is available\n\t\tvar bad = QUnit.config.reorder && defined.sessionStorage && +sessionStorage.getItem(\"qunit-\" + this.module + \"-\" + this.testName);\n\t\tif (bad) {\n\t\t\trun();\n\t\t} else {\n\t\t\tsynchronize(run, true);\n\t\t};\n\t}\n\n};\n\nvar QUnit = {\n\n\t// call on start of module test to prepend name to all tests\n\tmodule: function(name, testEnvironment) {\n\t\tconfig.currentModule = name;\n\t\tconfig.currentModuleTestEnviroment = testEnvironment;\n\t},\n\n\tasyncTest: function(testName, expected, callback) {\n\t\tif ( arguments.length === 2 ) {\n\t\t\tcallback = expected;\n\t\t\texpected = null;\n\t\t}\n\n\t\tQUnit.test(testName, expected, callback, true);\n\t},\n\n\ttest: function(testName, expected, callback, async) {\n\t\tvar name = '<span class=\"test-name\">' + testName + '</span>', testEnvironmentArg;\n\n\t\tif ( arguments.length === 2 ) {\n\t\t\tcallback = expected;\n\t\t\texpected = null;\n\t\t}\n\t\t// is 2nd argument a testEnvironment?\n\t\tif ( expected && typeof expected === 'object') {\n\t\t\ttestEnvironmentArg = expected;\n\t\t\texpected = null;\n\t\t}\n\n\t\tif ( config.currentModule ) {\n\t\t\tname = '<span class=\"module-name\">' + config.currentModule + \"</span>: \" + name;\n\t\t}\n\n\t\tif ( !validTest(config.currentModule + \": \" + testName) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar test = new Test(name, testName, expected, testEnvironmentArg, async, callback);\n\t\ttest.module = config.currentModule;\n\t\ttest.moduleTestEnvironment = config.currentModuleTestEnviroment;\n\t\ttest.queue();\n\t},\n\n\t/**\n\t * Specify the number of expected assertions to guarantee that failed test (no assertions are run at all) don't slip through.\n\t */\n\texpect: function(asserts) {\n\t\tconfig.current.expected = asserts;\n\t},\n\n\t/**\n\t * Asserts true.\n\t * @example ok( \"asdfasdf\".length > 5, \"There must be at least 5 chars\" );\n\t */\n\tok: function(a, msg) {\n\t\ta = !!a;\n\t\tvar details = {\n\t\t\tresult: a,\n\t\t\tmessage: msg\n\t\t};\n\t\tmsg = escapeInnerText(msg);\n\t\trunLoggingCallbacks( 'log', QUnit, details );\n\t\tconfig.current.assertions.push({\n\t\t\tresult: a,\n\t\t\tmessage: msg\n\t\t});\n\t},\n\n\t/**\n\t * Checks that the first two arguments are equal, with an optional message.\n\t * Prints out both actual and expected values.\n\t *\n\t * Prefered to ok( actual == expected, message )\n\t *\n\t * @example equal( format(\"Received {0} bytes.\", 2), \"Received 2 bytes.\" );\n\t *\n\t * @param Object actual\n\t * @param Object expected\n\t * @param String message (optional)\n\t */\n\tequal: function(actual, expected, message) {\n\t\tQUnit.push(expected == actual, actual, expected, message);\n\t},\n\n\tnotEqual: function(actual, expected, message) {\n\t\tQUnit.push(expected != actual, actual, expected, message);\n\t},\n\n\tdeepEqual: function(actual, expected, message) {\n\t\tQUnit.push(QUnit.equiv(actual, expected), actual, expected, message);\n\t},\n\n\tnotDeepEqual: function(actual, expected, message) {\n\t\tQUnit.push(!QUnit.equiv(actual, expected), actual, expected, message);\n\t},\n\n\tstrictEqual: function(actual, expected, message) {\n\t\tQUnit.push(expected === actual, actual, expected, message);\n\t},\n\n\tnotStrictEqual: function(actual, expected, message) {\n\t\tQUnit.push(expected !== actual, actual, expected, message);\n\t},\n\n\traises: function(block, expected, message) {\n\t\tvar actual, ok = false;\n\n\t\tif (typeof expected === 'string') {\n\t\t\tmessage = expected;\n\t\t\texpected = null;\n\t\t}\n\n\t\ttry {\n\t\t\tblock();\n\t\t} catch (e) {\n\t\t\tactual = e;\n\t\t}\n\n\t\tif (actual) {\n\t\t\t// we don't want to validate thrown error\n\t\t\tif (!expected) {\n\t\t\t\tok = true;\n\t\t\t// expected is a regexp\n\t\t\t} else if (QUnit.objectType(expected) === \"regexp\") {\n\t\t\t\tok = expected.test(actual);\n\t\t\t// expected is a constructor\n\t\t\t} else if (actual instanceof expected) {\n\t\t\t\tok = true;\n\t\t\t// expected is a validation function which returns true is validation passed\n\t\t\t} else if (expected.call({}, actual) === true) {\n\t\t\t\tok = true;\n\t\t\t}\n\t\t}\n\n\t\tQUnit.ok(ok, message);\n\t},\n\n\tstart: function(count) {\n\t\tconfig.semaphore -= count || 1;\n\t\tif (config.semaphore > 0) {\n\t\t\t// don't start until equal number of stop-calls\n\t\t\treturn;\n\t\t}\n\t\tif (config.semaphore < 0) {\n\t\t\t// ignore if start is called more often then stop\n\t\t\tconfig.semaphore = 0;\n\t\t}\n\t\t// A slight delay, to avoid any current callbacks\n\t\tif ( defined.setTimeout ) {\n\t\t\twindow.setTimeout(function() {\n\t\t\t\tif (config.semaphore > 0) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif ( config.timeout ) {\n\t\t\t\t\tclearTimeout(config.timeout);\n\t\t\t\t}\n\n\t\t\t\tconfig.blocking = false;\n\t\t\t\tprocess(true);\n\t\t\t}, 13);\n\t\t} else {\n\t\t\tconfig.blocking = false;\n\t\t\tprocess(true);\n\t\t}\n\t},\n\n\tstop: function(count) {\n\t\tconfig.semaphore += count || 1;\n\t\tconfig.blocking = true;\n\n\t\tif ( config.testTimeout && defined.setTimeout ) {\n\t\t\tclearTimeout(config.timeout);\n\t\t\tconfig.timeout = window.setTimeout(function() {\n\t\t\t\tQUnit.ok( false, \"Test timed out\" );\n\t\t\t\tconfig.semaphore = 1;\n\t\t\t\tQUnit.start();\n\t\t\t}, config.testTimeout);\n\t\t}\n\t}\n};\n\n//We want access to the constructor's prototype\n(function() {\n\tfunction F(){};\n\tF.prototype = QUnit;\n\tQUnit = new F();\n\t//Make F QUnit's constructor so that we can add to the prototype later\n\tQUnit.constructor = F;\n})();\n\n// Backwards compatibility, deprecated\nQUnit.equals = QUnit.equal;\nQUnit.same = QUnit.deepEqual;\n\n// Maintain internal state\nvar config = {\n\t// The queue of tests to run\n\tqueue: [],\n\n\t// block until document ready\n\tblocking: true,\n\n\t// when enabled, show only failing tests\n\t// gets persisted through sessionStorage and can be changed in UI via checkbox\n\thidepassed: false,\n\n\t// by default, run previously failed tests first\n\t// very useful in combination with \"Hide passed tests\" checked\n\treorder: true,\n\n\t// by default, modify document.title when suite is done\n\taltertitle: true,\n\n\turlConfig: ['noglobals', 'notrycatch'],\n\n\t//logging callback queues\n\tbegin: [],\n\tdone: [],\n\tlog: [],\n\ttestStart: [],\n\ttestDone: [],\n\tmoduleStart: [],\n\tmoduleDone: []\n};\n\n// Load parameters\n(function() {\n\tvar location = window.location || { search: \"\", protocol: \"file:\" },\n\t\tparams = location.search.slice( 1 ).split( \"&\" ),\n\t\tlength = params.length,\n\t\turlParams = {},\n\t\tcurrent;\n\n\tif ( params[ 0 ] ) {\n\t\tfor ( var i = 0; i < length; i++ ) {\n\t\t\tcurrent = params[ i ].split( \"=\" );\n\t\t\tcurrent[ 0 ] = decodeURIComponent( current[ 0 ] );\n\t\t\t// allow just a key to turn on a flag, e.g., test.html?noglobals\n\t\t\tcurrent[ 1 ] = current[ 1 ] ? decodeURIComponent( current[ 1 ] ) : true;\n\t\t\turlParams[ current[ 0 ] ] = current[ 1 ];\n\t\t}\n\t}\n\n\tQUnit.urlParams = urlParams;\n\tconfig.filter = urlParams.filter;\n\n\t// Figure out if we're running the tests from a server or not\n\tQUnit.isLocal = !!(location.protocol === 'file:');\n})();\n\n// Expose the API as global variables, unless an 'exports'\n// object exists, in that case we assume we're in CommonJS\nif ( typeof exports === \"undefined\" || typeof require === \"undefined\" ) {\n\textend(window, QUnit);\n\twindow.QUnit = QUnit;\n} else {\n\textend(exports, QUnit);\n\texports.QUnit = QUnit;\n}\n\n// define these after exposing globals to keep them in these QUnit namespace only\nextend(QUnit, {\n\tconfig: config,\n\n\t// Initialize the configuration options\n\tinit: function() {\n\t\textend(config, {\n\t\t\tstats: { all: 0, bad: 0 },\n\t\t\tmoduleStats: { all: 0, bad: 0 },\n\t\t\tstarted: +new Date,\n\t\t\tupdateRate: 1000,\n\t\t\tblocking: false,\n\t\t\tautostart: true,\n\t\t\tautorun: false,\n\t\t\tfilter: \"\",\n\t\t\tqueue: [],\n\t\t\tsemaphore: 0\n\t\t});\n\n\t\tvar tests = id( \"qunit-tests\" ),\n\t\t\tbanner = id( \"qunit-banner\" ),\n\t\t\tresult = id( \"qunit-testresult\" );\n\n\t\tif ( tests ) {\n\t\t\ttests.innerHTML = \"\";\n\t\t}\n\n\t\tif ( banner ) {\n\t\t\tbanner.className = \"\";\n\t\t}\n\n\t\tif ( result ) {\n\t\t\tresult.parentNode.removeChild( result );\n\t\t}\n\n\t\tif ( tests ) {\n\t\t\tresult = document.createElement( \"p\" );\n\t\t\tresult.id = \"qunit-testresult\";\n\t\t\tresult.className = \"result\";\n\t\t\ttests.parentNode.insertBefore( result, tests );\n\t\t\tresult.innerHTML = 'Running...<br/>&nbsp;';\n\t\t}\n\t},\n\n\t/**\n\t * Resets the test setup. Useful for tests that modify the DOM.\n\t *\n\t * If jQuery is available, uses jQuery's html(), otherwise just innerHTML.\n\t */\n\treset: function() {\n\t\tif ( window.jQuery ) {\n\t\t\tjQuery( \"#qunit-fixture\" ).html( config.fixture );\n\t\t} else {\n\t\t\tvar main = id( 'qunit-fixture' );\n\t\t\tif ( main ) {\n\t\t\t\tmain.innerHTML = config.fixture;\n\t\t\t}\n\t\t}\n\t},\n\n\t/**\n\t * Trigger an event on an element.\n\t *\n\t * @example triggerEvent( document.body, \"click\" );\n\t *\n\t * @param DOMElement elem\n\t * @param String type\n\t */\n\ttriggerEvent: function( elem, type, event ) {\n\t\tif ( document.createEvent ) {\n\t\t\tevent = document.createEvent(\"MouseEvents\");\n\t\t\tevent.initMouseEvent(type, true, true, elem.ownerDocument.defaultView,\n\t\t\t\t0, 0, 0, 0, 0, false, false, false, false, 0, null);\n\t\t\telem.dispatchEvent( event );\n\n\t\t} else if ( elem.fireEvent ) {\n\t\t\telem.fireEvent(\"on\"+type);\n\t\t}\n\t},\n\n\t// Safe object type checking\n\tis: function( type, obj ) {\n\t\treturn QUnit.objectType( obj ) == type;\n\t},\n\n\tobjectType: function( obj ) {\n\t\tif (typeof obj === \"undefined\") {\n\t\t\t\treturn \"undefined\";\n\n\t\t// consider: typeof null === object\n\t\t}\n\t\tif (obj === null) {\n\t\t\t\treturn \"null\";\n\t\t}\n\n\t\tvar type = toString.call( obj ).match(/^\\[object\\s(.*)\\]$/)[1] || '';\n\n\t\tswitch (type) {\n\t\t\t\tcase 'Number':\n\t\t\t\t\t\tif (isNaN(obj)) {\n\t\t\t\t\t\t\t\treturn \"nan\";\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\treturn \"number\";\n\t\t\t\t\t\t}\n\t\t\t\tcase 'String':\n\t\t\t\tcase 'Boolean':\n\t\t\t\tcase 'Array':\n\t\t\t\tcase 'Date':\n\t\t\t\tcase 'RegExp':\n\t\t\t\tcase 'Function':\n\t\t\t\t\t\treturn type.toLowerCase();\n\t\t}\n\t\tif (typeof obj === \"object\") {\n\t\t\t\treturn \"object\";\n\t\t}\n\t\treturn undefined;\n\t},\n\n\tpush: function(result, actual, expected, message) {\n\t\tvar details = {\n\t\t\tresult: result,\n\t\t\tmessage: message,\n\t\t\tactual: actual,\n\t\t\texpected: expected\n\t\t};\n\n\t\tmessage = escapeInnerText(message) || (result ? \"okay\" : \"failed\");\n\t\tmessage = '<span class=\"test-message\">' + message + \"</span>\";\n\t\texpected = escapeInnerText(QUnit.jsDump.parse(expected));\n\t\tactual = escapeInnerText(QUnit.jsDump.parse(actual));\n\t\tvar output = message + '<table><tr class=\"test-expected\"><th>Expected: </th><td><pre>' + expected + '</pre></td></tr>';\n\t\tif (actual != expected) {\n\t\t\toutput += '<tr class=\"test-actual\"><th>Result: </th><td><pre>' + actual + '</pre></td></tr>';\n\t\t\toutput += '<tr class=\"test-diff\"><th>Diff: </th><td><pre>' + QUnit.diff(expected, actual) +'</pre></td></tr>';\n\t\t}\n\t\tif (!result) {\n\t\t\tvar source = sourceFromStacktrace();\n\t\t\tif (source) {\n\t\t\t\tdetails.source = source;\n\t\t\t\toutput += '<tr class=\"test-source\"><th>Source: </th><td><pre>' + escapeInnerText(source) + '</pre></td></tr>';\n\t\t\t}\n\t\t}\n\t\toutput += \"</table>\";\n\n\t\trunLoggingCallbacks( 'log', QUnit, details );\n\n\t\tconfig.current.assertions.push({\n\t\t\tresult: !!result,\n\t\t\tmessage: output\n\t\t});\n\t},\n\n\turl: function( params ) {\n\t\tparams = extend( extend( {}, QUnit.urlParams ), params );\n\t\tvar querystring = \"?\",\n\t\t\tkey;\n\t\tfor ( key in params ) {\n\t\t\tif ( !hasOwn.call( params, key ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tquerystring += encodeURIComponent( key ) + \"=\" +\n\t\t\t\tencodeURIComponent( params[ key ] ) + \"&\";\n\t\t}\n\t\treturn window.location.pathname + querystring.slice( 0, -1 );\n\t},\n\n\textend: extend,\n\tid: id,\n\taddEvent: addEvent\n});\n\n//QUnit.constructor is set to the empty F() above so that we can add to it's prototype later\n//Doing this allows us to tell if the following methods have been overwritten on the actual\n//QUnit object, which is a deprecated way of using the callbacks.\nextend(QUnit.constructor.prototype, {\n\t// Logging callbacks; all receive a single argument with the listed properties\n\t// run test/logs.html for any related changes\n\tbegin: registerLoggingCallback('begin'),\n\t// done: { failed, passed, total, runtime }\n\tdone: registerLoggingCallback('done'),\n\t// log: { result, actual, expected, message }\n\tlog: registerLoggingCallback('log'),\n\t// testStart: { name }\n\ttestStart: registerLoggingCallback('testStart'),\n\t// testDone: { name, failed, passed, total }\n\ttestDone: registerLoggingCallback('testDone'),\n\t// moduleStart: { name }\n\tmoduleStart: registerLoggingCallback('moduleStart'),\n\t// moduleDone: { name, failed, passed, total }\n\tmoduleDone: registerLoggingCallback('moduleDone')\n});\n\nif ( typeof document === \"undefined\" || document.readyState === \"complete\" ) {\n\tconfig.autorun = true;\n}\n\nQUnit.load = function() {\n\trunLoggingCallbacks( 'begin', QUnit, {} );\n\n\t// Initialize the config, saving the execution queue\n\tvar oldconfig = extend({}, config);\n\tQUnit.init();\n\textend(config, oldconfig);\n\n\tconfig.blocking = false;\n\n\tvar urlConfigHtml = '', len = config.urlConfig.length;\n\tfor ( var i = 0, val; i < len, val = config.urlConfig[i]; i++ ) {\n\t\tconfig[val] = QUnit.urlParams[val];\n\t\turlConfigHtml += '<label><input name=\"' + val + '\" type=\"checkbox\"' + ( config[val] ? ' checked=\"checked\"' : '' ) + '>' + val + '</label>';\n\t}\n\n\tvar userAgent = id(\"qunit-userAgent\");\n\tif ( userAgent ) {\n\t\tuserAgent.innerHTML = navigator.userAgent;\n\t}\n\tvar banner = id(\"qunit-header\");\n\tif ( banner ) {\n\t\tbanner.innerHTML = '<a href=\"' + QUnit.url({ filter: undefined }) + '\"> ' + banner.innerHTML + '</a> ' + urlConfigHtml;\n\t\taddEvent( banner, \"change\", function( event ) {\n\t\t\tvar params = {};\n\t\t\tparams[ event.target.name ] = event.target.checked ? true : undefined;\n\t\t\twindow.location = QUnit.url( params );\n\t\t});\n\t}\n\n\tvar toolbar = id(\"qunit-testrunner-toolbar\");\n\tif ( toolbar ) {\n\t\tvar filter = document.createElement(\"input\");\n\t\tfilter.type = \"checkbox\";\n\t\tfilter.id = \"qunit-filter-pass\";\n\t\taddEvent( filter, \"click\", function() {\n\t\t\tvar ol = document.getElementById(\"qunit-tests\");\n\t\t\tif ( filter.checked ) {\n\t\t\t\tol.className = ol.className + \" hidepass\";\n\t\t\t} else {\n\t\t\t\tvar tmp = \" \" + ol.className.replace( /[\\n\\t\\r]/g, \" \" ) + \" \";\n\t\t\t\tol.className = tmp.replace(/ hidepass /, \" \");\n\t\t\t}\n\t\t\tif ( defined.sessionStorage ) {\n\t\t\t\tif (filter.checked) {\n\t\t\t\t\tsessionStorage.setItem(\"qunit-filter-passed-tests\", \"true\");\n\t\t\t\t} else {\n\t\t\t\t\tsessionStorage.removeItem(\"qunit-filter-passed-tests\");\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\tif ( config.hidepassed || defined.sessionStorage && sessionStorage.getItem(\"qunit-filter-passed-tests\") ) {\n\t\t\tfilter.checked = true;\n\t\t\tvar ol = document.getElementById(\"qunit-tests\");\n\t\t\tol.className = ol.className + \" hidepass\";\n\t\t}\n\t\ttoolbar.appendChild( filter );\n\n\t\tvar label = document.createElement(\"label\");\n\t\tlabel.setAttribute(\"for\", \"qunit-filter-pass\");\n\t\tlabel.innerHTML = \"Hide passed tests\";\n\t\ttoolbar.appendChild( label );\n\t}\n\n\tvar main = id('qunit-fixture');\n\tif ( main ) {\n\t\tconfig.fixture = main.innerHTML;\n\t}\n\n\tif (config.autostart) {\n\t\tQUnit.start();\n\t}\n};\n\naddEvent(window, \"load\", QUnit.load);\n\n// addEvent(window, \"error\") gives us a useless event object\nwindow.onerror = function( message, file, line ) {\n\tif ( QUnit.config.current ) {\n\t\tok( false, message + \", \" + file + \":\" + line );\n\t} else {\n\t\ttest( \"global failure\", function() {\n\t\t\tok( false, message + \", \" + file + \":\" + line );\n\t\t});\n\t}\n};\n\nfunction done() {\n\tconfig.autorun = true;\n\n\t// Log the last module results\n\tif ( config.currentModule ) {\n\t\trunLoggingCallbacks( 'moduleDone', QUnit, {\n\t\t\tname: config.currentModule,\n\t\t\tfailed: config.moduleStats.bad,\n\t\t\tpassed: config.moduleStats.all - config.moduleStats.bad,\n\t\t\ttotal: config.moduleStats.all\n\t\t} );\n\t}\n\n\tvar banner = id(\"qunit-banner\"),\n\t\ttests = id(\"qunit-tests\"),\n\t\truntime = +new Date - config.started,\n\t\tpassed = config.stats.all - config.stats.bad,\n\t\thtml = [\n\t\t\t'Tests completed in ',\n\t\t\truntime,\n\t\t\t' milliseconds.<br/>',\n\t\t\t'<span class=\"passed\">',\n\t\t\tpassed,\n\t\t\t'</span> tests of <span class=\"total\">',\n\t\t\tconfig.stats.all,\n\t\t\t'</span> passed, <span class=\"failed\">',\n\t\t\tconfig.stats.bad,\n\t\t\t'</span> failed.'\n\t\t].join('');\n\n\tif ( banner ) {\n\t\tbanner.className = (config.stats.bad ? \"qunit-fail\" : \"qunit-pass\");\n\t}\n\n\tif ( tests ) {\n\t\tid( \"qunit-testresult\" ).innerHTML = html;\n\t}\n\n\tif ( config.altertitle && typeof document !== \"undefined\" && document.title ) {\n\t\t// show ✖ for good, ✔ for bad suite result in title\n\t\t// use escape sequences in case file gets loaded with non-utf-8-charset\n\t\tdocument.title = [\n\t\t\t(config.stats.bad ? \"\\u2716\" : \"\\u2714\"),\n\t\t\tdocument.title.replace(/^[\\u2714\\u2716] /i, \"\")\n\t\t].join(\" \");\n\t}\n\n\trunLoggingCallbacks( 'done', QUnit, {\n\t\tfailed: config.stats.bad,\n\t\tpassed: passed,\n\t\ttotal: config.stats.all,\n\t\truntime: runtime\n\t} );\n}\n\nfunction validTest( name ) {\n\tvar filter = config.filter,\n\t\trun = false;\n\n\tif ( !filter ) {\n\t\treturn true;\n\t}\n\n\tvar not = filter.charAt( 0 ) === \"!\";\n\tif ( not ) {\n\t\tfilter = filter.slice( 1 );\n\t}\n\n\tif ( name.indexOf( filter ) !== -1 ) {\n\t\treturn !not;\n\t}\n\n\tif ( not ) {\n\t\trun = true;\n\t}\n\n\treturn run;\n}\n\n// so far supports only Firefox, Chrome and Opera (buggy)\n// could be extended in the future to use something like https://github.com/csnover/TraceKit\nfunction sourceFromStacktrace() {\n\ttry {\n\t\tthrow new Error();\n\t} catch ( e ) {\n\t\tif (e.stacktrace) {\n\t\t\t// Opera\n\t\t\treturn e.stacktrace.split(\"\\n\")[6];\n\t\t} else if (e.stack) {\n\t\t\t// Firefox, Chrome\n\t\t\treturn e.stack.split(\"\\n\")[4];\n\t\t} else if (e.sourceURL) {\n\t\t\t// Safari, PhantomJS\n\t\t\t// TODO sourceURL points at the 'throw new Error' line above, useless\n\t\t\t//return e.sourceURL + \":\" + e.line;\n\t\t}\n\t}\n}\n\nfunction escapeInnerText(s) {\n\tif (!s) {\n\t\treturn \"\";\n\t}\n\ts = s + \"\";\n\treturn s.replace(/[\\&<>]/g, function(s) {\n\t\tswitch(s) {\n\t\t\tcase \"&\": return \"&amp;\";\n\t\t\tcase \"<\": return \"&lt;\";\n\t\t\tcase \">\": return \"&gt;\";\n\t\t\tdefault: return s;\n\t\t}\n\t});\n}\n\nfunction synchronize( callback, last ) {\n\tconfig.queue.push( callback );\n\n\tif ( config.autorun && !config.blocking ) {\n\t\tprocess(last);\n\t}\n}\n\nfunction process( last ) {\n\tvar start = new Date().getTime();\n\tconfig.depth = config.depth ? config.depth + 1 : 1;\n\n\twhile ( config.queue.length && !config.blocking ) {\n\t\tif ( !defined.setTimeout || config.updateRate <= 0 || ( ( new Date().getTime() - start ) < config.updateRate ) ) {\n\t\t\tconfig.queue.shift()();\n\t\t} else {\n\t\t\twindow.setTimeout( function(){\n\t\t\t\tprocess( last );\n\t\t\t}, 13 );\n\t\t\tbreak;\n\t\t}\n\t}\n\tconfig.depth--;\n\tif ( last && !config.blocking && !config.queue.length && config.depth === 0 ) {\n\t\tdone();\n\t}\n}\n\nfunction saveGlobal() {\n\tconfig.pollution = [];\n\n\tif ( config.noglobals ) {\n\t\tfor ( var key in window ) {\n\t\t\tif ( !hasOwn.call( window, key ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconfig.pollution.push( key );\n\t\t}\n\t}\n}\n\nfunction checkPollution( name ) {\n\tvar old = config.pollution;\n\tsaveGlobal();\n\n\tvar newGlobals = diff( config.pollution, old );\n\tif ( newGlobals.length > 0 ) {\n\t\tok( false, \"Introduced global variable(s): \" + newGlobals.join(\", \") );\n\t}\n\n\tvar deletedGlobals = diff( old, config.pollution );\n\tif ( deletedGlobals.length > 0 ) {\n\t\tok( false, \"Deleted global variable(s): \" + deletedGlobals.join(\", \") );\n\t}\n}\n\n// returns a new Array with the elements that are in a but not in b\nfunction diff( a, b ) {\n\tvar result = a.slice();\n\tfor ( var i = 0; i < result.length; i++ ) {\n\t\tfor ( var j = 0; j < b.length; j++ ) {\n\t\t\tif ( result[i] === b[j] ) {\n\t\t\t\tresult.splice(i, 1);\n\t\t\t\ti--;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\treturn result;\n}\n\nfunction fail(message, exception, callback) {\n\tif ( typeof console !== \"undefined\" && console.error && console.warn ) {\n\t\tconsole.error(message);\n\t\tconsole.error(exception);\n\t\tconsole.warn(callback.toString());\n\n\t} else if ( window.opera && opera.postError ) {\n\t\topera.postError(message, exception, callback.toString);\n\t}\n}\n\nfunction extend(a, b) {\n\tfor ( var prop in b ) {\n\t\tif ( b[prop] === undefined ) {\n\t\t\tdelete a[prop];\n\n\t\t// Avoid \"Member not found\" error in IE8 caused by setting window.constructor\n\t\t} else if ( prop !== \"constructor\" || a !== window ) {\n\t\t\ta[prop] = b[prop];\n\t\t}\n\t}\n\n\treturn a;\n}\n\nfunction addEvent(elem, type, fn) {\n\tif ( elem.addEventListener ) {\n\t\telem.addEventListener( type, fn, false );\n\t} else if ( elem.attachEvent ) {\n\t\telem.attachEvent( \"on\" + type, fn );\n\t} else {\n\t\tfn();\n\t}\n}\n\nfunction id(name) {\n\treturn !!(typeof document !== \"undefined\" && document && document.getElementById) &&\n\t\tdocument.getElementById( name );\n}\n\nfunction registerLoggingCallback(key){\n\treturn function(callback){\n\t\tconfig[key].push( callback );\n\t};\n}\n\n// Supports deprecated method of completely overwriting logging callbacks\nfunction runLoggingCallbacks(key, scope, args) {\n\t//debugger;\n\tvar callbacks;\n\tif ( QUnit.hasOwnProperty(key) ) {\n\t\tQUnit[key].call(scope, args);\n\t} else {\n\t\tcallbacks = config[key];\n\t\tfor( var i = 0; i < callbacks.length; i++ ) {\n\t\t\tcallbacks[i].call( scope, args );\n\t\t}\n\t}\n}\n\n// Test for equality any JavaScript type.\n// Author: Philippe Rathé <prathe@gmail.com>\nQUnit.equiv = function () {\n\n\tvar innerEquiv; // the real equiv function\n\tvar callers = []; // stack to decide between skip/abort functions\n\tvar parents = []; // stack to avoiding loops from circular referencing\n\n\t// Call the o related callback with the given arguments.\n\tfunction bindCallbacks(o, callbacks, args) {\n\t\tvar prop = QUnit.objectType(o);\n\t\tif (prop) {\n\t\t\tif (QUnit.objectType(callbacks[prop]) === \"function\") {\n\t\t\t\treturn callbacks[prop].apply(callbacks, args);\n\t\t\t} else {\n\t\t\t\treturn callbacks[prop]; // or undefined\n\t\t\t}\n\t\t}\n\t}\n\n\tvar callbacks = function () {\n\n\t\t// for string, boolean, number and null\n\t\tfunction useStrictEquality(b, a) {\n\t\t\tif (b instanceof a.constructor || a instanceof b.constructor) {\n\t\t\t\t// to catch short annotation VS 'new' annotation of a\n\t\t\t\t// declaration\n\t\t\t\t// e.g. var i = 1;\n\t\t\t\t// var j = new Number(1);\n\t\t\t\treturn a == b;\n\t\t\t} else {\n\t\t\t\treturn a === b;\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\t\"string\" : useStrictEquality,\n\t\t\t\"boolean\" : useStrictEquality,\n\t\t\t\"number\" : useStrictEquality,\n\t\t\t\"null\" : useStrictEquality,\n\t\t\t\"undefined\" : useStrictEquality,\n\n\t\t\t\"nan\" : function(b) {\n\t\t\t\treturn isNaN(b);\n\t\t\t},\n\n\t\t\t\"date\" : function(b, a) {\n\t\t\t\treturn QUnit.objectType(b) === \"date\"\n\t\t\t\t\t\t&& a.valueOf() === b.valueOf();\n\t\t\t},\n\n\t\t\t\"regexp\" : function(b, a) {\n\t\t\t\treturn QUnit.objectType(b) === \"regexp\"\n\t\t\t\t\t\t&& a.source === b.source && // the regex itself\n\t\t\t\t\t\ta.global === b.global && // and its modifiers\n\t\t\t\t\t\t\t\t\t\t\t\t\t// (gmi) ...\n\t\t\t\t\t\ta.ignoreCase === b.ignoreCase\n\t\t\t\t\t\t&& a.multiline === b.multiline;\n\t\t\t},\n\n\t\t\t// - skip when the property is a method of an instance (OOP)\n\t\t\t// - abort otherwise,\n\t\t\t// initial === would have catch identical references anyway\n\t\t\t\"function\" : function() {\n\t\t\t\tvar caller = callers[callers.length - 1];\n\t\t\t\treturn caller !== Object && typeof caller !== \"undefined\";\n\t\t\t},\n\n\t\t\t\"array\" : function(b, a) {\n\t\t\t\tvar i, j, loop;\n\t\t\t\tvar len;\n\n\t\t\t\t// b could be an object literal here\n\t\t\t\tif (!(QUnit.objectType(b) === \"array\")) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tlen = a.length;\n\t\t\t\tif (len !== b.length) { // safe and faster\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\t// track reference to avoid circular references\n\t\t\t\tparents.push(a);\n\t\t\t\tfor (i = 0; i < len; i++) {\n\t\t\t\t\tloop = false;\n\t\t\t\t\tfor (j = 0; j < parents.length; j++) {\n\t\t\t\t\t\tif (parents[j] === a[i]) {\n\t\t\t\t\t\t\tloop = true;// dont rewalk array\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (!loop && !innerEquiv(a[i], b[i])) {\n\t\t\t\t\t\tparents.pop();\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tparents.pop();\n\t\t\t\treturn true;\n\t\t\t},\n\n\t\t\t\"object\" : function(b, a) {\n\t\t\t\tvar i, j, loop;\n\t\t\t\tvar eq = true; // unless we can prove it\n\t\t\t\tvar aProperties = [], bProperties = []; // collection of\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t// strings\n\n\t\t\t\t// comparing constructors is more strict than using\n\t\t\t\t// instanceof\n\t\t\t\tif (a.constructor !== b.constructor) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\t// stack constructor before traversing properties\n\t\t\t\tcallers.push(a.constructor);\n\t\t\t\t// track reference to avoid circular references\n\t\t\t\tparents.push(a);\n\n\t\t\t\tfor (i in a) { // be strict: don't ensures hasOwnProperty\n\t\t\t\t\t\t\t\t// and go deep\n\t\t\t\t\tloop = false;\n\t\t\t\t\tfor (j = 0; j < parents.length; j++) {\n\t\t\t\t\t\tif (parents[j] === a[i])\n\t\t\t\t\t\t\tloop = true; // don't go down the same path\n\t\t\t\t\t\t\t\t\t\t\t// twice\n\t\t\t\t\t}\n\t\t\t\t\taProperties.push(i); // collect a's properties\n\n\t\t\t\t\tif (!loop && !innerEquiv(a[i], b[i])) {\n\t\t\t\t\t\teq = false;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tcallers.pop(); // unstack, we are done\n\t\t\t\tparents.pop();\n\n\t\t\t\tfor (i in b) {\n\t\t\t\t\tbProperties.push(i); // collect b's properties\n\t\t\t\t}\n\n\t\t\t\t// Ensures identical properties name\n\t\t\t\treturn eq\n\t\t\t\t\t\t&& innerEquiv(aProperties.sort(), bProperties\n\t\t\t\t\t\t\t\t.sort());\n\t\t\t}\n\t\t};\n\t}();\n\n\tinnerEquiv = function() { // can take multiple arguments\n\t\tvar args = Array.prototype.slice.apply(arguments);\n\t\tif (args.length < 2) {\n\t\t\treturn true; // end transition\n\t\t}\n\n\t\treturn (function(a, b) {\n\t\t\tif (a === b) {\n\t\t\t\treturn true; // catch the most you can\n\t\t\t} else if (a === null || b === null || typeof a === \"undefined\"\n\t\t\t\t\t|| typeof b === \"undefined\"\n\t\t\t\t\t|| QUnit.objectType(a) !== QUnit.objectType(b)) {\n\t\t\t\treturn false; // don't lose time with error prone cases\n\t\t\t} else {\n\t\t\t\treturn bindCallbacks(a, callbacks, [ b, a ]);\n\t\t\t}\n\n\t\t\t// apply transition with (1..n) arguments\n\t\t})(args[0], args[1])\n\t\t\t\t&& arguments.callee.apply(this, args.splice(1,\n\t\t\t\t\t\targs.length - 1));\n\t};\n\n\treturn innerEquiv;\n\n}();\n\n/**\n * jsDump Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com |\n * http://flesler.blogspot.com Licensed under BSD\n * (http://www.opensource.org/licenses/bsd-license.php) Date: 5/15/2008\n *\n * @projectDescription Advanced and extensible data dumping for Javascript.\n * @version 1.0.0\n * @author Ariel Flesler\n * @link {http://flesler.blogspot.com/2008/05/jsdump-pretty-dump-of-any-javascript.html}\n */\nQUnit.jsDump = (function() {\n\tfunction quote( str ) {\n\t\treturn '\"' + str.toString().replace(/\"/g, '\\\\\"') + '\"';\n\t};\n\tfunction literal( o ) {\n\t\treturn o + '';\n\t};\n\tfunction join( pre, arr, post ) {\n\t\tvar s = jsDump.separator(),\n\t\t\tbase = jsDump.indent(),\n\t\t\tinner = jsDump.indent(1);\n\t\tif ( arr.join )\n\t\t\tarr = arr.join( ',' + s + inner );\n\t\tif ( !arr )\n\t\t\treturn pre + post;\n\t\treturn [ pre, inner + arr, base + post ].join(s);\n\t};\n\tfunction array( arr, stack ) {\n\t\tvar i = arr.length, ret = Array(i);\n\t\tthis.up();\n\t\twhile ( i-- )\n\t\t\tret[i] = this.parse( arr[i] , undefined , stack);\n\t\tthis.down();\n\t\treturn join( '[', ret, ']' );\n\t};\n\n\tvar reName = /^function (\\w+)/;\n\n\tvar jsDump = {\n\t\tparse:function( obj, type, stack ) { //type is used mostly internally, you can fix a (custom)type in advance\n\t\t\tstack = stack || [ ];\n\t\t\tvar parser = this.parsers[ type || this.typeOf(obj) ];\n\t\t\ttype = typeof parser;\n\t\t\tvar inStack = inArray(obj, stack);\n\t\t\tif (inStack != -1) {\n\t\t\t\treturn 'recursion('+(inStack - stack.length)+')';\n\t\t\t}\n\t\t\t//else\n\t\t\tif (type == 'function')  {\n\t\t\t\t\tstack.push(obj);\n\t\t\t\t\tvar res = parser.call( this, obj, stack );\n\t\t\t\t\tstack.pop();\n\t\t\t\t\treturn res;\n\t\t\t}\n\t\t\t// else\n\t\t\treturn (type == 'string') ? parser : this.parsers.error;\n\t\t},\n\t\ttypeOf:function( obj ) {\n\t\t\tvar type;\n\t\t\tif ( obj === null ) {\n\t\t\t\ttype = \"null\";\n\t\t\t} else if (typeof obj === \"undefined\") {\n\t\t\t\ttype = \"undefined\";\n\t\t\t} else if (QUnit.is(\"RegExp\", obj)) {\n\t\t\t\ttype = \"regexp\";\n\t\t\t} else if (QUnit.is(\"Date\", obj)) {\n\t\t\t\ttype = \"date\";\n\t\t\t} else if (QUnit.is(\"Function\", obj)) {\n\t\t\t\ttype = \"function\";\n\t\t\t} else if (typeof obj.setInterval !== undefined && typeof obj.document !== \"undefined\" && typeof obj.nodeType === \"undefined\") {\n\t\t\t\ttype = \"window\";\n\t\t\t} else if (obj.nodeType === 9) {\n\t\t\t\ttype = \"document\";\n\t\t\t} else if (obj.nodeType) {\n\t\t\t\ttype = \"node\";\n\t\t\t} else if (\n\t\t\t\t// native arrays\n\t\t\t\ttoString.call( obj ) === \"[object Array]\" ||\n\t\t\t\t// NodeList objects\n\t\t\t\t( typeof obj.length === \"number\" && typeof obj.item !== \"undefined\" && ( obj.length ? obj.item(0) === obj[0] : ( obj.item( 0 ) === null && typeof obj[0] === \"undefined\" ) ) )\n\t\t\t) {\n\t\t\t\ttype = \"array\";\n\t\t\t} else {\n\t\t\t\ttype = typeof obj;\n\t\t\t}\n\t\t\treturn type;\n\t\t},\n\t\tseparator:function() {\n\t\t\treturn this.multiline ?\tthis.HTML ? '<br />' : '\\n' : this.HTML ? '&nbsp;' : ' ';\n\t\t},\n\t\tindent:function( extra ) {// extra can be a number, shortcut for increasing-calling-decreasing\n\t\t\tif ( !this.multiline )\n\t\t\t\treturn '';\n\t\t\tvar chr = this.indentChar;\n\t\t\tif ( this.HTML )\n\t\t\t\tchr = chr.replace(/\\t/g,'   ').replace(/ /g,'&nbsp;');\n\t\t\treturn Array( this._depth_ + (extra||0) ).join(chr);\n\t\t},\n\t\tup:function( a ) {\n\t\t\tthis._depth_ += a || 1;\n\t\t},\n\t\tdown:function( a ) {\n\t\t\tthis._depth_ -= a || 1;\n\t\t},\n\t\tsetParser:function( name, parser ) {\n\t\t\tthis.parsers[name] = parser;\n\t\t},\n\t\t// The next 3 are exposed so you can use them\n\t\tquote:quote,\n\t\tliteral:literal,\n\t\tjoin:join,\n\t\t//\n\t\t_depth_: 1,\n\t\t// This is the list of parsers, to modify them, use jsDump.setParser\n\t\tparsers:{\n\t\t\twindow: '[Window]',\n\t\t\tdocument: '[Document]',\n\t\t\terror:'[ERROR]', //when no parser is found, shouldn't happen\n\t\t\tunknown: '[Unknown]',\n\t\t\t'null':'null',\n\t\t\t'undefined':'undefined',\n\t\t\t'function':function( fn ) {\n\t\t\t\tvar ret = 'function',\n\t\t\t\t\tname = 'name' in fn ? fn.name : (reName.exec(fn)||[])[1];//functions never have name in IE\n\t\t\t\tif ( name )\n\t\t\t\t\tret += ' ' + name;\n\t\t\t\tret += '(';\n\n\t\t\t\tret = [ ret, QUnit.jsDump.parse( fn, 'functionArgs' ), '){'].join('');\n\t\t\t\treturn join( ret, QUnit.jsDump.parse(fn,'functionCode'), '}' );\n\t\t\t},\n\t\t\tarray: array,\n\t\t\tnodelist: array,\n\t\t\targuments: array,\n\t\t\tobject:function( map, stack ) {\n\t\t\t\tvar ret = [ ];\n\t\t\t\tQUnit.jsDump.up();\n\t\t\t\tfor ( var key in map ) {\n\t\t\t\t    var val = map[key];\n\t\t\t\t\tret.push( QUnit.jsDump.parse(key,'key') + ': ' + QUnit.jsDump.parse(val, undefined, stack));\n                }\n\t\t\t\tQUnit.jsDump.down();\n\t\t\t\treturn join( '{', ret, '}' );\n\t\t\t},\n\t\t\tnode:function( node ) {\n\t\t\t\tvar open = QUnit.jsDump.HTML ? '&lt;' : '<',\n\t\t\t\t\tclose = QUnit.jsDump.HTML ? '&gt;' : '>';\n\n\t\t\t\tvar tag = node.nodeName.toLowerCase(),\n\t\t\t\t\tret = open + tag;\n\n\t\t\t\tfor ( var a in QUnit.jsDump.DOMAttrs ) {\n\t\t\t\t\tvar val = node[QUnit.jsDump.DOMAttrs[a]];\n\t\t\t\t\tif ( val )\n\t\t\t\t\t\tret += ' ' + a + '=' + QUnit.jsDump.parse( val, 'attribute' );\n\t\t\t\t}\n\t\t\t\treturn ret + close + open + '/' + tag + close;\n\t\t\t},\n\t\t\tfunctionArgs:function( fn ) {//function calls it internally, it's the arguments part of the function\n\t\t\t\tvar l = fn.length;\n\t\t\t\tif ( !l ) return '';\n\n\t\t\t\tvar args = Array(l);\n\t\t\t\twhile ( l-- )\n\t\t\t\t\targs[l] = String.fromCharCode(97+l);//97 is 'a'\n\t\t\t\treturn ' ' + args.join(', ') + ' ';\n\t\t\t},\n\t\t\tkey:quote, //object calls it internally, the key part of an item in a map\n\t\t\tfunctionCode:'[code]', //function calls it internally, it's the content of the function\n\t\t\tattribute:quote, //node calls it internally, it's an html attribute value\n\t\t\tstring:quote,\n\t\t\tdate:quote,\n\t\t\tregexp:literal, //regex\n\t\t\tnumber:literal,\n\t\t\t'boolean':literal\n\t\t},\n\t\tDOMAttrs:{//attributes to dump from nodes, name=>realName\n\t\t\tid:'id',\n\t\t\tname:'name',\n\t\t\t'class':'className'\n\t\t},\n\t\tHTML:false,//if true, entities are escaped ( <, >, \\t, space and \\n )\n\t\tindentChar:'  ',//indentation unit\n\t\tmultiline:true //if true, items in a collection, are separated by a \\n, else just a space.\n\t};\n\n\treturn jsDump;\n})();\n\n// from Sizzle.js\nfunction getText( elems ) {\n\tvar ret = \"\", elem;\n\n\tfor ( var i = 0; elems[i]; i++ ) {\n\t\telem = elems[i];\n\n\t\t// Get the text from text nodes and CDATA nodes\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 4 ) {\n\t\t\tret += elem.nodeValue;\n\n\t\t// Traverse everything else, except comment nodes\n\t\t} else if ( elem.nodeType !== 8 ) {\n\t\t\tret += getText( elem.childNodes );\n\t\t}\n\t}\n\n\treturn ret;\n};\n\n//from jquery.js\nfunction inArray( elem, array ) {\n\tif ( array.indexOf ) {\n\t\treturn array.indexOf( elem );\n\t}\n\n\tfor ( var i = 0, length = array.length; i < length; i++ ) {\n\t\tif ( array[ i ] === elem ) {\n\t\t\treturn i;\n\t\t}\n\t}\n\n\treturn -1;\n}\n\n/*\n * Javascript Diff Algorithm\n *  By John Resig (http://ejohn.org/)\n *  Modified by Chu Alan \"sprite\"\n *\n * Released under the MIT license.\n *\n * More Info:\n *  http://ejohn.org/projects/javascript-diff-algorithm/\n *\n * Usage: QUnit.diff(expected, actual)\n *\n * QUnit.diff(\"the quick brown fox jumped over\", \"the quick fox jumps over\") == \"the  quick <del>brown </del> fox <del>jumped </del><ins>jumps </ins> over\"\n */\nQUnit.diff = (function() {\n\tfunction diff(o, n) {\n\t\tvar ns = {};\n\t\tvar os = {};\n\n\t\tfor (var i = 0; i < n.length; i++) {\n\t\t\tif (ns[n[i]] == null)\n\t\t\t\tns[n[i]] = {\n\t\t\t\t\trows: [],\n\t\t\t\t\to: null\n\t\t\t\t};\n\t\t\tns[n[i]].rows.push(i);\n\t\t}\n\n\t\tfor (var i = 0; i < o.length; i++) {\n\t\t\tif (os[o[i]] == null)\n\t\t\t\tos[o[i]] = {\n\t\t\t\t\trows: [],\n\t\t\t\t\tn: null\n\t\t\t\t};\n\t\t\tos[o[i]].rows.push(i);\n\t\t}\n\n\t\tfor (var i in ns) {\n\t\t\tif ( !hasOwn.call( ns, i ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (ns[i].rows.length == 1 && typeof(os[i]) != \"undefined\" && os[i].rows.length == 1) {\n\t\t\t\tn[ns[i].rows[0]] = {\n\t\t\t\t\ttext: n[ns[i].rows[0]],\n\t\t\t\t\trow: os[i].rows[0]\n\t\t\t\t};\n\t\t\t\to[os[i].rows[0]] = {\n\t\t\t\t\ttext: o[os[i].rows[0]],\n\t\t\t\t\trow: ns[i].rows[0]\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tfor (var i = 0; i < n.length - 1; i++) {\n\t\t\tif (n[i].text != null && n[i + 1].text == null && n[i].row + 1 < o.length && o[n[i].row + 1].text == null &&\n\t\t\tn[i + 1] == o[n[i].row + 1]) {\n\t\t\t\tn[i + 1] = {\n\t\t\t\t\ttext: n[i + 1],\n\t\t\t\t\trow: n[i].row + 1\n\t\t\t\t};\n\t\t\t\to[n[i].row + 1] = {\n\t\t\t\t\ttext: o[n[i].row + 1],\n\t\t\t\t\trow: i + 1\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tfor (var i = n.length - 1; i > 0; i--) {\n\t\t\tif (n[i].text != null && n[i - 1].text == null && n[i].row > 0 && o[n[i].row - 1].text == null &&\n\t\t\tn[i - 1] == o[n[i].row - 1]) {\n\t\t\t\tn[i - 1] = {\n\t\t\t\t\ttext: n[i - 1],\n\t\t\t\t\trow: n[i].row - 1\n\t\t\t\t};\n\t\t\t\to[n[i].row - 1] = {\n\t\t\t\t\ttext: o[n[i].row - 1],\n\t\t\t\t\trow: i - 1\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\to: o,\n\t\t\tn: n\n\t\t};\n\t}\n\n\treturn function(o, n) {\n\t\to = o.replace(/\\s+$/, '');\n\t\tn = n.replace(/\\s+$/, '');\n\t\tvar out = diff(o == \"\" ? [] : o.split(/\\s+/), n == \"\" ? [] : n.split(/\\s+/));\n\n\t\tvar str = \"\";\n\n\t\tvar oSpace = o.match(/\\s+/g);\n\t\tif (oSpace == null) {\n\t\t\toSpace = [\" \"];\n\t\t}\n\t\telse {\n\t\t\toSpace.push(\" \");\n\t\t}\n\t\tvar nSpace = n.match(/\\s+/g);\n\t\tif (nSpace == null) {\n\t\t\tnSpace = [\" \"];\n\t\t}\n\t\telse {\n\t\t\tnSpace.push(\" \");\n\t\t}\n\n\t\tif (out.n.length == 0) {\n\t\t\tfor (var i = 0; i < out.o.length; i++) {\n\t\t\t\tstr += '<del>' + out.o[i] + oSpace[i] + \"</del>\";\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tif (out.n[0].text == null) {\n\t\t\t\tfor (n = 0; n < out.o.length && out.o[n].text == null; n++) {\n\t\t\t\t\tstr += '<del>' + out.o[n] + oSpace[n] + \"</del>\";\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (var i = 0; i < out.n.length; i++) {\n\t\t\t\tif (out.n[i].text == null) {\n\t\t\t\t\tstr += '<ins>' + out.n[i] + nSpace[i] + \"</ins>\";\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tvar pre = \"\";\n\n\t\t\t\t\tfor (n = out.n[i].row + 1; n < out.o.length && out.o[n].text == null; n++) {\n\t\t\t\t\t\tpre += '<del>' + out.o[n] + oSpace[n] + \"</del>\";\n\t\t\t\t\t}\n\t\t\t\t\tstr += \" \" + out.n[i].text + nSpace[i] + pre;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn str;\n\t};\n})();\n\n})(this);\n"
  }
]