[
  {
    "path": ".dockerignore",
    "content": "node_modules\n"
  },
  {
    "path": ".gitignore",
    "content": ".idea\n*.iml\n*.tmproj\n*.sublime-workspace\n.project\nnode_modules"
  },
  {
    "path": ".jshintrc",
    "content": "{\n\t\"maxerr\": 1000,\n\n\t\"predef\": [\n\t\t\"exports\",\n\t\t\"describe\",\n\t\t\"expect\",\n\t\t\"it\",\n\t\t\"beforeEach\",\n\t\t\"afterEach\",\n\t\t\"jasmine\",\n\t\t\"test\",\n\t\t\"spyOn\"\n\t],\n\n\t\"jquery\" : true,\n\t\"browser\" : true,\n\n\t\"curly\": true,\n\t\"debug\": false,\n\t\"devel\": true,\n\t\"eqeqeq\": true,\n\t\"eqnull\": true,\n\t\"expr\": true,\n\t\"forin\": false,\n\t\"immed\": false,\n\t\"latedef\": true,\n\t\"newcap\": true,\n\t\"noarg\": true,\n\t\"noempty\": false,\n\t\"nonew\": false,\n\t\"nomen\": false,\n\t\"plusplus\": false,\n\t\"regexp\": false,\n\t\"undef\": true,\n\t\"sub\": true,\n\t\"white\": false,\n\t\"scripturl\": true,\n\t\"esnext\": true\n}\n"
  },
  {
    "path": "Dockerfile",
    "content": "FROM node\nMAINTAINER Niko Bellic <niko.bellic@kakaocorp.com>\n\nRUN mkdir -p /usr/src/app\nWORKDIR /usr/src/app\n\nRUN npm install -g grunt\n\nCOPY package.json /usr/src/app/package.json\nRUN npm install\n\nCOPY . /usr/src/app\n\nEXPOSE 9100\n\nCMD grunt server\n"
  },
  {
    "path": "Dockerfile-alpine",
    "content": "# docker build -t mobz/elasticsearch-head:5-alpine -f Dockerfile-alpine .\n\nFROM node:alpine\nWORKDIR /usr/src/app\nRUN npm install http-server\nCOPY . .\nEXPOSE 9100\nCMD node_modules/http-server/bin/http-server _site -p 9100\n"
  },
  {
    "path": "Gruntfile.js",
    "content": "module.exports = function(grunt) {\n\n\tvar fileSets = require(\"./grunt_fileSets.js\");\n\n\t// Project configuration.\n\tgrunt.initConfig({\n\t\tclean: {\n\t\t\t_site: {\n\t\t\t\tsrc: ['_site']\n\t\t\t}\n\t\t},\n\t\tconcat: {\n\t\t\tvendorjs: {\n\t\t\t\tsrc: fileSets.vendorJs,\n\t\t\t\tdest: '_site/vendor.js'\n\t\t\t},\n\t\t\tvendorcss: {\n\t\t\t\tsrc: fileSets.vendorCss,\n\t\t\t\tdest: '_site/vendor.css'\n\t\t\t},\n\t\t\tappjs: {\n\t\t\t\tsrc: fileSets.srcJs,\n\t\t\t\tdest: '_site/app.js'\n\t\t\t},\n\t\t\tappcss: {\n\t\t\t\tsrc: fileSets.srcCss,\n\t\t\t\tdest: '_site/app.css'\n\t\t\t}\n\t\t},\n\n\t\tcopy: {\n\t\t\tsite_index: {\n\t\t\t\tsrc: 'index.html',\n\t\t\t\tdest: '_site/index.html',\n\t\t\t\toptions: {\n\t\t\t\t\tprocess: function( src ) {\n\t\t\t\t\t\treturn src.replace(/_site\\//g, \"\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tbase: {\n\t\t\t\texpand: true,\n\t\t\t\tcwd: 'src/app/base/',\n\t\t\t\tsrc: [ '*.gif', '*.png', '*.css' ],\n\t\t\t\tdest: '_site/base/'\n\t\t\t},\n\t\t\ticonFonts: {\n\t\t\t\texpand: true,\n\t\t\t\tcwd: 'src/vendor/font-awesome/fonts/',\n\t\t\t\tsrc: '**',\n\t\t\t\tdest: '_site/fonts'\n\t\t\t},\n\t\t\ti18n: {\n\t\t\t\tsrc: 'src/vendor/i18n/i18n.js',\n\t\t\t\tdest: '_site/i18n.js'\n\t\t\t},\n\t\t\tlang: {\n\t\t\t\texpand: true,\n\t\t\t\tcwd: 'src/app/lang/',\n\t\t\t\tsrc: '**',\n\t\t\t\tdest: '_site/lang/'\n\t\t\t},\n\t\t\tchrome: {\n\t\t\t\tsrc: 'src/chrome_ext/*.*',\n\t\t\t\tdest: '_site/'\n\t\t\t}\n\t\t},\n\n\t\tjasmine: {\n\t\t\ttask: {\n\t\t\t\tsrc: [ fileSets.vendorJs, 'src/vendor/i18n/i18n.js', 'src/app/lang/en_strings.js', fileSets.srcJs ],\n\t\t\t\toptions: {\n\t\t\t\t\tspecs: 'src/app/**/*Spec.js',\n\t\t\t\t\thelpers: 'test/spec/*Helper.js',\n\t\t\t\t\tdisplay: \"short\",\n\t\t\t\t\tsummary: true\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\twatch: {\n\t\t\t\"scripts\": {\n\t\t\t\tfiles: ['src/**/*', 'test/spec/*' ],\n\t\t\t\ttasks: ['default'],\n\t\t\t\toptions: {\n\t\t\t\t\tspawn: false\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"grunt\": {\n\t\t\t\tfiles: [ 'Gruntfile.js' ]\n\t\t\t}\n\t\t},\n\n\t\tconnect: {\n\t\t\tserver: {\n\t\t\t\toptions: {\n\t\t\t\t\tport: 9100,\n\t\t\t\t\tbase: '.',\n\t\t\t\t\tkeepalive: true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t});\n\n\tgrunt.loadNpmTasks('grunt-contrib-clean');\n\tgrunt.loadNpmTasks('grunt-contrib-concat');\n\tgrunt.loadNpmTasks('grunt-contrib-watch');\n\tgrunt.loadNpmTasks('grunt-contrib-connect');\n\tgrunt.loadNpmTasks('grunt-contrib-copy');\n\tgrunt.loadNpmTasks('grunt-contrib-jasmine');\n\n\t// Default task(s).\n\tgrunt.registerTask('default', ['clean', 'concat', 'copy', 'jasmine']);\n\tgrunt.registerTask('server', ['connect:server']);\n\tgrunt.registerTask('dev', [ 'default', 'watch' ]);\n\n\n};\n"
  },
  {
    "path": "LICENCE",
    "content": "Copyright 2010-2013 Ben Birch\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this software except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
  },
  {
    "path": "README.textile",
    "content": "h1. elasticsearch-head\n\nh2. A web front end for an Elasticsearch cluster\n\nh3. \"http://mobz.github.io/elasticsearch-head\":http://mobz.github.io/elasticsearch-head\n\nh2. Running\n\nThere are multiple ways of running elasticsearch-head.\n\nh4. Running with built in server\n\n* @git clone git://github.com/mobz/elasticsearch-head.git@\n* @cd elasticsearch-head@\n* @npm install@\n* @npm run start@\n\n* @open@ \"http://localhost:9100/\":http://localhost:9100/\n\nThis will start a local webserver running on port 9100 serving elasticsearch-head\n\nh4. Running with docker\n\n* for Elasticsearch 5.x: @docker run -p 9100:9100 mobz/elasticsearch-head:5@\n* for Elasticsearch 2.x: @docker run -p 9100:9100 mobz/elasticsearch-head:2@\n* for Elasticsearch 1.x: @docker run -p 9100:9100 mobz/elasticsearch-head:1@\n* for fans of alpine there is @mobz/elasticsearch-head:5-alpine@\n  \n* @open@ \"http://localhost:9100/\":http://localhost:9100/\n\nh4. Running as a Chrome extension\n\n* Install \"ElasticSearch Head\":https://chrome.google.com/webstore/detail/elasticsearch-head/ffmkiejjmecolpfloofpjologoblkegm/ from the Chrome Web Store.\n* Click the extension icon in the toolbar of your web browser.\n* Note that you don't need to \"enable CORS\":#enable-cors-in-elasticsearch with this method.\n\nh4. Running as a plugin of Elasticsearch (deprecated)\n\n* for Elasticsearch 5.x, 6.x, and 7.x: site plugins are not supported. Run \"as a standalone server\":#running-with-built-in-server\n* for Elasticsearch 2.x: @sudo elasticsearch/bin/plugin install mobz/elasticsearch-head@\n* for Elasticsearch 1.x: @sudo elasticsearch/bin/plugin -install mobz/elasticsearch-head/1.x@\n* for Elasticsearch 0.x: @sudo elasticsearch/bin/plugin -install mobz/elasticsearch-head/0.9@\n\n* @open http://localhost:9200/_plugin/head/@\n\nThis will automatically download the appropriate version of elasticsearch-head from github and run it as a plugin within the elasticsearch cluster. In this mode elasticsearch-head automatically connects to the node that is running it\n\nh4. Running with the local proxy\n\nThis is an _experimental feature_ which creates a local proxy for many remote elasticsearch clusters\n\n* configure clusters in proxy/clusters\n* create a file per remote cluster you want to connect to ( see @localhost9200.json@ as example )\n* requires node >= 6.0 \n* @npm install@\n* @npm run proxy@\n\nAt the moment it only works with @grunt server@ running on http://localhost:9100\n\nh4. Alternatives\n\n* File System: elastisearch-head is a standalone webapp written in good-ol' html5. This means, you can put it up on any webserver, run it directly from the filesystem. It'll even fit on a floppy disk.\n* DEB package: There is an unofficial deb package. the plugin executable will be available at @/usr/share/elasticsearch/bin/plugin@.\n* Homebrew: There is an unofficial keg. The plugin executable will be available at @/usr/local/Cellar/elasticsearch/(elasticsearch version)/libexec/bin/plugin@.\n\nh3. Connecting to elasticsearch\n\nBy default elasticsearch exposes a http rest API on port 9200 which elasticsearch-head connects to.\n\nh4. Enable CORS in elasticsearch\n\nWhen not running as a Chrome extension or as a plugin of elasticsearch (which is not even possible from version 5), you must enable \"CORS\":https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-http.html in elasticsearch, or else your browser will reject elasticsearch-head's requests due to violation of the same-origin policy.\n\nIn elasticsearch configuration;\n\n* add @http.cors.enabled: true@\n* you must also set @http.cors.allow-origin@ because no origin allowed by default. @http.cors.allow-origin: \"*\"@ is valid value, however it's considered as a security risk as your cluster is open to cross origin from *anywhere*.\n\nh4. Basic Authentication\n\nelasticsearch-head will add basic auth headers to each request if you pass in the \"correct url parameters\":#url-parameters\nYou will also need to add @http.cors.allow-headers: Authorization@ to the elasticsearch configuration\n\nh4. x-pack\n\nelasticsearch x-pack requires basic authentication _and_ CORS as described above. Make sure you have the correct CORS setup and then open es-head with a url like \"http://localhost:9100/?auth_user=elastic&auth_password=changeme\"\n\nh4. URL Parameters\n\nParameters may be appended to the url to set an initial state eg. @head/index.html?base_uri=http://node-01.example.com:9200@\n\n* @base_uri@ force elasticsearch-head to connect to a particular node.\n* @dashboard@ experimental feature to open elasticsearch-head in a mode suitable for dashboard / radiator. Accepts one parameter @dashboard=cluster@\n* @auth_user@ adds basic auth credentials to http requests ( requires \"elasticsearch-http-basic\":https://github.com/karussell/elasticsearch-http-basic plugin or a reverse proxy )\n* @auth_password@ basic auth password as above (note: without \"additional security layers\":http://security.stackexchange.com/questions/988/is-basic-auth-secure-if-done-over-https, passwords are sent over the network *in the clear* )\n* @lang@ force elasticsearch-head to use specified ui language (eg: en, fr, pt, zh, zh-TW, tr, ja)\n\nh4. Contributing\n\nTo contribute to elasticsearch-head you will need the following developer tools\n\n# git and a \"github\":https://github.com/ account\n# \"node ( including npm )\":http://nodejs.org/download\n# \"grunt-cli\":http://gruntjs.com/getting-started\n# (to run jasmine tests) \"phantomjs\":http://phantomjs.org\n\nThen\n\n# create a fork of elasticsearch-head on github\n# clone your fork to your machine\n# @cd elasticsearch-head@\n# @npm install@ # downloads node dev dependencies\n# @grunt dev@ # builds the distribution files, then watches the src directory for changes (if you have an warning like \"Warning: Task \"clean\" failed. Use --force to continue.\", well use --force ;) )\n\nChanges to both _site and src directories *must* be committed, to allow people to \nrun elasticsearch-head without running dev tools and follow existing dev patterns, \nsuch as indenting with tabs.\n\nh5. Contributing an Internationalisation\n\n* Simplified Chinese by \"darkcount\":https://github.com/hangxin1940\n* Traditional Chinese by \"kewang\":https://github.com/kewang\n* English (primary) by \"Ben Birch\":https://twitter.com/mobz\n* French by \"David Pilato\":https://twitter.com/dadoonet\n* Portuguese by \"caiodangelo\":https://github.com/caiodangelo\n* Turkish by \"Cemre Mengu\":https://github.com/cemremengu\n* Japanese by \"Satoshi Kimura\":https://github.com/satoshi-kimura\n* Vietnamese by \"Du Tran\":https://github.com/quangdutran\n\nTo contribute an internationalisation\n\n# Follow \"Contributing\" instructions above\n# Find your 2-character \"ISO 639-1 language code\":http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes\n# edit _site/index.html to add your 2 letter language code to the data-langs attribute of this line @<script src=\"_site/i18n.js\" data-baseDir=\"_site/lang\" data-langs=\"en,fr,your_lang_here\"></script>@\n# make a copy of @src/app/langs/en_strings.js@ prefixed with your language code\n# convert english strings and fragments to your language. \"Formatting Rules\":http://docs.oracle.com/javase/tutorial/i18n/format/messageintro.html\n# Submit a pull request\n\n!http://mobz.github.com/elasticsearch-head/screenshots/clusterOverview.png(ClusterOverview Screenshot)!\n"
  },
  {
    "path": "_site/app.css",
    "content": "TABLE.table {\n\tborder-collapse: collapse;\n}\n\n\nTABLE.table TH {\n\tfont-weight: normal;\n\ttext-align: left;\n\tvertical-align: middle;\n}\n\nTABLE.table TBODY.striped TR:nth-child(odd) {\n\tbackground: #eee;\n}\n\nTABLE.table H3 {\n\tmargin: 0;\n\tfont-weight: bold;\n\tfont-size: 140%;\n}\n\n.require { color: #a00; }\n\n.uiButton {\n\tpadding: 0;\n\tborder: 0;\n\tmargin: 3px;\n\twidth: auto;\n\toverflow: visible;\n\tcursor: pointer;\n\tbackground: transparent;\n}\n\n.uiButton-content {\n\theight: 20px;\n\tborder: 1px solid #668dc6;\n\tborder-radius: 2px;\n\tbackground: #96c6eb;\n\tbackground: -moz-linear-gradient(top, #96c6eb, #5296c7);\n\tbackground: -webkit-linear-gradient(top, #96c6eb, #5296c7);\n\tcolor: white;\n\tfont-weight: bold;\n}\n\n.moz .uiButton-content { margin: 0 -2px; }\n\n.uiButton-label {\n\t\tpadding: 2px 6px;\n\t\twhite-space: nowrap;\n}\n.uiButton:hover .uiButton-content {\n\tbackground: #2777ba;\n\tbackground: -moz-linear-gradient(top, #6aaadf, #2777ba);\n\tbackground: -webkit-linear-gradient(top, #6aaadf, #2777ba);\n}\n.uiButton.active .uiButton-content,\n.uiButton:active .uiButton-content {\n\tbackground: #2575b7;\n\tbackground: -moz-linear-gradient(top, #2576b8, #2575b7);\n\tbackground: -webkit-linear-gradient(top, #2576b8, #2575b7);\n}\n.uiButton.disabled .uiButton-content,\n.uiButton.disabled:active .uiButton-content {\n\t\tborder-color: #c6c6c6;\n\t\tcolor: #999999;\n\t\tbackground: #ddd;\n\t\tbackground: -moz-linear-gradient(top, #ddd, #ddd);\n\t\tbackground: -webkit-linear-gradient(top, #ddd, #ddd);\n}\n\n.uiButton.disabled {\n\t\tcursor: default;\n}\n\n.uiMenuButton {\n\tdisplay: inline-block;\n}\n\n.uiMenuButton .uiButton-label {\n\tbackground-image: url('data:image/gif;base64,R0lGODlhDwAPAIABAP///////yH5BAEAAAEALAAAAAAPAA8AAAITjI+py+0P4wG0gmavq1HLD4ZiAQA7');\n\tbackground-position: right 50%;\n\tbackground-repeat: no-repeat;\n\tpadding-right: 17px;\n\ttext-align: left;\n}\n\n.uiSplitButton {\n\twhite-space: nowrap;\n}\n\n.uiSplitButton .uiButton:first-child {\n\tmargin-right: 0;\n\tdisplay: inline-block;\n}\n\n.uiSplitButton .uiButton:first-child .uiButton-content {\n\tborder-right-width: 1;\n\tborder-right-color: #5296c7;\n\tborder-top-right-radius: 0;\n\tborder-bottom-right-radius: 0;\n}\n\n.uiSplitButton .uiMenuButton {\n\tmargin-left: 0;\n}\n\n.uiSplitButton .uiButton:last-child .uiButton-content {\n\tborder-radius: 2px;\n\tborder-left-width: 1;\n\tborder-left-color: #96c6eb;\n\tborder-top-left-radius: 0;\n\tborder-bottom-left-radius: 0;\n\theight: 20px;\n}\n\n.uiSplitButton .uiButton:last-child .uiButton-label {\n\tpadding: 2px 17px 2px 6px;\n\tmargin-left: -8px;\n}\n\n.uiToolbar {\n\theight: 28px;\n\tbackground: #fdfefe;\n\tbackground: -moz-linear-gradient(top, #fdfefe, #eaedef);\n\tbackground: -webkit-linear-gradient(top, #fdfefe, #eaedef);\n\tborder-bottom: 1px solid #d2d5d7;\n\tpadding: 3px 10px;\n}\n\n.uiToolbar H2 {\n\tdisplay: inline-block;\n\tfont-size: 120%;\n\tmargin: 0;\n\tpadding: 5px 20px 5px 0;\n}\n\n.uiToolbar .uiTextField {\n\tdisplay: inline-block;\n}\n\n.uiToolbar .uiTextField INPUT {\n\tpadding-top: 2px;\n\tpadding-bottom: 5px;\n}\n#uiModal {\n\tbackground: black;\n}\n\n.uiPanel {\n\tbox-shadow: -1px 2.5px 4px -3px black, -1px -2.5px 4px -3px black, 3px 2.5px 4px -3px black, 3px -2.5px 4px -3px black;\n\tposition: absolute;\n\tbackground: #eee;\n\tborder: 1px solid #666;\n}\n\n.uiPanel-titleBar {\n\ttext-align: center;\n\tfont-weight: bold;\n\tpadding: 2px 0;\n\tbackground: rgba(223, 223, 223, 0.75);\n\tbackground: -moz-linear-gradient(top, rgba(223, 223, 223, 0.75), rgba(193, 193, 193, 0.75), rgba(223, 223, 223, 0.75));\n\tbackground: -webkit-linear-gradient(top, rgba(223, 223, 223, 0.75), rgba(193, 193, 193, 0.75), rgba(223, 223, 223, 0.75));\n\tborder-bottom: 1px solid #bbb;\n}\n\n.uiPanel-close {\n\tcursor: pointer;\n\tborder: 1px solid #aaa;\n\tbackground: #fff;\n\tcolor: #fff;\n\tfloat: left;\n\theight: 10px;\n\tleft: 3px;\n\tline-height: 9px;\n\tpadding: 1px 0;\n\tposition: relative;\n\ttext-shadow: 0 0 1px #000;\n\ttop: 0px;\n\twidth: 12px;\n}\n.uiPanel-close:hover {\n\tbackground: #eee;\n}\n\n.uiPanel-body {\n\toverflow: auto;\n}\n\n\n.uiInfoPanel {\n\tbackground: rgba(0, 0, 0, 0.75);\n\tcolor: white;\n\tborder-radius: 8px;\n\tpadding: 1px;\n}\n.uiInfoPanel .uiPanel-titleBar {\n\tbackground: rgba(74, 74, 74, 0.75);\n\tbackground: -moz-linear-gradient(top, rgba(84, 84, 84, 0.75), rgba(54, 54, 54, 0.75), rgba(64, 64, 64, 0.75));\n\tbackground: -webkit-linear-gradient(top, rgba(84, 84, 84, 0.75), rgba(54, 54, 54, 0.75), rgba(64, 64, 64, 0.75));\n\tborder-radius: 8px 8px 0 0;\n\tpadding: 1px 0 2px 0;\n\tborder-bottom: 0;\n}\n.uiInfoPanel .uiPanel-close {\n\tborder-radius: 6px;\n\theight: 13px;\n\twidth: 13px;\n\tbackground: #ccc;\n\tleft: 3px;\n\ttop: 1px;\n\tcolor: #333;\n\ttext-shadow: #222 0 0 1px;\n\tline-height: 11px;\n\tborder: 0;\n\tpadding: 0;\n}\n.uiInfoPanel .uiPanel-close:hover {\n\tbackground: #eee;\n}\n\n.uiInfoPanel .uiPanel-body {\n\tbackground: transparent;\n\tpadding: 20px;\n\tborder-radius: 0 0 8px 8px;\n\tborder: 1px solid #222;\n}\n\n.uiMenuPanel {\n\tborder: 1px solid #668dc6;\n\tposition: absolute;\n\tbackground: #96c6eb;\n\tcolor: white;\n}\n\n.uiMenuPanel LI {\n\tlist-style: none;\n\tborder-bottom: 1px solid #668dc6;\n}\n\n.uiMenuPanel LI:hover {\n\tbackground: #2575b7;\n}\n\n.uiMenuPanel LI:last-child {\n\tborder-bottom: 0;\n} \n\n.uiMenuPanel-label {\n\twhite-space: nowrap;\n\tpadding: 2px 10px 2px 10px;\n\tcursor: pointer;\n}\n\n.disabled .uiMenuPanel-label {\n\tcursor: auto;\n\tcolor: #888;\n}\n\n.uiSelectMenuPanel .uiMenuPanel-label {\n\tmargin-left: 1em;\n\tpadding-left: 4px;\n}\n\n.uiSelectMenuPanel .uiMenuPanel-item.selected .uiMenuPanel-label:before {\n\tcontent: \"\\2713\";\n\twidth: 12px;\n\tmargin-left: -12px;\n\tdisplay: inline-block;\n}\n\n.uiTable TABLE {\n\tborder-collapse: collapse;\n}\n\n.uiTable-body {\n\toverflow-y: scroll;\n\toverflow-x: auto;\n}\n\n.uiTable-headers {\n\toverflow-x: hidden;\n}\n\n.uiTable-body TD {\n\twhite-space: nowrap;\n}\n\n.uiTable-body .uiTable-header-row TH,\n.uiTable-body .uiTable-header-row TH DIV {\n\tpadding-top: 0;\n\tpadding-bottom: 0;\n}\n\n.uiTable-body .uiTable-header-cell > DIV {\n\theight: 0;\n\toverflow: hidden;\n}\n\n.uiTable-headercell-menu {\n\tfloat: right;\n}\n\n.uiTable-tools {\n\tpadding: 3px 4px;\n\theight: 14px;\n}\n\n.uiTable-header-row {\n\tbackground: #ddd;\n\tbackground: -moz-linear-gradient(top, #eee, #ccc);\n\tbackground: -webkit-linear-gradient(top, #eee, #ccc);\n}\n\n.uiTable-headercell-text {\n\tmargin-right: 20px;\n}\n\n.uiTable-headercell-menu {\n\tdisplay: none;\n}\n\n.uiTable-header-row TH {\n\tborder-right: 1px solid #bbb;\n\tpadding: 0;\n\ttext-align: left;\n}\n\n.uiTable-header-row TH > DIV {\n\tpadding: 3px 4px;\n\tborder-right: 1px solid #eee;\n}\n\n.uiTable-headerEndCap > DIV {\n\twidth: 19px;\n}\n\n.uiTable-header-row .uiTable-sort {\n\tbackground: #ccc;\n\tbackground: -moz-linear-gradient(top, #bebebe, #ccc);\n\tbackground: -webkit-linear-gradient(top, #bebebe, #ccc);\n}\n.uiTable-header-row TH.uiTable-sort > DIV {\n\tborder-right: 1px solid #ccc;\n}\n\n.uiTable-sort .uiTable-headercell-menu {\n\tdisplay: block;\n}\n\n.uiTable TABLE TD {\n\tborder-right: 1px solid transparent;\n\tpadding: 3px 4px;\n}\n\n.uiTable-body TABLE TR:nth-child(even) {\n\tbackground: #f3f3f3;\n}\n\n.uiTable-body TABLE TR.selected {\n\tcolor: white;\n\tbackground: #6060f1;\n}\n\nDIV.uiJsonPretty-object { font-size: 1.26em; font-family: monospace; }\nUL.uiJsonPretty-object,\nUL.uiJsonPretty-array { margin: 0; padding: 0 0 0 2em; list-style: none; }\nUL.uiJsonPretty-object LI,\nUL.uiJsonPretty-array LI { padding: 0; margin: 0; }\n.expando > SPAN.uiJsonPretty-name:before { content: \"\\25bc\\a0\"; color: #555; position: relative; top: 2px; }\n.expando.uiJsonPretty-minimised > SPAN.uiJsonPretty-name:before { content: \"\\25ba\\a0\"; top: 0; }\n.uiJsonPretty-minimised > UL SPAN.uiJsonPretty-name:before,\n.expando .uiJsonPretty-minimised > UL SPAN.uiJsonPretty-name:before { content: \"\"; }\nSPAN.uiJsonPretty-string,\nSPAN.uiJsonPretty-string A { color: green; }\nSPAN.uiJsonPretty-string A { text-decoration: underline;}\nSPAN.uiJsonPretty-number { color: blue; }\nSPAN.uiJsonPretty-null { color: red; }\nSPAN.uiJsonPretty-boolean { color: purple; }\n.expando > .uiJsonPretty-name { cursor: pointer; }\n.expando > .uiJsonPretty-name:hover { text-decoration: underline; }\n.uiJsonPretty-minimised { white-space: nowrap; overflow: hidden; }\n.uiJsonPretty-minimised > UL { opacity: 0.6; }\n.uiJsonPretty-minimised .uiJsonPretty-minimised > UL { opacity: 1; }\n.uiJsonPretty-minimised UL, .uiJsonPretty-minimised LI { display: inline; padding: 0; }\n\n\n.uiJsonPanel SPAN.uiJsonPretty-string { color: #6F6; }\n.uiJsonPanel SPAN.uiJsonPretty-number { color: #66F; }\n.uiJsonPanel SPAN.uiJsonPretty-null { color: #F66; }\n.uiJsonPanel SPAN.uiJsonPretty-boolean { color: #F6F; }\n\n.uiPanelForm-field {\n\tdisplay: block;\n\tpadding: 2px 0;\n\tclear: both;\n}\n\n.uiPanelForm-label {\n\tfloat: left;\n\twidth: 200px;\n\tpadding: 3px 7px;\n\ttext-align: right;\n}\n\n.uiSidebarSection-head {\n\tbackground-color: #b9cfff;\n\tbackground-image: url('data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAcCAMAAABifa5OAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAMAUExURQUCFf///wICAgMDAwQEBAUFBQYGBgcHBwgICAkJCQoKCgsLCwwMDA0NDQ4ODg8PDxAQEBERERISEhMTExQUFBUVFRYWFhcXFxgYGBkZGRoaGhsbGxwcHB0dHR4eHh8fHyAgICEhISIiIiMjIyQkJCUlJSYmJicnJygoKCkpKSoqKisrKywsLC0tLS4uLi8vLzAwMDExMTIyMjMzMzQ0NDU1NTY2Njc3Nzg4ODk5OTo6Ojs7Ozw8PD09PT4+Pj8/P0BAQEFBQUJCQkNDQ0REREVFRUZGRkdHR0hISElJSUpKSktLS0xMTE1NTU5OTk9PT1BQUFFRUVJSUlNTU1RUVFVVVVZWVldXV1hYWFlZWVpaWltbW1xcXF1dXV5eXl9fX2BgYGFhYWJiYmNjY2RkZGVlZWZmZmdnZ2hoaGlpaWpqamtra2xsbG1tbW5ubm9vb3BwcHFxcXJycnNzc3R0dHV1dXZ2dnd3d3h4eHl5eXp6ent7e3x8fH19fX5+fn9/f4CAgIGBgYKCgoODg4SEhIWFhYaGhoeHh4iIiImJiYqKiouLi4yMjI2NjY6Ojo+Pj5CQkJGRkZKSkpOTk5SUlJWVlZaWlpeXl5iYmJmZmZqampubm5ycnJ2dnZ6enp+fn6CgoKGhoaKioqOjo6SkpKWlpaampqenp6ioqKmpqaqqqqurq6ysrK2tra6urq+vr7CwsLGxsbKysrOzs7S0tLW1tba2tre3t7i4uLm5ubq6uru7u7y8vL29vb6+vr+/v8DAwMHBwcLCwsPDw8TExMXFxcbGxsfHx8jIyMnJycrKysvLy8zMzM3Nzc7Ozs/Pz9DQ0NHR0dLS0tPT09TU1NXV1dbW1tfX19jY2NnZ2dra2tvb29zc3N3d3d7e3t/f3+Dg4OHh4eLi4uPj4+Tk5OXl5ebm5ufn5+jo6Onp6erq6uvr6+zs7O3t7e7u7u/v7/Dw8PHx8fLy8vPz8/T09PX19fb29vf39/j4+Pn5+fr6+vv7+/z8/P39/f7+/v///2Oyy/cAAAACdFJOU/8A5bcwSgAAADxJREFUeNq8zzkOACAMA8Hd/3+agiuRcIsrRopIjArOoLK1QAMNNBCRPkhLyzkn35Bjfd7JR1Nr09NoDACnvgDl1zlzoQAAAABJRU5ErkJggg==');\n\tbackground-repeat: no-repeat;\n\tbackground-position: 2px 5px;\n\tmargin-bottom: 1px;\n\tpadding: 3px 3px 3px 17px;\n\tcursor: pointer;\n}\n\n.shown > .uiSidebarSection-head {\n\tbackground-position: 2px -13px;\n}\n\n.uiSidebarSection-body {\n\tmargin-bottom: 3px;\n\tdisplay: none;\n}\n\n.uiSidebarSection-help {\n\ttext-shadow: #228 1px 1px 2px;\n\tcolor: blue;\n\tcursor: pointer;\n}\n\n.uiSidebarSection-help:hover {\n\ttext-decoration: underline;\n}\n\n.uiQueryFilter {\n\twidth: 350px;\n\tpadding: 5px;\n\tbackground: #d8e7ff;\n\tbackground: -moz-linear-gradient(left, #d8e7ff, #e8f1ff);\n\tbackground: -webkit-linear-gradient(left, #d8e7ff, #e8f1ff);\n}\n\n.uiQueryFilter DIV.uiQueryFilter-section {\n\tmargin-bottom: 5px;\n}\n\n.uiQueryFilter HEADER {\n\tdisplay: block;\n\tfont-variant: small-caps;\n\tfont-weight: bold;\n\tmargin: 5px 0;\n}\n\n.uiQueryFilter-aliases SELECT {\n\twidth: 100%;\n}\n\n.uiQueryFilter-booble {\n\tcursor: pointer;\n\tbackground: #e8f1ff;\n\tborder: 1px solid #e8f1ff;\n\tborder-radius: 5px;\n\tpadding: 1px 4px;\n\tmargin-bottom: 1px;\n\toverflow: hidden;\n\twhite-space: nowrap;\n}\n\n.uiQueryFilter-booble.selected {\n\tbackground: #dae3f0;\n\tborder-top: 1px solid #c8d4e6;\n\tborder-left: 1px solid #c8d4e6;\n\tborder-bottom: 1px solid #ffffff;\n\tborder-right: 1px solid #ffffff;\n}\n\n.uiQueryFilter-filterName {\n\tbackground-color: #cbdfff;\n\tmargin-bottom: 4px;\n\tpadding: 3px;\n\tcursor: pointer;\n}\n\n.uiQueryFilter-filters INPUT  {\n\twidth: 300px;\n}\n\n.uiQueryFilter-subMultiFields {\n\tpadding-left: 10px;\n}\n\n.uiQueryFilter-rangeHintFrom,\n.uiQueryFilter-rangeHintTo {\n\tmargin: 0;\n\topacity: 0.75;\n}\n.uiBrowser-filter {\n\tfloat: left;\n}\n\n.uiBrowser-table {\n\tmargin-left: 365px;\n}\n\n.uiAnyRequest-request {\n\tfloat: left;\n\twidth: 350px;\n\tpadding: 5px;\n\tbackground: #d8e7ff;\n\tbackground: -moz-linear-gradient(left, #d8e7ff, #e8f1ff);\n\tbackground: -webkit-linear-gradient(left, #d8e7ff, #e8f1ff);\n}\n\n.uiAnyRequest-request INPUT[type=text],\n.uiAnyRequest-request TEXTAREA {\n\twidth: 340px;\n}\n\n.anyRequest INPUT[name=path] {\n\twidth: 259px;\n}\n\n.uiAnyRequest-out {\n\tmargin-left: 365px;\n}\n\n.uiAnyRequest-out P {\n\tmargin-top: 0;\n}\n\n.uiAnyRequest-jsonErr {\n\tcolor: red;\n}\n\n.uiAnyRequest-history {\n\tmargin: 0;\n\tpadding: 0;\n\tlist-style: none;\n\tmax-height: 100px;\n\toverflow-x: hidden;\n\toverflow-y: auto;\n}\n\n.uiNodesView TH,\n.uiNodesView TD {\n\tvertical-align: top;\n\tpadding: 2px 20px;\n}\n\n.uiNodesView TH.close,\n.uiNodesView TD.close {\n\tcolor: #888;\n\tbackground: #f2f2f2;\n}\n\n.uiNodesView .uiMenuButton .uiButton-content {\n\tpadding-right: 3px;\n\tborder-radius: 8px;\n\theight: 14px;\n}\n\n.uiNodesView .uiMenuButton.active .uiButton-content,\n.uiNodesView .uiMenuButton:active .uiButton-content {\n\tborder-bottom-right-radius: 0px;\n\tborder-bottom-left-radius: 0px;\n}\n\n.uiNodesView .uiMenuButton .uiButton-label {\n\tpadding: 0px 17px 0px 7px;\n}\n\n.uiNodesView-hasAlias {\n\ttext-align: center;\n}\n.uiNodesView-hasAlias.max {\n\tborder-top-right-radius: 8px;\n\tborder-bottom-right-radius: 8px;\n}\n.uiNodesView-hasAlias.min {\n\tborder-top-left-radius: 8px;\n\tborder-bottom-left-radius: 8px;\n}\n.uiNodesView-hasAlias-remove {\n\tfloat: right;\n\tfont-weight: bold;\n\tcursor: pointer;\n}\n\n.uiNodesView TD.uiNodesView-icon {\n\tpadding: 20px 0px 15px 20px;\n}\n\n.uiNodesView-node:nth-child(odd) {\n\tbackground: #eee;\n}\n\n.uiNodesView-routing {\n\tposition: relative;\n\tmin-width: 90px;\n}\n\n.uiNodesView-nullReplica,\n.uiNodesView-replica {\n\tbox-sizing: border-box;\n\tcursor: pointer;\n\tfloat: left;\n\theight: 40px;\n\twidth: 35px;\n\tmargin: 4px;\n\tborder: 2px solid #444;\n\tpadding: 2px;\n\tfont-size: 32px;\n\tline-height: 32px;\n\ttext-align: center;\n\tletter-spacing: -5px;\n\ttext-indent: -7px;\n}\n\n.uiNodesView-replica.primary {\n\tborder-width: 4px;\n\tline-height: 29px;\n}\n\n.uiNodesView-nullReplica {\n\tborder-color: transparent;\n}\n\n.uiNodesView-replica.state-UNASSIGNED { background: #eeeeee; color: #999; border-color: #666; float: none; display: inline-block; }\n.uiNodesView-replica.state-INITIALIZING { background: #dddc88; }\n.uiNodesView-replica.state-STARTED { background: #99dd88; }\n.uiNodesView-replica.state-RELOCATING { background: #dc88dd; }\n\n\n.uiClusterConnect-uri {\n\twidth: 280px;\n}\n\n.uiStructuredQuery {\n\tpadding: 10px;\n}\n\n.uiStructuredQuery-out {\n\tmin-height: 30px;\n}\n\n.uiFilterBrowser-row * {\n\tmargin-right: 0.4em;\n}\n\n.uiFilterBrowser-row BUTTON {\n\theight: 22px;\n\tposition: relative;\n\ttop: 1px;\n}\n\n.uiHeader {\n\tpadding: 3px 10px;\n}\n\n.uiHeader-name, .uiHeader-status {\n\tfont-size: 1.2em;\n\tfont-weight: bold;\n\tpadding: 0 10px;\n}\n\n\n.uiApp-header {\n\tbackground: #eee;\n\tposition: fixed;\n\twidth: 100%;\n\tz-index: 9;\n}\n\n.uiApp-header H1 {\n\tmargin: -2px 0 -4px 0;\n\tfloat: left;\n\tpadding-right: 25px;\n}\n\n.uiApp-headerMenu {\n\tborder-bottom: 1px solid #bbb;\n\tpadding: 0px 3px;\n\theight: 22px;\n}\n\n.uiApp-headerMenu .active {\n\tbackground: white;\n\tborder-bottom-color: white;\n}\n\n.uiApp-headerMenuItem {\n\tborder: 1px solid #bbb;\n\tpadding: 4px 8px 1px ;\n\tmargin: 2px 1px 0;\n\theight: 14px;\n\tcursor: pointer;\n}\n\n.uiApp-body {\n\tpadding: 51px 0px 0px 0px;\n}\n\n.uiApp-headerNewMenuItem {\n\tcolor: blue;\n}\n"
  },
  {
    "path": "_site/app.js",
    "content": "(function() {\n\n\tvar window = this,\n\t\t$ = jQuery;\n\n\tfunction ns( namespace ) {\n\t\treturn (namespace || \"\").split(\".\").reduce( function( space, name ) {\n\t\t\treturn space[ name ] || ( space[ name ] = { ns: ns } );\n\t\t}, this );\n\t}\n\n\tvar app = ns(\"app\");\n\n\tvar acx = ns(\"acx\");\n\n\t/**\n\t * object iterator, returns an array with one element for each property of the object\n\t * @function\n\t */\n\tacx.eachMap = function(obj, fn, thisp) {\n\t\tvar ret = [];\n\t\tfor(var n in obj) {\n\t\t\tret.push(fn.call(thisp, n, obj[n], obj));\n\t\t}\n\t\treturn ret;\n\t};\n\n\t/**\n\t * augments the first argument with the properties of the second and subsequent arguments\n\t * like {@link $.extend} except that existing properties are not overwritten\n\t */\n\tacx.augment = function() {\n\t\tvar args = Array.prototype.slice.call(arguments),\n\t\t\tsrc = (args.length === 1) ? this : args.shift(),\n\t\t\taugf = function(n, v) {\n\t\t\t\tif(! (n in src)) {\n\t\t\t\t\tsrc[n] = v;\n\t\t\t\t}\n\t\t\t};\n\t\tfor(var i = 0; i < args.length; i++) {\n\t\t\t$.each(args[i], augf);\n\t\t}\n\t\treturn src;\n\t};\n\n\t/**\n\t * tests whether the argument is an array\n\t * @function\n\t */\n\tacx.isArray = $.isArray;\n\n\t/**\n\t * tests whether the argument is an object\n\t * @function\n\t */\n\tacx.isObject = function (value) {\n\t\treturn Object.prototype.toString.call(value) == \"[object Object]\";\n\t};\n\n\t/**\n\t * tests whether the argument is a function\n\t * @function\n\t */\n\tacx.isFunction = $.isFunction;\n\n\t/**\n\t * tests whether the argument is a date\n\t * @function\n\t */\n\tacx.isDate = function (value) {\n\t\treturn Object.prototype.toString.call(value) == \"[object Date]\";\n\t};\n\n\t/**\n\t * tests whether the argument is a regexp\n\t * @function\n\t */\n\tacx.isRegExp = function (value) {\n\t\treturn Object.prototype.toString.call(value) == \"[object RegExp]\";\n\t};\n\n\t/**\n\t * tests whether the value is blank or empty\n\t * @function\n\t */\n\tacx.isEmpty = function (value, allowBlank) {\n\t\treturn value === null || value === undefined || ((acx.isArray(value) && !value.length)) || (!allowBlank ? value === '' : false);\n\t};\n\n\t/**\n\t * data type for performing chainable geometry calculations<br>\n\t * can be initialised x,y | {x, y} | {left, top}\n\t */\n\tacx.vector = function(x, y) {\n\t\treturn new acx.vector.prototype.Init(x, y);\n\t};\n\n\tacx.vector.prototype = {\n\t\tInit : function(x, y) {\n\t\t\tx = x || 0;\n\t\t\tthis.y = isFinite(x.y) ? x.y : (isFinite(x.top) ? x.top : (isFinite(y) ? y : 0));\n\t\t\tthis.x = isFinite(x.x) ? x.x : (isFinite(x.left) ? x.left : (isFinite(x) ? x : 0));\n\t\t},\n\t\t\n\t\tadd : function(i, j) {\n\t\t\tvar d = acx.vector(i, j);\n\t\t\treturn new this.Init(this.x + d.x, this.y + d.y);\n\t\t},\n\t\t\n\t\tsub : function(i, j) {\n\t\t\tvar d = acx.vector(i, j);\n\t\t\treturn new this.Init(this.x - d.x, this.y - d.y);\n\t\t},\n\t\t\n\t\taddX : function(i) {\n\t\t\treturn new this.Init(this.x + i, this.y);\n\t\t},\n\t\t\n\t\taddY : function(j) {\n\t\t\treturn new this.Init(this.x, this.y + j);\n\t\t},\n\n\t\tmod : function(fn) { // runs a function against the x and y values\n\t\t\treturn new this.Init({x: fn.call(this, this.x, \"x\"), y: fn.call(this, this.y, \"y\")});\n\t\t},\n\t\t\n\t\t/** returns true if this is within a rectangle formed by the points p and q */\n\t\twithin : function(p, q) {\n\t\t\treturn ( this.x >= ((p.x < q.x) ? p.x : q.x) && this.x <= ((p.x > q.x) ? p.x : q.x) &&\n\t\t\t\t\tthis.y >= ((p.y < q.y) ? p.y : q.y) && this.y <= ((p.y > q.y) ? p.y : q.y) );\n\t\t},\n\t\t\n\t\tasOffset : function() {\n\t\t\treturn { top: this.y, left: this.x };\n\t\t},\n\t\t\n\t\tasSize : function() {\n\t\t\treturn { height: this.y, width: this.x };\n\t\t}\n\t};\n\n\tacx.vector.prototype.Init.prototype = acx.vector.prototype;\n\n\t/**\n\t * short cut functions for working with vectors and jquery.\n\t * Each function returns the equivalent jquery value in a two dimentional vector\n\t */\n\t$.fn.vSize = function() { return acx.vector(this.width(), this.height()); };\n\t$.fn.vOuterSize = function(margin) { return acx.vector(this.outerWidth(margin), this.outerHeight(margin)); };\n\t$.fn.vScroll = function() { return acx.vector(this.scrollLeft(), this.scrollTop()); };\n\t$.fn.vOffset = function() { return acx.vector(this.offset()); };\n\t$.fn.vPosition = function() { return acx.vector(this.position()); };\n\t$.Event.prototype.vMouse = function() { return acx.vector(this.pageX, this.pageY); };\n\n\t/**\n\t * object extensions (ecma5 compatible)\n\t */\n\tacx.augment(Object, {\n\t\tkeys: function(obj) {\n\t\t\tvar ret = [];\n\t\t\tfor(var n in obj) if(Object.prototype.hasOwnProperty.call(obj, n)) ret.push(n);\n\t\t\treturn ret;\n\t\t}\n\t});\n\n\t/**\n\t * Array prototype extensions\n\t */\n\tacx.augment(Array.prototype, {\n\t\t'contains' : function(needle) {\n\t\t\treturn this.indexOf(needle) !== -1;\n\t\t},\n\n\t\t// returns a new array consisting of all the members that are in both arrays\n\t\t'intersection' : function(b) {\n\t\t\tvar ret = [];\n\t\t\tfor(var i = 0; i < this.length; i++) {\n\t\t\t\tif(b.contains(this[i])) {\n\t\t\t\t\tret.push(this[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn ret;\n\t\t},\n\t\t\n\t\t'remove' : function(value) {\n\t\t\tvar i = this.indexOf(value);\n\t\t\tif(i !== -1) {\n\t\t\t\tthis.splice(i, 1);\n\t\t\t}\n\t\t}\n\t});\n\n\t/**\n\t * String prototype extensions\n\t */\n\tacx.augment(String.prototype, {\n\t\t'contains' : function(needle) {\n\t\t\treturn this.indexOf(needle) !== -1;\n\t\t},\n\n\t\t'equalsIgnoreCase' : function(match) {\n\t\t\treturn this.toLowerCase() === match.toLowerCase();\n\t\t},\n\n\t\t'escapeHtml' : function() {\n\t\t\treturn this.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n\t\t},\n\n\t\t'escapeJS' : function() {\n\t\t\tvar meta = {'\"':'\\\\\"', '\\\\':'\\\\\\\\', '/':'\\\\/', '\\b':'\\\\b', '\\f':'\\\\f', '\\n':'\\\\n', '\\r':'\\\\r', '\\t':'\\\\t'},\n\t\t\t\txfrm = function(c) { return meta[c] || \"\\\\u\" + c.charCodeAt(0).toString(16).zeroPad(4); };\n\t\t\treturn this.replace(new RegExp('([\"\\\\\\\\\\x00-\\x1f\\x7f-\\uffff])', 'g'), xfrm);\n\t\t},\n\n\t\t'escapeRegExp' : function() {\n\t\t\tvar ret = \"\", esc = \"\\\\^$*+?.()=|{,}[]-\";\n\t\t\tfor ( var i = 0; i < this.length; i++) {\n\t\t\t\tret += (esc.contains(this.charAt(i)) ? \"\\\\\" : \"\") + this.charAt(i);\n\t\t\t}\n\t\t\treturn ret;\n\t\t},\n\t\t\n\t\t'zeroPad' : function(len) {\n\t\t\treturn (\"0000000000\" + this).substring(this.length - len + 10);\n\t\t}\n\t});\n\n\t$.fn.forEach = Array.prototype.forEach;\n\n\t// joey / jquery integration\n\t$.joey = function( obj ) {\n\t\treturn $( window.joey( obj ) );\n\t};\n\n\twindow.joey.plugins.push( function( obj ) {\n\t\tif( obj instanceof jQuery ) {\n\t\t\treturn obj[0];\n\t\t}\n\t});\n\n})();\n\n/**\n * base class for creating inheritable classes\n * based on resigs 'Simple Javascript Inheritance Class' (based on base2 and prototypejs)\n * modified with static super and auto config\n * @name Class\n * @constructor\n */\n(function( $, app ){\n\n\tvar ux = app.ns(\"ux\");\n\n\tvar initializing = false, fnTest = /\\b_super\\b/;\n\n\tux.Class = function(){};\n\n\tux.Class.extend = function(prop) {\n\t\tfunction Class() {\n\t\t\tif(!initializing) {\n\t\t\t\tvar args = Array.prototype.slice.call(arguments);\n\t\t\t\tthis.config = $.extend( function(t) { // automatically construct a config object based on defaults and last item passed into the constructor\n\t\t\t\t\treturn $.extend(t._proto && t._proto() && arguments.callee(t._proto()) || {}, t.defaults);\n\t\t\t\t} (this) , args.pop() );\n\t\t\t\tthis.init && this.init.apply(this, args); // automatically run the init function when class created\n\t\t\t}\n\t\t}\n\n\t\tinitializing = true;\n\t\tvar prototype = new this();\n\t\tinitializing = false;\n\t\t\n\t\tvar _super = this.prototype;\n\t\tprototype._proto = function() {\n\t\t\treturn _super;\n\t\t};\n\n\t\tfor(var name in prop) {\n\t\t\tprototype[name] = typeof prop[name] === \"function\" && typeof _super[name] === \"function\" && fnTest.test(prop[name]) ?\n\t\t\t\t(function(name, fn){\n\t\t\t\t\treturn function() { this._super = _super[name]; return fn.apply(this, arguments); };\n\t\t\t\t})(name, prop[name]) : prop[name];\n\t\t}\n\n\t\tClass.prototype = prototype;\n\t\tClass.constructor = Class;\n\n\t\tClass.extend = arguments.callee; // make class extendable\n\n\t\treturn Class;\n\t};\n})( this.jQuery, this.app );\n\n(function( app ) {\n\n\tvar ut = app.ns(\"ut\");\n\n\tut.option_template = function(v) { return { tag: \"OPTION\", value: v, text: v }; };\n\n\tut.require_template = function(f) { return f.require ? { tag: \"SPAN\", cls: \"require\", text: \"*\" } : null; };\n\n\n\tvar sib_prefix = ['B','ki','Mi', 'Gi', 'Ti', 'Pi', 'Ei', 'Zi', 'Yi'];\n\n\tut.byteSize_template = function(n) {\n\t\tvar i = 0;\n\t\twhile( n >= 1000 ) {\n\t\t\ti++;\n\t\t\tn /= 1024;\n\t\t}\n\t\treturn (i === 0 ? n.toString() : n.toFixed( 3 - parseInt(n,10).toString().length )) + ( sib_prefix[ i ] || \"..E\" );\n\t};\n\n\tvar sid_prefix = ['','k','M', 'G', 'T', 'P', 'E', 'Z', 'Y'];\n\n\tut.count_template = function(n) {\n\t\tvar i = 0;\n\t\twhile( n >= 1000 ) {\n\t\t\ti++;\n\t\t\tn /= 1000;\n\t\t}\n\t\treturn i === 0 ? n.toString() : ( n.toFixed( 3 - parseInt(n,10).toString().length ) + ( sid_prefix[ i ] || \"..E\" ) );\n\t};\n\n})( this.app );\n\n(function( app ) {\n\n\tvar ux = app.ns(\"ux\");\n\n\tux.Observable = ux.Class.extend((function() {\n\t\treturn {\n\t\t\tinit: function() {\n\t\t\t\tthis.observers = {};\n\t\t\t\tfor( var opt in this.config ) { // automatically install observers that are defined in the configuration\n\t\t\t\t\tif( opt.indexOf( 'on' ) === 0 ) {\n\t\t\t\t\t\tthis.on( opt.substring(2) , this.config[ opt ] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\t_getObs: function( type ) {\n\t\t\t\treturn ( this.observers[ type.toLowerCase() ] || ( this.observers[ type.toLowerCase() ] = [] ) );\n\t\t\t},\n\t\t\ton: function( type, fn, params, thisp ) {\n\t\t\t\tthis._getObs( type ).push( { \"cb\" : fn, \"args\" : params || [] , \"cx\" : thisp || this } );\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tfire: function( type ) {\n\t\t\t\tvar params = Array.prototype.slice.call( arguments, 1 );\n\t\t\t\tthis._getObs( type ).slice().forEach( function( ob ) {\n\t\t\t\t\tob[\"cb\"].apply( ob[\"cx\"], ob[\"args\"].concat( params ) );\n\t\t\t\t} );\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tremoveAllObservers: function() {\n\t\t\t\tthis.observers = {};\n\t\t\t},\n\t\t\tremoveObserver: function( type, fn ) {\n\t\t\t\tvar obs = this._getObs( type ),\n\t\t\t\t\tindex = obs.reduce( function(p, t, i) { return (t.cb === fn) ? i : p; }, -1 );\n\t\t\t\tif(index !== -1) {\n\t\t\t\t\tobs.splice( index, 1 );\n\t\t\t\t}\n\t\t\t\treturn this; // make observable functions chainable\n\t\t\t},\n\t\t\thasObserver: function( type ) {\n\t\t\t\treturn !! this._getObs( type ).length;\n\t\t\t}\n\t\t};\n\t})());\n\n})( this.app );\n(function( app ) {\n\n\tvar ux = app.ns(\"ux\");\n\n\tvar extend = ux.Observable.extend;\n\tvar instance = function() {\n\t\tif( ! (\"me\" in this) ) {\n\t\t\tthis.me = new this();\n\t\t}\n\t\treturn this.me;\n\t};\n\n\tux.Singleton = ux.Observable.extend({});\n\n\tux.Singleton.extend = function() {\n\t\tvar Self = extend.apply( this, arguments );\n\t\tSelf.instance = instance;\n\t\treturn Self;\n\t};\n\n})( this.app );\n\n(function( $, app ) {\n\n\tvar ux = app.ns(\"ux\");\n\n\t/**\n\t * Provides drag and drop functionality<br>\n\t * a DragDrop instance is created for each usage pattern and then used over and over again<br>\n\t * first a dragObj is defined - this is the jquery node that will be dragged around<br>\n\t * second, the event callbacks are defined - these allow you control the ui during dragging and run functions when successfully dropping<br>\n\t * thirdly drop targets are defined - this is a list of DOM nodes, the constructor works in one of two modes:\n\t * <li>without targets - objects can be picked up and dragged around, dragStart and dragStop events fire</li>\n\t * <li>with targets - as objects are dragged over targets dragOver, dragOut and DragDrop events fire\n\t * to start dragging call the DragDrop.pickup_handler() function, dragging stops when the mouse is released.\n\t * @constructor\n\t * The following options are supported\n\t * <dt>targetSelector</dt>\n\t *   <dd>an argument passed directly to jquery to create a list of targets, as such it can be a CSS style selector, or an array of DOM nodes<br>if target selector is null the DragDrop does Drag only and will not fire dragOver dragOut and dragDrop events</dd>\n\t * <dt>pickupSelector</dt>\n\t *   <dd>a jquery selector. The pickup_handler is automatically bound to matched elements (eg clicking on these elements starts the drag). if pickupSelector is null, the pickup_handler must be manually bound <code>$(el).bind(\"mousedown\", dragdrop.pickup_handler)</code></dd>\n\t * <dt>dragObj</dt>\n\t *   <dd>the jQuery element to drag around when pickup is called. If not defined, dragObj must be set in onDragStart</dd>\n\t * <dt>draggingClass</dt>\n\t *   <dd>the class(es) added to items when they are being dragged</dd>\n\t * The following observables are supported\n\t * <dt>dragStart</dt>\n\t *   <dd>a callback when start to drag<br><code>function(jEv)</code></dd>\n\t * <dt>dragOver</dt>\n\t *   <dd>a callback when we drag into a target<br><code>function(jEl)</code></dd>\n\t * <dt>dragOut</dt>\n\t *   <dd>a callback when we drag out of a target, or when we drop over a target<br><code>function(jEl)</code></dd>\n\t * <dt>dragDrop</dt>\n\t *   <dd>a callback when we drop on a target<br><code>function(jEl)</code></dd>\n\t * <dt>dragStop</dt>\n\t *   <dd>a callback when we stop dragging<br><code>function(jEv)</code></dd>\n\t */\n\tux.DragDrop = ux.Observable.extend({\n\t\tdefaults : {\n\t\t\ttargetsSelector : null,\n\t\t\tpickupSelector:   null,\n\t\t\tdragObj :         null,\n\t\t\tdraggingClass :   \"dragging\"\n\t\t},\n\n\t\tinit: function(options) {\n\t\t\tthis._super(); // call the class initialiser\n\t\t\n\t\t\tthis.drag_handler = this.drag.bind(this);\n\t\t\tthis.drop_handler = this.drop.bind(this);\n\t\t\tthis.pickup_handler = this.pickup.bind(this);\n\t\t\tthis.targets = [];\n\t\t\tthis.dragObj = null;\n\t\t\tthis.dragObjOffset = null;\n\t\t\tthis.currentTarget = null;\n\t\t\tif(this.config.pickupSelector) {\n\t\t\t\t$(this.config.pickupSelector).bind(\"mousedown\", this.pickup_handler);\n\t\t\t}\n\t\t},\n\n\t\tdrag : function(jEv) {\n\t\t\tjEv.preventDefault();\n\t\t\tvar mloc = acx.vector( this.lockX || jEv.pageX, this.lockY || jEv.pageY );\n\t\t\tthis.dragObj.css(mloc.add(this.dragObjOffset).asOffset());\n\t\t\tif(this.targets.length === 0) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif(this.currentTarget !== null && mloc.within(this.currentTarget[1], this.currentTarget[2])) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif(this.currentTarget !== null) {\n\t\t\t\tthis.fire('dragOut', this.currentTarget[0]);\n\t\t\t\tthis.currentTarget = null;\n\t\t\t}\n\t\t\tfor(var i = 0; i < this.targets.length; i++) {\n\t\t\t\tif(mloc.within(this.targets[i][1], this.targets[i][2])) {\n\t\t\t\t\tthis.currentTarget = this.targets[i];\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(this.currentTarget !== null) {\n\t\t\t\tthis.fire('dragOver', this.currentTarget[0]);\n\t\t\t}\n\t\t},\n\t\t\n\t\tdrop : function(jEv) {\n\t\t\t$(document).unbind(\"mousemove\", this.drag_handler);\n\t\t\t$(document).unbind(\"mouseup\", this.drop_handler);\n\t\t\tthis.dragObj.removeClass(this.config.draggingClass);\n\t\t\tif(this.currentTarget !== null) {\n\t\t\t\tthis.fire('dragOut', this.currentTarget[0]);\n\t\t\t\tthis.fire('dragDrop', this.currentTarget[0]);\n\t\t\t}\n\t\t\tthis.fire('dragStop', jEv);\n\t\t\tthis.dragObj = null;\n\t\t},\n\t\t\n\t\tpickup : function(jEv, opts) {\n\t\t\t$.extend(this.config, opts);\n\t\t\tthis.fire('dragStart', jEv);\n\t\t\tthis.dragObj = this.dragObj || this.config.dragObj;\n\t\t\tthis.dragObjOffset = this.config.dragObjOffset || acx.vector(this.dragObj.offset()).sub(jEv.pageX, jEv.pageY);\n\t\t\tthis.lockX = this.config.lockX ? jEv.pageX : 0;\n\t\t\tthis.lockY = this.config.lockY ? jEv.pageY : 0;\n\t\t\tthis.dragObj.addClass(this.config.draggingClass);\n\t\t\tif(!this.dragObj.get(0).parentNode || this.dragObj.get(0).parentNode.nodeType === 11) { // 11 = document fragment\n\t\t\t\t$(document.body).append(this.dragObj);\n\t\t\t}\n\t\t\tif(this.config.targetsSelector) {\n\t\t\t\tthis.currentTarget = null;\n\t\t\t\tvar targets = ( this.targets = [] );\n\t\t\t\t// create an array of elements optimised for rapid collision detection calculation\n\t\t\t\t$(this.config.targetsSelector).each(function(i, el) {\n\t\t\t\t\tvar jEl = $(el);\n\t\t\t\t\tvar tl = acx.vector(jEl.offset());\n\t\t\t\t\tvar br = tl.add(jEl.width(), jEl.height());\n\t\t\t\t\ttargets.push([jEl, tl, br]);\n\t\t\t\t});\n\t\t\t}\n\t\t\t$(document).bind(\"mousemove\", this.drag_handler);\n\t\t\t$(document).bind(\"mouseup\", this.drop_handler);\n\t\t\tthis.drag_handler(jEv);\n\t\t}\n\t});\n\n})( this.jQuery, this.app );\n\n(function( app ) {\n\n\tvar ux = app.ns(\"ux\");\n\n\tux.FieldCollection = ux.Observable.extend({\n\t\tdefaults: {\n\t\t\tfields: []\t// the collection of fields\n\t\t},\n\t\tinit: function() {\n\t\t\tthis._super();\n\t\t\tthis.fields = this.config.fields;\n\t\t},\n\t\tvalidate: function() {\n\t\t\treturn this.fields.reduce(function(r, field) {\n\t\t\t\treturn r && field.validate();\n\t\t\t}, true);\n\t\t},\n\t\tgetData: function(type) {\n\t\t\treturn this.fields.reduce(function(r, field) {\n\t\t\t\tr[field.name] = field.val(); return r;\n\t\t\t}, {});\n\t\t}\n\t});\n\n})( this.app );\n\n(function( $, app ) {\n\n\tvar data = app.ns(\"data\");\n\tvar ux = app.ns(\"ux\");\n\n\tdata.Model = ux.Observable.extend({\n\t\tdefaults: {\n\t\t\tdata: null\n\t\t},\n\t\tinit: function() {\n\t\t\tthis.set( this.config.data );\n\t\t},\n\t\tset: function( key, value ) {\n\t\t\tif( arguments.length === 1 ) {\n\t\t\t\tthis._data = $.extend( {}, key );\n\t\t\t} else {\n\t\t\t\tkey.split(\".\").reduce(function( ptr, prop, i, props) {\n\t\t\t\t\tif(i === (props.length - 1) ) {\n\t\t\t\t\t\tptr[prop] = value;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif( !(prop in ptr) ) {\n\t\t\t\t\t\t\tptr[ prop ] = {};\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn ptr[prop];\n\t\t\t\t\t}\n\t\t\t\t}, this._data );\n\t\t\t}\n\t\t},\n\t\tget: function( key ) {\n\t\t\treturn key.split(\".\").reduce( function( ptr, prop ) {\n\t\t\t\treturn ( ptr && ( prop in ptr ) ) ? ptr[ prop ] : undefined;\n\t\t\t}, this._data );\n\t\t},\n\t});\n})( this.jQuery, this.app );\n\n(function( app ) {\n\n\tvar data = app.ns(\"data\");\n\tvar ux = app.ns(\"ux\");\n\n\tdata.DataSourceInterface = ux.Observable.extend({\n\t\t/*\n\t\tproperties\n\t\t\tmeta = { total: 0 },\n\t\t\theaders = [ { name: \"\" } ],\n\t\t\tdata = [ { column: value, column: value } ],\n\t\t\tsort = { column: \"name\", dir: \"desc\" }\n\t\tevents\n\t\t\tdata: function( DataSourceInterface )\n\t\t */\n\t\t_getSummary: function(res) {\n\t\t\tthis.summary = i18n.text(\"TableResults.Summary\", res._shards.successful, res._shards.total, (typeof res.hits.total === 'object') ? res.hits.total.value : res.hits.total, (res.took / 1000).toFixed(3));\n\t\t},\n\t\t_getMeta: function(res) {\n\t\t\tthis.meta = { total: res.hits.total, shards: res._shards, tool: res.took };\n\t\t}\n\t});\n\n})( this.app );\n(function( app ) {\n\n\tvar data = app.ns(\"data\");\n\n\tdata.ResultDataSourceInterface = data.DataSourceInterface.extend({\n\t\tresults: function(res) {\n\t\t\tthis._getSummary(res);\n\t\t\tthis._getMeta(res);\n\t\t\tthis._getData(res);\n\t\t\tthis.sort = {};\n\t\t\tthis.fire(\"data\", this);\n\t\t},\n\t\t_getData: function(res) {\n\t\t\tvar columns = this.columns = [];\n\t\t\tthis.data = res.hits.hits.map(function(hit) {\n\t\t\t\tvar row = (function(path, spec, row) {\n\t\t\t\t\tfor(var prop in spec) {\n\t\t\t\t\t\tif(acx.isObject(spec[prop])) {\n\t\t\t\t\t\t\targuments.callee(path.concat(prop), spec[prop], row);\n\t\t\t\t\t\t} else if(acx.isArray(spec[prop])) {\n\t\t\t\t\t\t\tif(spec[prop].length) {\n\t\t\t\t\t\t\t\targuments.callee(path.concat(prop), spec[prop][0], row)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tvar dpath = path.concat(prop).join(\".\");\n\t\t\t\t\t\t\tif(! columns.contains(dpath)) {\n\t\t\t\t\t\t\t\tcolumns.push(dpath);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\trow[dpath] = (spec[prop] || \"null\").toString();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn row;\n\t\t\t\t})([ hit._type ], hit, {});\n\t\t\t\trow._source = hit;\n\t\t\t\treturn row;\n\t\t\t}, this);\n\t\t}\n\t});\n\n})( this.app );\n\n(function( app ) {\n\n\t/*\n\tnotes on elasticsearch terminology used in this project\n\n\tindices[index] contains one or more\n\ttypes[type] contains one or more\n\tdocuments contain one or more\n\tpaths[path]\n\teach path contains one element of data\n\teach path maps to one field\n\n\teg PUT, \"/twitter/tweet/1\"\n\t{\n\t\tuser: \"mobz\",\n\t\tdate: \"2011-01-01\",\n\t\tmessage: \"You know, for browsing elasticsearch\",\n\t\tname: {\n\t\t\tfirst: \"Ben\",\n\t\t\tlast: \"Birch\"\n\t\t}\n\t}\n\n\tcreates\n\t\t1 index: twitter\n\t\t\t\tthis is the collection of index data\n\t\t1 type: tweet\n\t\t\t\tthis is the type of document (kind of like a table in sql)\n\t\t1 document: /twitter/tweet/1\n\t\t\t\tthis is an actual document in the index ( kind of like a row in sql)\n\t\t5 paths: [ [\"user\"], [\"date\"], [\"message\"], [\"name\",\"first\"], [\"name\",\"last\"] ]\n\t\t\t\tsince documents can be heirarchical this maps a path from a document root to a piece of data\n\t\t5 fields: [ \"user\", \"date\", \"message\", \"first\", \"last\" ]\n\t\t\t\tthis is an indexed 'column' of data. fields are not heirarchical\n\n\t\tthe relationship between a path and a field is called a mapping. mappings also contain a wealth of information about how es indexes the field\n\n\tnotes\n\t1) a path is stored as an array, the dpath is  <index> . <type> . path.join(\".\"),\n\t\t\twhich can be considered the canonical reference for a mapping\n\t2) confusingly, es uses the term index for both the collection of indexed data, and the individually indexed fields\n\t\t\tso the term index_name is the same as field_name in this sense.\n\n\t*/\n\n\tvar data = app.ns(\"data\");\n\tvar ux = app.ns(\"ux\");\n\n\tvar coretype_map = {\n\t\t\"string\" : \"string\",\n\t\t\"keyword\" : \"string\",\n\t\t\"text\" : \"string\",\n\t\t\"byte\" : \"number\",\n\t\t\"short\" : \"number\",\n\t\t\"long\" : \"number\",\n\t\t\"integer\" : \"number\",\n\t\t\"float\" : \"number\",\n\t\t\"double\" : \"number\",\n\t\t\"ip\" : \"number\",\n\t\t\"date\" : \"date\",\n\t\t\"boolean\" : \"boolean\",\n\t\t\"binary\" : \"binary\",\n\t\t\"multi_field\" : \"multi_field\"\n\t};\n\n\tvar default_property_map = {\n\t\t\"string\" : { \"store\" : \"no\", \"index\" : \"analysed\" },\n\t\t\"number\" : { \"store\" : \"no\", \"precision_steps\" : 4 },\n\t\t\"date\" : { \"store\" : \"no\", \"format\" : \"dateOptionalTime\", \"index\": \"yes\", \"precision_steps\": 4 },\n\t\t\"boolean\" : { \"store\" : \"no\", \"index\": \"yes\" },\n\t\t\"binary\" : { },\n\t\t\"multi_field\" : { }\n\t};\n\n\t// parses metatdata from a cluster, into a bunch of useful data structures\n\tdata.MetaData = ux.Observable.extend({\n\t\tdefaults: {\n\t\t\tstate: null // (required) response from a /_cluster/state request\n\t\t},\n\t\tinit: function() {\n\t\t\tthis._super();\n\t\t\tthis.refresh(this.config.state);\n\t\t},\n\t\tgetIndices: function(alias) {\n\t\t\treturn alias ? this.aliases[alias] : this.indicesList;\n\t\t},\n\t\t// returns an array of strings containing all types that are in all of the indices passed in, or all types\n\t\tgetTypes: function(indices) {\n\t\t\tvar indices = indices || [], types = [];\n\t\t\tthis.typesList.forEach(function(type) {\n\t\t\t\tfor(var i = 0; i < indices.length; i++) {\n\t\t\t\t\tif(! this.indices[indices[i]].types.contains(type))\n\t\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\ttypes.push(type);\n\t\t\t}, this);\n\t\t\treturn types;\n\t\t},\n\t\trefresh: function(state) {\n\t\t\t// currently metadata expects all like named fields to have the same type, even when from different types and indices\n\t\t\tvar aliases = this.aliases = {};\n\t\t\tvar indices = this.indices = {};\n\t\t\tvar types = this.types = {};\n\t\t\tvar fields = this.fields = {};\n\t\t\tvar paths = this.paths = {};\n\n\t\t\tfunction createField( mapping, index, type, path, name ) {\n\t\t\t\tvar dpath = [ index, type ].concat( path ).join( \".\" );\n\t\t\t\tvar field_name = mapping.index_name || path.join( \".\" );\n\t\t\t\tvar field = paths[ dpath ] = fields[ field_name ] || $.extend({\n\t\t\t\t\tfield_name : field_name,\n\t\t\t\t\tcore_type : coretype_map[ mapping.type ],\n\t\t\t\t\tdpaths : []\n\t\t\t\t}, default_property_map[ coretype_map[ mapping.type ] ], mapping );\n\n\t\t\t\tif (field.type === \"multi_field\" && typeof field.fields !== \"undefined\") {\n\t\t\t\t\tfor (var subField in field.fields) {\n\t\t\t\t\t\tfield.fields[ subField ] = createField( field.fields[ subField ], index, type, path.concat( subField ), name + \".\" + subField );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (fields.dpaths) {\n\t\t\t\t\tfield.dpaths.push(dpath);\n\t\t\t\t}\n\t\t\t\treturn field;\n\t\t\t}\n\t\t\tfunction getFields(properties, type, index, listeners) {\n\t\t\t\t(function procPath(prop, path) {\n\t\t\t\t\tfor (var n in prop) {\n\t\t\t\t\t\tif (\"properties\" in prop[n]) {\n\t\t\t\t\t\t\tprocPath( prop[ n ].properties, path.concat( n ) );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tvar field = createField(prop[n], index, type, path.concat(n), n);\t\t\t\t\t\t\t\n\t\t\t\t\t\t\tlisteners.forEach( function( listener ) {\n\t\t\t\t\t\t\t\tlistener[ field.field_name ] = field;\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})(properties, []);\n\t\t\t}\n\t\t\tfor (var index in state.metadata.indices) {\n\t\t\t\tindices[index] = {\n\t\t\t\t\ttypes : [], fields : {}, paths : {}, parents : {}\n\t\t\t\t};\n\t\t\t\tindices[index].aliases = state.metadata.indices[index].aliases;\n\t\t\t\tindices[index].aliases.forEach(function(alias) {\n\t\t\t\t\t(aliases[alias] || (aliases[alias] = [])).push(index);\n\t\t\t\t});\n\t\t\t\tvar mapping = state.metadata.indices[index].mappings;\n\t\t\t\tfor (var type in mapping) {\n\t\t\t\t\tindices[index].types.push(type);\n\t\t\t\t\tif ( type in types) {\n\t\t\t\t\t\ttypes[type].indices.push(index);\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttypes[type] = {\n\t\t\t\t\t\t\tindices : [index], fields : {}\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\tgetFields(mapping[type].properties, type, index, [fields, types[type].fields, indices[index].fields]);\n\t\t\t\t\tif ( typeof mapping[type]._parent !== \"undefined\") {\n\t\t\t\t\t\tindices[index].parents[type] = mapping[type]._parent.type;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.aliasesList = Object.keys(aliases);\n\t\t\tthis.indicesList = Object.keys(indices);\n\t\t\tthis.typesList = Object.keys(types);\n\t\t\tthis.fieldsList = Object.keys(fields);\n\t\t}\n\t});\n\n})( this.app );\t\n\n(function( app ) {\n\n\tvar data = app.ns(\"data\");\n\tvar ux = app.ns(\"ux\");\n\n\tdata.MetaDataFactory = ux.Observable.extend({\n\t\tdefaults: {\n\t\t\tcluster: null // (required) an app.services.Cluster\n\t\t},\n\t\tinit: function() {\n\t\t\tthis._super();\n\t\t\tvar _cluster = this.config.cluster;\n\t\t\tthis.config.cluster.get(\"_cluster/state\", function(data) {\n\t\t\t\tthis.metaData = new app.data.MetaData({state: data});\n\t\t\t\tthis.fire(\"ready\", this.metaData,  { originalData: data, \"k\": 1 }); // TODO originalData needed for legacy ui.FilterBrowser\n\t\t\t}.bind(this), function() {\n\t\t\t\t\n\t\t\t\tvar _this = this;\n\t\t\t\t\n\t\t\t\t_cluster.get(\"_all\", function( data ) {\n\t\t\t\t\tclusterState = {routing_table:{indices:{}}, metadata:{indices:{}}};\n\t\t\t\t\t\n\t\t\t\t\tfor(var k in data) {\n\t\t\t\t\t\tclusterState[\"routing_table\"][\"indices\"][k] = {\"shards\":{\"1\":[{\n                            \"state\":\"UNASSIGNED\",\n                            \"primary\":false,\n                            \"node\":\"unknown\",\n                            \"relocating_node\":null,\n                            \"shard\":'?',\n                            \"index\":k\n                        }]}};\n\t\t\t\t\t\t\n\n\t\t\t\t\t\tclusterState[\"metadata\"][\"indices\"][k] = {};\n\t\t\t\t\t\tclusterState[\"metadata\"][\"indices\"][k][\"mappings\"] = data[k][\"mappings\"];\n\t\t\t\t\t\tclusterState[\"metadata\"][\"indices\"][k][\"aliases\"] = $.makeArray(Object.keys(data[k][\"aliases\"]));\n\t\t\t\t\t\tclusterState[\"metadata\"][\"indices\"][k][\"settings\"] = data[k][\"settings\"];\n\t\t\t\t\t\tclusterState[\"metadata\"][\"indices\"][k][\"fields\"] = {};\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\t_this.metaData = new app.data.MetaData({state: clusterState});\n\t\t\t\t\t_this.fire(\"ready\", _this.metaData, {originalData: clusterState});\n\t\t\t\t});\t\t\t\t\n\n\t\t\t}.bind(this));\n\t\t}\n\t});\n\n})( this.app );\n\n(function( app ) {\n\n\tvar data = app.ns(\"data\");\n\tvar ux = app.ns(\"ux\");\n\n\tdata.Query = ux.Observable.extend({\n\t\tdefaults: {\n\t\t\tcluster: null,  // (required) instanceof app.services.Cluster\n\t\t\tsize: 50        // size of pages to return\n\t\t},\n\t\tinit: function() {\n\t\t\tthis._super();\n\t\t\tthis.cluster = this.config.cluster;\n\t\t\tthis.refuid = 0;\n\t\t\tthis.refmap = {};\n\t\t\tthis.indices = [];\n\t\t\tthis.types = [];\n\t\t\tthis.search = {\n\t\t\t\tquery: { bool: { must: [], must_not: [], should: [] } },\n\t\t\t\tfrom: 0,\n\t\t\t\tsize: this.config.size,\n\t\t\t\tsort: [],\n\t\t\t\taggs: {},\n\t\t\t\tversion: true\n\t\t\t};\n\t\t\tthis.defaultClause = this.addClause();\n\t\t\tthis.history = [ this.getState() ];\n\t\t},\n\t\tclone: function() {\n\t\t\tvar q = new data.Query({ cluster: this.cluster });\n\t\t\tq.restoreState(this.getState());\n\t\t\tfor(var uqid in q.refmap) {\n\t\t\t\tq.removeClause(uqid);\n\t\t\t}\n\t\t\treturn q;\n\t\t},\n\t\tgetState: function() {\n\t\t\treturn $.extend(true, {}, { search: this.search, indices: this.indices, types: this.types });\n\t\t},\n\t\trestoreState: function(state) {\n\t\t\tstate = $.extend(true, {}, state || this.history[this.history.length - 1]);\n\t\t\tthis.indices = state.indices;\n\t\t\tthis.types = state.types;\n\t\t\tthis.search = state.search;\n\t\t},\n\t\tgetData: function() {\n\t\t\treturn JSON.stringify(this.search);\n\t\t},\n\t\tquery: function() {\n\t\t\tvar state = this.getState();\n\t\t\tthis.cluster.post(\n\t\t\t\t\t(this.indices.join(\",\") || \"_all\") + \"/\" + ( this.types.length ? this.types.join(\",\") + \"/\" : \"\") + \"_search\",\n\t\t\t\t\tthis.getData(),\n\t\t\t\t\tfunction(results) {\n\t\t\t\t\t\tif(results === null) {\n\t\t\t\t\t\t\talert(i18n.text(\"Query.FailAndUndo\"));\n\t\t\t\t\t\t\tthis.restoreState();\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.history.push(state);\n\n\t\t\t\t\t\tthis.fire(\"results\", this, results);\n\t\t\t\t\t}.bind(this));\n\t\t},\n\t\tloadParents: function(res,metadata){\n\t\t\t//create data for mget\n\t\t\tvar data = { docs :[] };\n\t\t\tvar indexToTypeToParentIds = {};\n\t\t\tres.hits.hits.forEach(function(hit) {\n\t\t\tif (typeof hit.fields != \"undefined\"){\n\t\t\t\tif (typeof hit.fields._parent != \"undefined\"){\n\t\t\t\t\tvar parentType = metadata.indices[hit._index].parents[hit._type];\n\t\t\t\t\tif (typeof indexToTypeToParentIds[hit._index] == \"undefined\"){\n\t\t\t\t\t\tindexToTypeToParentIds[hit._index] = new Object();\n\t\t\t\t\t}\n\t\t\t\t\tif (typeof indexToTypeToParentIds[hit._index][hit._type] == \"undefined\"){\n\t\t\t\t\t\tindexToTypeToParentIds[hit._index][hit._type] = new Object();\n\t\t\t\t\t}\n\t\t\t\t\tif (typeof indexToTypeToParentIds[hit._index][hit._type][hit.fields._parent] == \"undefined\"){\n\t\t\t\t\t\tindexToTypeToParentIds[hit._index][hit._type][hit.fields._parent] = null;\n\t\t\t\t\t\tdata.docs.push({ _index:hit._index, _type:parentType, _id:hit.fields._parent});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\t//load parents\n\t\tvar state = this.getState();\n\t\t\tthis.cluster.post(\"_mget\",JSON.stringify(data),\n\t\t\t\tfunction(results) {\n\t\t\t\t\tif(results === null) {\n\t\t\t\t\t\talert(i18n.text(\"Query.FailAndUndo\"));\n\t\t\t\t\t\tthis.restoreState();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tthis.history.push(state);\n\t\t\t\t\tvar indexToTypeToParentIdToHit = new Object();\n\t\t\t\t\tresults.docs.forEach(function(doc) {\n\t\t\t\t\t\tif (typeof indexToTypeToParentIdToHit[doc._index] == \"undefined\"){\n\t\t\t\t\t\tindexToTypeToParentIdToHit[doc._index] = new Object();\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\tif (typeof indexToTypeToParentIdToHit[doc._index][doc._type] == \"undefined\"){\n\t\t\t\t\t\tindexToTypeToParentIdToHit[doc._index][doc._type] = new Object();\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\tindexToTypeToParentIdToHit[doc._index][doc._type][doc._id] = doc;\n\t\t\t\t\t});\n\t\t\t\t\t\n\t\t\t\t\tres.hits.hits.forEach(function(hit) {\n\t\t\t\t\t\tif (typeof hit.fields != \"undefined\"){\n\t\t\t\t\t\t\tif (typeof hit.fields._parent != \"undefined\"){\n\t\t\t\t\t\t\t\tvar parentType = metadata.indices[hit._index].parents[hit._type];\n\t\t\t\t\t\t\t\thit._parent = indexToTypeToParentIdToHit[hit._index][parentType][hit.fields._parent];\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\tthis.fire(\"resultsWithParents\", this, res);\n\t\t\t\t}.bind(this));\n\t\t},\n\t\tsetPage: function(page) {\n\t\t\tthis.search.from = this.config.size * (page - 1);\n\t\t},\n\t\tsetSort: function(index, desc) {\n\t\t\tvar sortd = {}; sortd[index] = { order: desc ? 'asc' : 'desc' };\n\t\t\tthis.search.sort.unshift( sortd );\n\t\t\tfor(var i = 1; i < this.search.sort.length; i++) {\n\t\t\t\tif(Object.keys(this.search.sort[i])[0] === index) {\n\t\t\t\t\tthis.search.sort.splice(i, 1);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tsetIndex: function(index, add) {\n\t\t\tif(add) {\n\t\t\t\tif(! this.indices.contains(index)) this.indices.push(index);\n\t\t\t} else {\n\t\t\t\tthis.indices.remove(index);\n\t\t\t}\n\t\t\tthis.fire(\"setIndex\", this, { index: index, add: !!add });\n\t\t},\n\t\tsetType: function(type, add) {\n\t\t\tif(add) {\n\t\t\t\tif(! this.types.contains(type)) this.types.push(type);\n\t\t\t} else {\n\t\t\t\tthis.types.remove(type);\n\t\t\t}\n\t\t\tthis.fire(\"setType\", this, { type: type, add: !!add });\n\t\t},\n\t\taddClause: function(value, field, op, bool) {\n\t\t\tbool = bool || \"should\";\n\t\t\top = op || \"match_all\";\n\t\t\tfield = field || \"_all\";\n\t\t\tvar clause = this._setClause(value, field, op, bool);\n\t\t\tvar uqid = \"q-\" + this.refuid++;\n\t\t\tthis.refmap[uqid] = { clause: clause, value: value, field: field, op: op, bool: bool };\n\t\t\tif(this.search.query.bool.must.length + this.search.query.bool.should.length > 1) {\n\t\t\t\tthis.removeClause(this.defaultClause);\n\t\t\t}\n\t\t\tthis.fire(\"queryChanged\", this, { uqid: uqid, search: this.search} );\n\t\t\treturn uqid; // returns reference to inner query object to allow fast updating\n\t\t},\n\t\tremoveClause: function(uqid) {\n\t\t\tvar ref = this.refmap[uqid],\n\t\t\t\tbool = this.search.query.bool[ref.bool];\n\t\t\tbool.remove(ref.clause);\n\t\t\tif(this.search.query.bool.must.length + this.search.query.bool.should.length === 0) {\n\t\t\t\tthis.defaultClause = this.addClause();\n\t\t\t}\n\t\t},\n\t\taddAggs: function(aggs) {\n\t\t\tvar aggsId = \"f-\" + this.refuid++;\n\t\t\tthis.search.aggs[aggsId] = aggs;\n\t\t\tthis.refmap[aggsId] = { aggsId: aggsId, aggs: aggs };\n\t\t\treturn aggsId;\n\t\t},\n\t\tremoveAggs: function(aggsId) {\n\t\t\tdelete this.search.aggs[aggsId];\n\t\t\tdelete this.refmap[aggsId];\n\t\t},\n\t\t_setClause: function(value, field, op, bool) {\n\t\t\tvar clause = {}, query = {};\n\t\t\tif(op === \"match_all\") {\n\t\t\t} else if(op === \"query_string\") {\n\t\t\t\tquery[\"default_field\"] = field;\n\t\t\t\tquery[\"query\"] = value;\n\t\t\t} else if(op === \"missing\") {\n\t\t\t\top = \"constant_score\"\n\t\t\t\tvar missing = {}, filter = {};\n\t\t\t\tmissing[\"field\"] = field;\n\t\t\t\tfilter[\"missing\"] = missing\n\t\t\t\tquery[\"filter\"] = filter;\n\t\t\t} else {\n\t\t\t\tquery[field] = value;\n\t\t\t}\n\t\t\tclause[op] = query;\n\t\t\tthis.search.query.bool[bool].push(clause);\n\t\t\treturn clause;\n\t\t}\n\t});\n\n})( this.app );\n\n(function( app ) {\n\n\tvar data = app.ns(\"data\");\n\n\tdata.QueryDataSourceInterface = data.DataSourceInterface.extend({\n\t\tdefaults: {\n\t\t\tmetadata: null, // (required) instanceof app.data.MetaData, the cluster metadata\n\t\t\tquery: null     // (required) instanceof app.data.Query the data source\n\t\t},\n\t\tinit: function() {\n\t\t\tthis._super();\n\t\t\tthis.config.query.on(\"results\", this._results_handler.bind(this) );\n\t\t\tthis.config.query.on(\"resultsWithParents\", this._load_parents.bind(this) );\n\t\t},\n\t\t_results_handler: function(query, res) {\n\t\t\tthis._getSummary(res);\n\t\t\tthis._getMeta(res);\n\t\t\tvar sort = query.search.sort[0] || { \"_score\": { order: \"asc\" }};\n\t\t\tvar sortField = Object.keys(sort)[0];\n\t\t\tthis.sort = { column: sortField, dir: sort[sortField].order };\n\t\t\tthis._getData(res, this.config.metadata);\n\t\t\tthis.fire(\"data\", this);\n\t\t},\n\t\t_load_parents: function(query, res) {\n\t\t\tquery.loadParents(res, this.config.metadata);\n\t\t},\n\t\t_getData: function(res, metadata) {\n\t\t\tvar metaColumns = [\"_index\", \"_type\", \"_id\", \"_score\"];\n\t\t\tvar columns = this.columns = [].concat(metaColumns);\n\n\t\t\tthis.data = res.hits.hits.map(function(hit) {\n\t\t\t\tvar row = (function(path, spec, row) {\n\t\t\t\t\tfor(var prop in spec) {\n\t\t\t\t\t\tif(acx.isObject(spec[prop])) {\n\t\t\t\t\t\t\targuments.callee(path.concat(prop), spec[prop], row);\n\t\t\t\t\t\t} else if(acx.isArray(spec[prop])) {\n\t\t\t\t\t\t\tif(spec[prop].length) {\n\t\t\t\t\t\t\t\targuments.callee(path.concat(prop), spec[prop][0], row)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tvar dpath = path.concat(prop).join(\".\");\n\t\t\t\t\t\t\tif(metadata.paths[dpath]) {\n\t\t\t\t\t\t\t\tvar field_name = metadata.paths[dpath].field_name;\n\t\t\t\t\t\t\t\tif(! columns.contains(field_name)) {\n\t\t\t\t\t\t\t\t\tcolumns.push(field_name);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\trow[field_name] = (spec[prop] === null ? \"null\" : spec[prop] ).toString();\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// TODO: field not in metadata index\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\treturn row;\n\t\t\t\t})([ hit._index, hit._type ], hit._source, {});\n\t\t\t\tmetaColumns.forEach(function(n) { row[n] = hit[n]; });\n\t\t\t\trow._source = hit;\n\t\t\t\tif (typeof hit._parent!= \"undefined\") {\n\t\t\t\t\t(function(prefix, path, spec, row) {\n\t\t\t\t\tfor(var prop in spec) {\n\t\t\t\t\t\tif(acx.isObject(spec[prop])) {\n\t\t\t\t\t\t\targuments.callee(prefix, path.concat(prop), spec[prop], row);\n\t\t\t\t\t\t} else if(acx.isArray(spec[prop])) {\n\t\t\t\t\t\t\tif(spec[prop].length) {\n\t\t\t\t\t\t\t\targuments.callee(prefix, path.concat(prop), spec[prop][0], row)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tvar dpath = path.concat(prop).join(\".\");\n\t\t\t\t\t\t\tif(metadata.paths[dpath]) {\n\t\t\t\t\t\t\t\tvar field_name = metadata.paths[dpath].field_name;\n\t\t\t\t\t\t\t\tvar column_name = prefix+\".\"+field_name;\n\t\t\t\t\t\t\t\tif(! columns.contains(column_name)) {\n\t\t\t\t\t\t\t\t\tcolumns.push(column_name);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\trow[column_name] = (spec[prop] === null ? \"null\" : spec[prop] ).toString();\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// TODO: field not in metadata index\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\t})(hit._parent._type,[hit._parent._index, hit._parent._type], hit._parent._source, row);\n\t\t\t\t}\n\t\t\t\treturn row;\n\t\t\t}, this);\n\t\t}\n\t});\n\n})( this.app );\n\n(function( app ) {\n\n\tvar data = app.ns(\"data\");\n\tvar ux = app.ns(\"ux\");\n\n\tdata.BoolQuery = ux.Observable.extend({\n\t\tdefaults: {\n\t\t\tsize: 50\t\t// size of pages to return\n\t\t},\n\t\tinit: function() {\n\t\t\tthis._super();\n\t\t\tthis.refuid = 0;\n\t\t\tthis.refmap = {};\n\t\t\tthis.search = {\n\t\t\t\tquery: { bool: { must: [], must_not: [], should: [] } },\n\t\t\t\tfrom: 0,\n\t\t\t\tsize: this.config.size,\n\t\t\t\tsort: [],\n\t\t\t\taggs: {}\n\t\t\t};\n\t\t\tthis.defaultClause = this.addClause();\n\t\t},\n\t\tsetSize: function(size) {\n\t\t\tthis.search.size = parseInt( size, 10 );\n\t\t},\n\t\tsetPage: function(page) {\n\t\t\tthis.search.from = this.config.size * (page - 1) + 1;\n\t\t},\n\t\taddClause: function(value, field, op, bool) {\n\t\t\tbool = bool || \"should\";\n\t\t\top = op || \"match_all\";\n\t\t\tfield = field || \"_all\";\n\t\t\tvar clause = this._setClause(value, field, op, bool);\n\t\t\tvar uqid = \"q-\" + this.refuid++;\n\t\t\tthis.refmap[uqid] = { clause: clause, value: value, field: field, op: op, bool: bool };\n\t\t\tif(this.search.query.bool.must.length + this.search.query.bool.should.length > 1) {\n\t\t\t\tthis.removeClause(this.defaultClause);\n\t\t\t}\n\t\t\tthis.fire(\"queryChanged\", this, { uqid: uqid, search: this.search} );\n\t\t\treturn uqid; // returns reference to inner query object to allow fast updating\n\t\t},\n\t\tremoveClause: function(uqid) {\n\t\t\tvar ref = this.refmap[uqid],\n\t\t\t\tbool = this.search.query.bool[ref.bool];\n\t\t\tvar clauseIdx = bool.indexOf(ref.clause);\n\t\t\t// Check that this clause hasn't already been removed\n\t\t\tif (clauseIdx >=0) {\n\t\t\t\tbool.splice(clauseIdx, 1);\n\t\t\t}\n\t\t},\n\t\t_setClause: function(value, field, op, bool) {\n\t\t\tvar clause = {}, query = {};\n\t\t\tif(op === \"match_all\") {\n\t\t\t} else if(op === \"query_string\") {\n\t\t\t\tquery[\"default_field\"] = field.substring(field.indexOf(\".\")+1);\n\t\t\t\tquery[\"query\"] = value;\n\t\t\t} else if(op === \"missing\") {\n\t\t\t\top = \"exists\";\n\t\t\t\tif (bool === \"must_not\") {\n\t\t\t\t\tbool = \"must\"\n\t\t\t\t} else if (bool === \"must\") {\n\t\t\t\t\tbool = \"must_not\"\n\t\t\t\t}\n\t\t\t\tquery[\"field\"] = field.substring(field.indexOf(\".\")+1);\n\t\t\t} else {\n\t\t\t\tquery[field.substring(field.indexOf(\".\")+1)] = value;\n\t\t\t}\n\t\t\tclause[op] = query;\n\t\t\tthis.search.query.bool[bool].push(clause);\n\t\t\treturn clause;\n\t\t},\n\t\tgetData: function() {\n\t\t\treturn JSON.stringify(this.search);\n\t\t}\n\t});\n\n})( this.app );\n(function( app ) {\n\t\n\tvar ux = app.ns(\"ux\");\n\tvar services = app.ns(\"services\");\n\n\tservices.Preferences = ux.Singleton.extend({\n\t\tinit: function() {\n\t\t\tthis._storage = window.localStorage;\n\t\t\tthis._setItem(\"__version\", 1 );\n\t\t},\n\t\tget: function( key ) {\n\t\t\treturn this._getItem( key );\n\t\t},\n\t\tset: function( key, val ) {\n\t\t\treturn this._setItem( key, val );\n\t\t},\n\t\t_getItem: function( key ) {\n\t\t\ttry {\n\t\t\t\treturn JSON.parse( this._storage.getItem( key ) );\n\t\t\t} catch(e) {\n\t\t\t\tconsole.warn( e );\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t},\n\t\t_setItem: function( key, val ) {\n\t\t\ttry {\n\t\t\t\treturn this._storage.setItem( key, JSON.stringify( val ) );\n\t\t\t} catch(e) {\n\t\t\t\tconsole.warn( e );\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t}\n\t});\n\n})( this.app );\n\n(function( $, app ) {\n\n\tvar services = app.ns(\"services\");\n\tvar ux = app.ns(\"ux\");\n\n\tfunction parse_version( v ) {\n\t\treturn v.match(/^(\\d+)\\.(\\d+)\\.(\\d+)/).slice(1,4).map( function(d) { return parseInt(d || 0, 10); } );\n\t}\n\n\tservices.Cluster = ux.Class.extend({\n\t\tdefaults: {\n\t\t\tbase_uri: null\n\t\t},\n\t\tinit: function() {\n\t\t\tthis.base_uri = this.config.base_uri;\n\t\t},\n\t\tsetVersion: function( v ) {\n\t\t\tthis.version = v;\n\t\t\tthis._version_parts = parse_version( v );\n\t\t},\n\t\tversionAtLeast: function( v ) {\n\t\t\tvar testVersion = parse_version( v );\n\t\t\tfor( var i = 0; i < 3; i++ ) {\n\t\t\t\tif( testVersion[i] !== this._version_parts[i] ) {\n\t\t\t\t\treturn testVersion[i] < this._version_parts[i];\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\t\trequest: function( params ) {\n\t\t\treturn $.ajax( $.extend({\n\t\t\t\turl: this.base_uri + params.path,\n\t\t\t\tcontentType: \"application/json\",\n\t\t\t\tdataType: \"json\",\n\t\t\t\terror: function(xhr, type, message) {\n\t\t\t\t\tif(\"console\" in window) {\n\t\t\t\t\t\tconsole.log({ \"XHR Error\": type, \"message\": message });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},  params) );\n\t\t},\n\t\t\"get\": function(path, success, error) { return this.request( { type: \"GET\", path: path, success: success, error: error } ); },\n\t\t\"post\": function(path, data, success, error) { return this.request( { type: \"POST\", path: path, data: data, success: success, error: error } ); },\n\t\t\"put\": function(path, data, success, error) { return this.request( { type: \"PUT\", path: path, data: data, success: success, error: error } ); },\n\t\t\"delete\": function(path, data, success, error) { return this.request( { type: \"DELETE\", path: path, data: data, success: success, error: error } ); }\n\t});\n\n})( this.jQuery, this.app );\n\n\t(function( app ) {\n\n\tvar services = app.ns(\"services\");\n\tvar ux = app.ns(\"ux\");\n\n\tservices.ClusterState = ux.Observable.extend({\n\t\tdefaults: {\n\t\t\tcluster: null\n\t\t},\n\t\tinit: function() {\n\t\t\tthis._super();\n\t\t\tthis.cluster = this.config.cluster;\n\t\t\tthis.clusterState = null;\n\t\t\tthis.status = null;\n\t\t\tthis.nodeStats = null;\n\t\t\tthis.clusterNodes = null;\n\t\t},\n\t\trefresh: function() {\n\t\t\tvar self = this, clusterState, status, nodeStats, clusterNodes, clusterHealth;\n\t\t\tfunction updateModel() {\n\t\t\t\tif( clusterState && status && nodeStats && clusterNodes && clusterHealth ) {\n\t\t\t\t\tthis.clusterState = clusterState;\n\t\t\t\t\tthis.status = status;\n\t\t\t\t\tthis.nodeStats = nodeStats;\n\t\t\t\t\tthis.clusterNodes = clusterNodes;\n\t\t\t\t\tthis.clusterHealth = clusterHealth;\n\t\t\t\t\tthis.fire( \"data\", this );\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar _cluster = this.cluster;\n\t\t\t_cluster.get(\"_cluster/state\", function( data ) {\n\t\t\t\tclusterState = data;\n\t\t\t\tupdateModel.call( self );\n\t\t\t},function() {\n\t\t\t\t\n\t\t\t\t_cluster.get(\"_all\", function( data ) {\n\t\t\t\t\tclusterState = {routing_table:{indices:{}}, metadata:{indices:{}}};\n\t\t\t\t\t\n\t\t\t\t\tfor(var k in data) {\n\t\t\t\t\t\tclusterState[\"routing_table\"][\"indices\"][k] = {\"shards\":{\"1\":[{\n                            \"state\":\"UNASSIGNED\",\n                            \"primary\":false,\n                            \"node\":\"unknown\",\n                            \"relocating_node\":null,\n                            \"shard\":'?',\n                            \"index\":k\n                        }]}};\n\t\t\t\t\t\t\n\n\t\t\t\t\t\tclusterState[\"metadata\"][\"indices\"][k] = {};\n\t\t\t\t\t\tclusterState[\"metadata\"][\"indices\"][k][\"mappings\"] = data[k][\"mappings\"];\n\t\t\t\t\t\tclusterState[\"metadata\"][\"indices\"][k][\"aliases\"] = $.makeArray(Object.keys(data[k][\"aliases\"]));\n\t\t\t\t\t\tclusterState[\"metadata\"][\"indices\"][k][\"settings\"] = data[k][\"settings\"];\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\tupdateModel.call( self );\n\t\t\t\t});\n\t\t\t\t\n\t\t\t});\n\t\t\tthis.cluster.get(\"_stats\", function( data ) {\n\t\t\t\tstatus = data;\n\t\t\t\tupdateModel.call( self );\n\t\t\t});\n\t\t\tthis.cluster.get(\"_nodes/stats\", function( data ) {\n\t\t\t\tnodeStats = data;\n\t\t\t\tupdateModel.call( self );\n\t\t\t});\n\t\t\tthis.cluster.get(\"_nodes\", function( data ) {\n\t\t\t\tclusterNodes = data;\n\t\t\t\tupdateModel.call( self );\n\t\t\t});\n\t\t\tthis.cluster.get(\"_cluster/health\", function( data ) {\n\t\t\t\tclusterHealth = data;\n\t\t\t\tupdateModel.call( self );\n\t\t\t});\n\t\t},\n\t\t_clusterState_handler: function(state) {\n\t\t\tthis.clusterState = state;\n\t\t\tthis.redraw(\"clusterState\");\n\t\t},\n\t\t_status_handler: function(status) {\n\t\t\tthis.status = status;\n\t\t\tthis.redraw(\"status\");\n\t\t},\n\t\t_clusterNodeStats_handler: function(stats) {\n\t\t\tthis.nodeStats = stats;\n\t\t\tthis.redraw(\"nodeStats\");\n\t\t},\n\t\t_clusterNodes_handler: function(nodes) {\n\t\t\tthis.clusterNodes = nodes;\n\t\t\tthis.redraw(\"clusterNodes\");\n\t\t},\n\t\t_clusterHealth_handler: function(health) {\n\t\t\tthis.clusterHealth = health;\n\t\t\tthis.redraw(\"status\");\n\t\t}\n\t});\n\n})( this.app );\n\n(function( $, joey, app ) {\n\n\tvar ui = app.ns(\"ui\");\n\tvar ux = app.ns(\"ux\");\n\n\tui.AbstractWidget = ux.Observable.extend({\n\t\tdefaults : {\n\t\t\tid: null     // the id of the widget\n\t\t},\n\n\t\tel: null,       // this is the jquery wrapped dom element(s) that is the root of the widget\n\n\t\tinit: function() {\n\t\t\tthis._super();\n\t\t\tfor(var prop in this) {       // automatically bind all the event handlers\n\t\t\t\tif(prop.contains(\"_handler\")) {\n\t\t\t\t\tthis[prop] = this[prop].bind(this);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\tid: function(suffix) {\n\t\t\treturn this.config.id ? (this.config.id + (suffix ? \"-\" + suffix : \"\")) : undefined;\n\t\t},\n\n\t\tattach: function( parent, method ) {\n\t\t\tif( parent ) {\n\t\t\t\tthis.el[ method || \"appendTo\"]( parent );\n\t\t\t}\n\t\t\tthis.fire(\"attached\", this );\n\t\t\treturn this;\n\t\t},\n\n\t\tremove: function() {\n\t\t\tif ( this.el !== null ) { this.el.remove(); }\n\t\t\tthis.fire(\"removed\", this );\n\t\t\tthis.removeAllObservers();\n\t\t\tthis.el = null;\n\t\t\treturn this;\n\t\t}\n\t});\n\n\tjoey.plugins.push( function( obj ) {\n\t\tif( obj instanceof ui.AbstractWidget ) {\n\t\t\treturn obj.el[0];\n\t\t}\n\t});\n\n})( this.jQuery, this.joey, this.app );\n\n(function( $, app, joey ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.AbstractField = ui.AbstractWidget.extend({\n\n\t\tdefaults: {\n\t\t\tname : \"\",\t\t\t// (required) - name of the field\n\t\t\trequire: false,\t// validation requirements (false, true, regexp, function)\n\t\t\tvalue: \"\",\t\t\t// default value\n\t\t\tlabel: \"\"\t\t\t\t// human readable label of this field\n\t\t},\n\n\t\tinit: function(parent) {\n\t\t\tthis._super();\n\t\t\tthis.el = $.joey(this._main_template());\n\t\t\tthis.field = this.el.find(\"[name=\"+this.config.name+\"]\");\n\t\t\tthis.label = this.config.label;\n\t\t\tthis.require = this.config.require;\n\t\t\tthis.name = this.config.name;\n\t\t\tthis.val( this.config.value );\n\t\t\tthis.attach( parent );\n\t\t},\n\n\t\tval: function( val ) {\n\t\t\tif(val === undefined) {\n\t\t\t\treturn this.field.val();\n\t\t\t} else {\n\t\t\t\tthis.field.val( val );\n\t\t\t\treturn this;\n\t\t\t}\n\t\t},\n\n\t\tvalidate: function() {\n\t\t\tvar val = this.val(), req = this.require;\n\t\t\tif( req === false ) {\n\t\t\t\treturn true;\n\t\t\t} else if( req === true ) {\n\t\t\t\treturn val.length > 0;\n\t\t\t} else if( req.test && $.isFunction(req.test) ) {\n\t\t\t\treturn req.test( val );\n\t\t\t} else if( $.isFunction(req) ) {\n\t\t\t\treturn req( val, this );\n\t\t\t}\n\t\t}\n\n\t});\n\n})( this.jQuery, this.app, this.joey );\n\n(function( app ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.TextField = ui.AbstractField.extend({\n\t\tinit: function() {\n\t\t\tthis._super();\n\t\t},\n\t\t_keyup_handler: function() {\n\t\t\tthis.fire(\"change\", this );\n\t\t},\n\t\t_main_template: function() {\n\t\t\treturn { tag: \"DIV\", id: this.id(), cls: \"uiField uiTextField\", children: [\n\t\t\t\t{ tag: \"INPUT\",\n\t\t\t\t\ttype: \"text\",\n\t\t\t\t\tname: this.config.name,\n\t\t\t\t\tplaceholder: this.config.placeholder,\n\t\t\t\t\tonkeyup: this._keyup_handler\n\t\t\t\t}\n\t\t\t]};\n\t\t}\n\t});\n\n})( this.app );\n\n(function( app ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.CheckField = ui.AbstractField.extend({\n\t\t_main_template: function() { return (\n\t\t\t{ tag: \"DIV\", id: this.id(), cls: \"uiCheckField\", children: [\n\t\t\t\t{ tag: \"INPUT\", type: \"checkbox\", name: this.config.name, checked: !!this.config.value }\n\t\t\t] }\n\t\t); },\n\t\tvalidate: function() {\n\t\t\treturn this.val() || ( ! this.require );\n\t\t},\n\t\tval: function( val ) {\n\t\t\tif( val === undefined ) {\n\t\t\t\treturn !!this.field.attr( \"checked\" );\n\t\t\t} else {\n\t\t\t\tthis.field.attr( \"checked\", !!val );\n\t\t\t}\n\t\t}\n\t});\n\n})( this.app );\n\n\n\n(function( $, joey, app ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.Button = ui.AbstractWidget.extend({\n\t\tdefaults : {\n\t\t\tlabel: \"\",                 // the label text\n\t\t\tdisabled: false,           // create a disabled button\n\t\t\tautoDisable: false         // automatically disable the button when clicked\n\t\t},\n\n\t\t_baseCls: \"uiButton\",\n\n\t\tinit: function(parent) {\n\t\t\tthis._super();\n\t\t\tthis.el = $.joey(this.button_template())\n\t\t\t\t.bind(\"click\", this.click_handler);\n\t\t\tthis.config.disabled && this.disable();\n\t\t\tthis.attach( parent );\n\t\t},\n\n\t\tclick_handler: function(jEv) {\n\t\t\tif(! this.disabled) {\n\t\t\t\tthis.fire(\"click\", jEv, this);\n\t\t\t\tthis.config.autoDisable && this.disable();\n\t\t\t}\n\t\t},\n\n\t\tenable: function() {\n\t\t\tthis.el.removeClass(\"disabled\");\n\t\t\tthis.disabled = false;\n\t\t\treturn this;\n\t\t},\n\n\t\tdisable: function(disable) {\n\t\t\tif(disable === false) {\n\t\t\t\t\treturn this.enable();\n\t\t\t}\n\t\t\tthis.el.addClass(\"disabled\");\n\t\t\tthis.disabled = true;\n\t\t\treturn this;\n\t\t},\n\n\t\tbutton_template: function() { return (\n\t\t\t{ tag: 'BUTTON', type: 'button', id: this.id(), cls: this._baseCls, children: [\n\t\t\t\t{ tag: 'DIV', cls: 'uiButton-content', children: [\n\t\t\t\t\t{ tag: 'DIV', cls: 'uiButton-label', text: this.config.label }\n\t\t\t\t] }\n\t\t\t] }\n\t\t); }\n\t});\n\n})( this.jQuery, this.joey, this.app );\n\n(function( $, app ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.MenuButton = app.ui.Button.extend({\n\t\tdefaults: {\n\t\t\tmenu: null\n\t\t},\n\t\t_baseCls: \"uiButton uiMenuButton\",\n\t\tinit: function(parent) {\n\t\t\tthis._super(parent);\n\t\t\tthis.menu = this.config.menu;\n\t\t\tthis.on(\"click\", this.openMenu_handler);\n\t\t\tthis.menu.on(\"open\", function() { this.el.addClass(\"active\"); }.bind(this));\n\t\t\tthis.menu.on(\"close\", function() { this.el.removeClass(\"active\"); }.bind(this));\n\t\t},\n\t\topenMenu_handler: function(jEv) {\n\t\t\tthis.menu && this.menu.open(jEv);\n\t\t}\n\t});\n\n})( this.jQuery, this.app );\n\n(function( $, app ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.SplitButton = ui.AbstractWidget.extend({\n\t\tdefaults: {\n\t\t\titems: [],\n\t\t\tlabel: \"\"\n\t\t},\n\t\t_baseCls: \"uiSplitButton\",\n\t\tinit: function( parent ) {\n\t\t\tthis._super( parent );\n\t\t\tthis.value = null;\n\t\t\tthis.button = new ui.Button({\n\t\t\t\tlabel: this.config.label,\n\t\t\t\tonclick: this._click_handler\n\t\t\t});\n\t\t\tthis.menu = new ui.SelectMenuPanel({\n\t\t\t\tvalue: this.config.value,\n\t\t\t\titems: this._getItems(),\n\t\t\t\tonSelect: this._select_handler\n\t\t\t});\n\t\t\tthis.menuButton = new ui.MenuButton({\n\t\t\t\tlabel: \"\\u00a0\",\n\t\t\t\tmenu: this.menu\n\t\t\t});\n\t\t\tthis.el = $.joey(this._main_template());\n\t\t},\n\t\tremove: function() {\n\t\t\tthis.menu.remove();\n\t\t},\n\t\tdisable: function() {\n\t\t\tthis.button.disable();\n\t\t},\n\t\tenable: function() {\n\t\t\tthis.button.enable();\n\t\t},\n\t\t_click_handler: function() {\n\t\t\tthis.fire(\"click\", this, { value: this.value } );\n\t\t},\n\t\t_select_handler: function( panel, event ) {\n\t\t\tthis.fire( \"select\", this, event );\n\t\t},\n\t\t_getItems: function() {\n\t\t\treturn this.config.items;\n\t\t},\n\t\t_main_template: function() {\n\t\t\treturn { tag: \"DIV\", cls: this._baseCls, children: [\n\t\t\t\tthis.button, this.menuButton\n\t\t\t] };\n\t\t}\n\t});\n\n})( this.jQuery, this.app );\n\n(function( $, app, i18n ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.RefreshButton = ui.SplitButton.extend({\n\t\tdefaults: {\n\t\t\ttimer: -1\n\t\t},\n\t\tinit: function( parent ) {\n\t\t\tthis.config.label = i18n.text(\"General.RefreshResults\");\n\t\t\tthis._super( parent );\n\t\t\tthis.set( this.config.timer );\n\t\t},\n\t\tset: function( value ) {\n\t\t\tthis.value = value;\n\t\t\twindow.clearInterval( this._timer );\n\t\t\tif( this.value > 0 ) {\n\t\t\t\tthis._timer = window.setInterval( this._refresh_handler, this.value );\n\t\t\t}\n\t\t},\n\t\t_click_handler: function() {\n\t\t\tthis._refresh_handler();\n\t\t},\n\t\t_select_handler: function( el, event ) {\n\t\t\tthis.set( event.value );\n\t\t\tthis.fire(\"change\", this );\n\t\t},\n\t\t_refresh_handler: function() {\n\t\t\tthis.fire(\"refresh\", this );\n\t\t},\n\t\t_getItems: function() {\n\t\t\treturn [\n\t\t\t\t{ text: i18n.text(\"General.ManualRefresh\"), value: -1 },\n\t\t\t\t{ text: i18n.text(\"General.RefreshQuickly\"), value: 100 },\n\t\t\t\t{ text: i18n.text(\"General.Refresh5seconds\"), value: 5000 },\n\t\t\t\t{ text: i18n.text(\"General.Refresh1minute\"), value: 60000 }\n\t\t\t];\n\t\t}\n\t});\n\n})( this.jQuery, this.app, this.i18n );\n\n(function( $, app ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.Toolbar = ui.AbstractWidget.extend({\n\t\tdefaults: {\n\t\t\tlabel: \"\",\n\t\t\tleft: [],\n\t\t\tright: []\n\t\t},\n\t\tinit: function(parent) {\n\t\t\tthis._super();\n\t\t\tthis.el = $.joey(this._main_template());\n\t\t},\n\t\t_main_template: function() {\n\t\t\treturn { tag: \"DIV\", cls: \"uiToolbar\", children: [\n\t\t\t\t{ tag: \"DIV\", cls: \"pull-left\", children: [\n\t\t\t\t\t{ tag: \"H2\", text: this.config.label }\n\t\t\t\t].concat(this.config.left) },\n\t\t\t\t{ tag: \"DIV\", cls: \"pull-right\", children: this.config.right }\n\t\t\t]};\n\t\t}\n\t});\n\n})( this.jQuery, this.app );\n\n(function( $, app ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.AbstractPanel = ui.AbstractWidget.extend({\n\t\tdefaults: {\n\t\t\tbody: null,            // initial content of the body\n\t\t\tmodal: true,           // create a modal panel - creates a div that blocks interaction with page\n\t\t\theight: 'auto',        // panel height\n\t\t\twidth: 400,            // panel width (in pixels)\n\t\t\topen: false,           // show the panel when it is created\n\t\t\tparent: 'BODY',        // node that panel is attached to\n\t\t\tautoRemove: false      // remove the panel from the dom and destroy it when the widget is closed\n\t\t},\n\t\tshared: {  // shared data for all instances of ui.Panel and decendants\n\t\t\tstack: [], // array of all open panels\n\t\t\tmodal: $( { tag: \"DIV\", id: \"uiModal\", css: { opacity: 0.2, position: \"absolute\", top: \"0px\", left: \"0px\" } } )\n\t\t},\n\t\tinit: function() {\n\t\t\tthis._super();\n\t\t},\n\t\topen: function( ev ) {\n\t\t\tthis.el\n\t\t\t\t.css( { visibility: \"hidden\" } )\n\t\t\t\t.appendTo( this.config.parent )\n\t\t\t\t.css( this._getPosition( ev ) )\n\t\t\t\t.css( { zIndex: (this.shared.stack.length ? (+this.shared.stack[this.shared.stack.length - 1].el.css(\"zIndex\") + 10) : 100) } )\n\t\t\t\t.css( { visibility: \"visible\", display: \"block\" } );\n\t\t\tthis.shared.stack.remove(this);\n\t\t\tthis.shared.stack.push(this);\n\t\t\tthis._setModal();\n\t\t\t$(document).bind(\"keyup\", this._close_handler );\n\t\t\tthis.fire(\"open\", { source: this, event: ev } );\n\t\t\treturn this;\n\t\t},\n\t\tclose: function() {\n\t\t\tvar index = this.shared.stack.indexOf(this);\n\t\t\tif(index !== -1) {\n\t\t\t\tthis.shared.stack.splice(index, 1);\n\t\t\t\tthis.el.css( { left: \"-2999px\" } ); // move the dialog to the left rather than hiding to prevent ie6 rendering artifacts\n\t\t\t\tthis._setModal();\n\t\t\t\tthis.fire(\"close\", this );\n\t\t\t\tif(this.config.autoRemove) {\n\t\t\t\t\tthis.remove();\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn this;\n\t\t},\n\t\t// close the panel and remove it from the dom, destroying it (you can not reuse the panel after calling remove)\n\t\tremove: function() {\n\t\t\tthis.close();\n\t\t\t$(document).unbind(\"keyup\", this._close_handler );\n\t\t\tthis._super();\n\t\t},\n\t\t// starting at the top of the stack, find the first panel that wants a modal and put it just underneath, otherwise remove the modal\n\t\t_setModal: function() {\n\t\t\tfor(var stackPtr = this.shared.stack.length - 1; stackPtr >= 0; stackPtr--) {\n\t\t\t\tif(this.shared.stack[stackPtr].config.modal) {\n\t\t\t\t\tthis.shared.modal\n\t\t\t\t\t\t.appendTo( document.body )\n\t\t\t\t\t\t.css( { zIndex: this.shared.stack[stackPtr].el.css(\"zIndex\") - 5 } )\n\t\t\t\t\t\t.css( $(document).vSize().asSize() );\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.shared.modal.remove(); // no panels that want a modal were found\n\t\t},\n\t\t_getPosition: function() {\n\t\t\treturn $(window).vSize()                        // get the current viewport size\n\t\t\t\t.sub(this.el.vSize())                         // subtract the size of the panel\n\t\t\t\t.mod(function(s) { return s / 2; })           // divide by 2 (to center it)\n\t\t\t\t.add($(document).vScroll())                   // add the current scroll offset\n\t\t\t\t.mod(function(s) { return Math.max(5, s); })  // make sure the panel is not off the edge of the window\n\t\t\t\t.asOffset();                                  // and return it as a {top, left} object\n\t\t},\n\t\t_close_handler: function( ev ) {\n\t\t\tif( ev.type === \"keyup\" && ev.keyCode !== 27) { return; } // press esc key to close\n\t\t\t$(document).unbind(\"keyup\", this._close_handler);\n\t\t\tthis.close( ev );\n\t\t}\n\t});\n\n})( this.jQuery, this.app );\n\n(function( $, app ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.DraggablePanel = ui.AbstractPanel.extend({\n\t\tdefaults: {\n\t//\t\ttitle: \"\"   // (required) text for the panel title\n\t\t},\n\n\t\t_baseCls: \"uiPanel\",\n\n\t\tinit: function() {\n\t\t\tthis._super();\n\t\t\tthis.body = $(this._body_template());\n\t\t\tthis.title = $(this._title_template());\n\t\t\tthis.el = $.joey( this._main_template() );\n\t\t\tthis.el.css( { width: this.config.width } );\n\t\t\tthis.dd = new app.ux.DragDrop({\n\t\t\t\tpickupSelector: this.el.find(\".uiPanel-titleBar\"),\n\t\t\t\tdragObj: this.el\n\t\t\t});\n\t\t\t// open the panel if set in configuration\n\t\t\tthis.config.open && this.open();\n\t\t},\n\n\t\tsetBody: function(body) {\n\t\t\t\tthis.body.empty().append(body);\n\t\t},\n\t\t_body_template: function() { return { tag: \"DIV\", cls: \"uiPanel-body\", css: { height: this.config.height + (this.config.height === 'auto' ? \"\" : \"px\" ) }, children: [ this.config.body ] }; },\n\t\t_title_template: function() { return { tag: \"SPAN\", cls: \"uiPanel-title\", text: this.config.title }; },\n\t\t_main_template: function() { return (\n\t\t\t{ tag: \"DIV\", id: this.id(), cls: this._baseCls, children: [\n\t\t\t\t{ tag: \"DIV\", cls: \"uiPanel-titleBar\", children: [\n\t\t\t\t\t{ tag: \"DIV\", cls: \"uiPanel-close\", onclick: this._close_handler, text: \"x\" },\n\t\t\t\t\tthis.title\n\t\t\t\t]},\n\t\t\t\tthis.body\n\t\t\t] }\n\t\t); }\n\t});\n\n})( this.jQuery, this.app );\n\n(function( app ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.InfoPanel = ui.DraggablePanel.extend({\n\t\t_baseCls: \"uiPanel uiInfoPanel\"\n\t});\n\n})( this.app );\n\n(function( app ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.DialogPanel = ui.DraggablePanel.extend({\n\t\t_commit_handler: function(jEv) {\n\t\t\tthis.fire(\"commit\", this, { jEv: jEv });\n\t\t},\n\t\t_main_template: function() {\n\t\t\tvar t = this._super();\n\t\t\tt.children.push(this._actionsBar_template());\n\t\t\treturn t;\n\t\t},\n\t\t_actionsBar_template: function() {\n\t\t\treturn { tag: \"DIV\", cls: \"pull-right\", children: [\n\t\t\t\tnew app.ui.Button({ label: \"Cancel\", onclick: this._close_handler }),\n\t\t\t\tnew app.ui.Button({ label: \"OK\", onclick: this._commit_handler })\n\t\t\t]};\n\t\t}\n\t});\n\n})( this.app );\n\n(function( app ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.MenuPanel = ui.AbstractPanel.extend({\n\t\tdefaults: {\n\t\t\titems: [],\t\t// (required) an array of menu items\n\t\t\tmodal: false\n\t\t},\n\t\t_baseCls: \"uiMenuPanel\",\n\t\tinit: function() {\n\t\t\tthis._super();\n\t\t\tthis.el = $(this._main_template());\n\t\t},\n\t\topen: function(jEv) {\n\t\t\tthis._super(jEv);\n\t\t\tvar cx = this; setTimeout(function() { $(document).bind(\"click\", cx._close_handler); }, 50);\n\t\t},\n\t\t_getItems: function() {\n\t\t\treturn this.config.items;\n\t\t},\n\t\t_close_handler: function(jEv) {\n\t\t\tthis._super(jEv);\n\t\t\t$(document).unbind(\"click\", this._close_handler);\n\t\t},\n\t\t_main_template: function() {\n\t\t\treturn { tag: \"DIV\", cls: this._baseCls, children: this._getItems().map(this._menuItem_template, this) };\n\t\t},\n\t\t_menuItem_template: function(item) {\n\t\t\tvar dx = item.disabled ? { onclick: function() {} } : {};\n\t\t\treturn { tag: \"LI\", cls: \"uiMenuPanel-item\" + (item.disabled ? \" disabled\" : \"\") + (item.selected ? \" selected\" : \"\"), children: [ $.extend({ tag: \"DIV\", cls: \"uiMenuPanel-label\" }, item, dx ) ] };\n\t\t},\n\t\t_getPosition: function(jEv) {\n\t\t\tvar right = !! $(jEv.target).parents(\".pull-right\").length;\n\t\t\tvar parent = $(jEv.target).closest(\"BUTTON\");\n\t\t\treturn parent.vOffset()\n\t\t\t\t.addY(parent.vSize().y)\n\t\t\t\t.addX( right ? parent.vSize().x - this.el.vOuterSize().x : 0 )\n\t\t\t\t.asOffset();\n\t\t}\n\t});\n\n})( this.app );\n\n(function( app ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.SelectMenuPanel = ui.MenuPanel.extend({\n\t\tdefaults: {\n\t\t\titems: [],\t\t// (required) an array of menu items\n\t\t\tvalue: null\n\t\t},\n\t\t_baseCls: \"uiSelectMenuPanel uiMenuPanel\",\n\t\tinit: function() {\n\t\t\tthis.value = this.config.value;\n\t\t\tthis._super();\n\t\t},\n\t\t_getItems: function() {\n\t\t\treturn this.config.items.map( function( item ) {\n\t\t\t\treturn {\n\t\t\t\t\ttext: item.text,\n\t\t\t\t\tselected: this.value === item.value,\n\t\t\t\t\tonclick: function( jEv ) {\n\t\t\t\t\t\tvar el = $( jEv.target ).closest(\"LI\");\n\t\t\t\t\t\tel.parent().children().removeClass(\"selected\");\n\t\t\t\t\t\tel.addClass(\"selected\");\n\t\t\t\t\t\tthis.fire( \"select\", this, { value: item.value } );\n\t\t\t\t\t\tthis.value = item.value;\n\t\t\t\t\t}.bind(this)\n\t\t\t\t};\n\t\t\t}, this );\n\n\t\t}\n\t});\n\n})( this.app );\n\n( function( $, app ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.Table = ui.AbstractWidget.extend({\n\t\tdefaults: {\n\t\t\tstore: null, // (required) implements interface app.data.DataSourceInterface\n\t\t\theight: 0,\n\t\t\twidth: 0\n\t\t},\n\t\t_baseCls: \"uiTable\",\n\t\tinit: function(parent) {\n\t\t\tthis._super();\n\t\t\tthis.initElements(parent);\n\t\t\tthis.config.store.on(\"data\", this._data_handler);\n\t\t},\n\t\tattach: function(parent) {\n\t\t\tif(parent) {\n\t\t\t\tthis._super(parent);\n\t\t\t\tthis._reflow();\n\t\t\t}\n\t\t},\n\t\tinitElements: function(parent) {\n\t\t\tthis.el = $.joey(this._main_template());\n\t\t\tthis.body = this.el.find(\".uiTable-body\");\n\t\t\tthis.headers = this.el.find(\".uiTable-headers\");\n\t\t\tthis.tools = this.el.find(\".uiTable-tools\");\n\t\t\tthis.attach( parent );\n\t\t},\n\t\t_data_handler: function(store) {\n\t\t\tthis.tools.text(store.summary);\n\t\t\tthis.headers.empty().append(this._header_template(store.columns));\n\t\t\tthis.body.empty().append(this._body_template(store.data, store.columns));\n\t\t\tthis._reflow();\n\t\t},\n\t\t_reflow: function() {\n\t\t\tvar firstCol = this.body.find(\"TR:first TH.uiTable-header-cell > DIV\"),\n\t\t\t\t\theaders = this.headers.find(\"TR:first TH.uiTable-header-cell > DIV\");\n\t\t\tfor(var i = 0; i < headers.length; i++) {\n\t\t\t\t$(headers[i]).width( $(firstCol[i]).width() );\n\t\t\t}\n\t\t\tthis._scroll_handler();\n\t\t},\n\t\t_scroll_handler: function(ev) {\n\t\t\tthis.el.find(\".uiTable-headers\").scrollLeft(this.body.scrollLeft());\n\t\t},\n\t\t_dataClick_handler: function(ev) {\n\t\t\tvar row = $(ev.target).closest(\"TR\");\n\t\t\tif(row.length) {\n\t\t\t\tthis.fire(\"rowClick\", this, { row: row } );\n\t\t\t}\n\t\t},\n\t\t_headerClick_handler: function(ev) {\n\t\t\tvar header = $(ev.target).closest(\"TH.uiTable-header-cell\");\n\t\t\tif(header.length) {\n\t\t\t\tthis.fire(\"headerClick\", this, { header: header, column: header.data(\"column\"), dir: header.data(\"dir\") });\n\t\t\t}\n\t\t},\n\t\t_main_template: function() {\n\t\t\treturn { tag: \"DIV\", id: this.id(), css: { width: this.config.width + \"px\" }, cls: this._baseCls, children: [\n\t\t\t\t{ tag: \"DIV\", cls: \"uiTable-tools\" },\n\t\t\t\t{ tag: \"DIV\", cls: \"uiTable-headers\", onclick: this._headerClick_handler },\n\t\t\t\t{ tag: \"DIV\", cls: \"uiTable-body\",\n\t\t\t\t\tonclick: this._dataClick_handler,\n\t\t\t\t\tonscroll: this._scroll_handler,\n\t\t\t\t\tcss: { height: this.config.height + \"px\", width: this.config.width + \"px\" }\n\t\t\t\t}\n\t\t\t] };\n\t\t},\n\t\t_header_template: function(columns) {\n\t\t\tvar ret = { tag: \"TABLE\", children: [ this._headerRow_template(columns) ] };\n\t\t\tret.children[0].children.push(this._headerEndCap_template());\n\t\t\treturn ret;\n\t\t},\n\t\t_headerRow_template: function(columns) {\n\t\t\treturn { tag: \"TR\", cls: \"uiTable-header-row\", children: columns.map(function(column) {\n\t\t\t\tvar dir = ((this.config.store.sort.column === column) && this.config.store.sort.dir) || \"none\";\n\t\t\t\treturn { tag: \"TH\", data: { column: column, dir: dir }, cls: \"uiTable-header-cell\" + ((dir !== \"none\") ? \" uiTable-sort\" : \"\"), children: [\n\t\t\t\t\t{ tag: \"DIV\", children: [\n\t\t\t\t\t\t{ tag: \"DIV\", cls: \"uiTable-headercell-menu\", text: dir === \"asc\" ? \"\\u25b2\" : \"\\u25bc\" },\n\t\t\t\t\t\t{ tag: \"DIV\", cls: \"uiTable-headercell-text\", text: column }\n\t\t\t\t\t]}\n\t\t\t\t]};\n\t\t\t}, this)};\n\t\t},\n\t\t_headerEndCap_template: function() {\n\t\t\treturn { tag: \"TH\", cls: \"uiTable-headerEndCap\", children: [ { tag: \"DIV\" } ] };\n\t\t},\n\t\t_body_template: function(data, columns) {\n\t\t\treturn { tag: \"TABLE\", children: []\n\t\t\t\t.concat(this._headerRow_template(columns))\n\t\t\t\t.concat(data.map(function(row) {\n\t\t\t\t\treturn { tag: \"TR\", data: { row: row }, cls: \"uiTable-row\", children: columns.map(function(column){\n\t\t\t\t\t\treturn { tag: \"TD\", cls: \"uiTable-cell\", children: [ { tag: \"DIV\", text: (row[column] || \"\").toString() } ] };\n\t\t\t\t\t})};\n\t\t\t\t}))\n\t\t\t};\n\t\t}\n\n\t});\n\n})( this.jQuery, this.app );\n\n( function( $, app, joey ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tvar CELL_SEPARATOR = \",\";\n\tvar CELL_QUOTE = '\"';\n\tvar LINE_SEPARATOR = \"\\r\\n\";\n\n\tui.CSVTable = ui.AbstractWidget.extend({\n\t\tdefaults: {\n\t\t\tresults: null\n\t\t},\n\t\t_baseCls: \"uiCSVTable\",\n\t\tinit: function( parent ) {\n\t\t\tthis._super();\n\t\t\tvar results = this.config.results.hits.hits;\n\t\t\tvar columns = this._parseResults( results );\n\t\t\tthis._downloadButton = new ui.Button({\n\t\t\t\tlabel: \"Generate Download Link\",\n\t\t\t\tonclick: this._downloadLinkGenerator_handler\n\t\t\t});\n\t\t\tthis._downloadLink = $.joey( { tag: \"A\", text: \"download\", });\n\t\t\tthis._downloadLink.hide();\n\t\t\tthis._csvText = this._csv_template( columns, results );\n\t\t\tthis.el = $.joey( this._main_template() );\n\t\t\tthis.attach( parent );\n\t\t},\n\t\t_downloadLinkGenerator_handler: function() {\n\t\t\tvar csvData = new Blob( [ this._csvText ], { type: 'text/csv' });\n\t\t\tvar csvURL = URL.createObjectURL( csvData );\n\t\t\tthis._downloadLink.attr( \"href\", csvURL );\n\t\t\tthis._downloadLink.show();\n\t\t},\n\t\t_parseResults: function( results ) {\n\t\t\tvar columnPaths = {};\n\t\t\t(function parse( path, obj ) {\n\t\t\t\tif( obj instanceof Array ) {\n\t\t\t\t\tfor( var i = 0; i < obj.length; i++ ) {\n\t\t\t\t\t\tparse( path, obj[i] );\n\t\t\t\t\t}\n\t\t\t\t} else if( typeof obj === \"object\" ) {\n\t\t\t\t\tfor( var prop in obj ) {\n\t\t\t\t\t\tparse( path + \".\" + prop, obj[ prop ] );\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tcolumnPaths[ path ] = true;\n\t\t\t\t}\n\t\t\t})( \"root\", results );\n\t\t\tvar columns = [];\n\t\t\tfor( var column in columnPaths ) {\n\t\t\t\tcolumns.push( column.split(\".\").slice(1) );\n\t\t\t}\n\t\t\treturn columns;\n\t\t},\n\t\t_main_template: function() { return (\n\t\t\t{ tag: \"DIV\", cls: this._baseCls, id: this.id(), children: [\n\t\t\t\tthis._downloadButton,\n\t\t\t\tthis._downloadLink,\n\t\t\t\t{ tag: \"PRE\", text: this._csvText }\n\t\t\t] }\n\t\t); },\n\t\t_csv_template: function( columns, results ) {\n\t\t\treturn this._header_template( columns ) + LINE_SEPARATOR + this._results_template( columns, results );\n\t\t},\n\t\t_header_template: function( columns ) {\n\t\t\treturn columns.map( function( column ) {\n\t\t\t\treturn column.join(\".\");\n\t\t\t}).join( CELL_SEPARATOR );\n\t\t},\n\t\t_results_template: function( columns, results ) {\n\t\t\treturn results.map( function( result ) {\n\t\t\t\treturn columns.map( function( column ) {\n\t\t\t\t\tvar l = 0,\n\t\t\t\t\t\tptr = result;\n\t\t\t\t\twhile( l !== column.length && ptr != null ) {\n\t\t\t\t\t\tptr = ptr[ column[ l++ ] ];\n\t\t\t\t\t}\n\t\t\t\t\treturn ( ptr == null ) ? \"\" : ( CELL_QUOTE + ptr.toString().replace(/\"/g, '\"\"') + CELL_QUOTE );\n\t\t\t\t}).join( CELL_SEPARATOR );\n\t\t\t}).join( LINE_SEPARATOR );\n\t\t}\n\t});\n\n})( this.jQuery, this.app, this.joey );\n\n(function( $, app ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.JsonPretty = ui.AbstractWidget.extend({\n\t\tdefaults: {\n\t\t\tobj: null\n\t\t},\n\t\tinit: function(parent) {\n\t\t\tthis._super();\n\t\t\tthis.el = $(this._main_template());\n\t\t\tthis.attach(parent);\n\t\t\tthis.el.click(this._click_handler);\n\t\t},\n\t\t\n\t\t_click_handler: function(jEv) {\n\t\t\tvar t = $(jEv.target).closest(\".uiJsonPretty-name\").closest(\"LI\");\n\t\t\tif(t.length === 0 || t.parents(\".uiJsonPretty-minimised\").length > 0) { return; }\n\t\t\tt.toggleClass(\"uiJsonPretty-minimised\");\n\t\t\tjEv.stopPropagation();\n\t\t},\n\t\t\n\t\t_main_template: function() {\n\t\t\ttry {\n\t\t\t\t\treturn { tag: \"DIV\", cls: \"uiJsonPretty\", children: this.pretty.parse(this.config.obj) };\n\t\t\t}\tcatch (error) {\n\t\t\t\t\tthrow \"JsonPretty error: \" + error.message;\n\t\t\t}\n\t\t},\n\t\t\n\t\tpretty: { // from https://github.com/RyanAmos/Pretty-JSON/blob/master/pretty_json.js\n\t\t\t\"expando\" : function(value) {\n\t\t\t\treturn (value && (/array|object/i).test(value.constructor.name)) ? \"expando\" : \"\";\n\t\t\t},\n\t\t\t\"parse\": function (member) {\n\t\t\t\treturn this[(member == null) ? 'null' : member.constructor.name.toLowerCase()](member);\n\t\t\t},\n\t\t\t\"null\": function (value) {\n\t\t\t\treturn this['value']('null', 'null');\n\t\t\t},\n\t\t\t\"array\": function (value) {\n\t\t\t\tvar results = [];\n\t\t\t\tvar lastItem = value.length - 1;\n\t\t\t\tvalue.forEach(function( v, i ) {\n\t\t\t\t\tresults.push({ tag: \"LI\", cls: this.expando(v), children: [ this['parse'](v) ] });\n\t\t\t\t\tif( i !== lastItem ) {\n\t\t\t\t\t\tresults.push(\",\");\n\t\t\t\t\t}\n\t\t\t\t}, this);\n\t\t\t\treturn [ \"[ \", ((results.length > 0) ? { tag: \"UL\", cls: \"uiJsonPretty-array\", children: results } : null), \"]\" ];\n\t\t\t},\n\t\t\t\"object\": function (value) {\n\t\t\t\tvar results = [];\n\t\t\t\tvar keys = Object.keys( value );\n\t\t\t\tvar lastItem = keys.length - 1;\n\t\t\t\tkeys.forEach( function( key, i ) {\n\t\t\t\t\tvar children = [ this['value']( 'name', '\"' + key + '\"' ), \": \", this['parse']( value[ key ]) ];\n\t\t\t\t\tif( i !== lastItem ) {\n\t\t\t\t\t\tchildren.push(\",\");\n\t\t\t\t\t}\n\t\t\t\t\tresults.push( { tag: \"LI\", cls: this.expando( value[ key ] ), children: children } );\n\t\t\t\t}, this);\n\t\t\t\treturn [ \"{ \", ((results.length > 0) ? { tag: \"UL\", cls: \"uiJsonPretty-object\", children: results } : null ),  \"}\" ];\n\t\t\t},\n\t\t\t\"number\": function (value) {\n\t\t\t\treturn this['value']('number', value.toString());\n\t\t\t},\n\t\t\t\"string\": function (value) {\n\t\t\t\tif (/^(http|https|file):\\/\\/[^\\s]+$/.test(value)) {\n\t\t\t\t\treturn this['link']( value );\n\t\t\t\t} else {\n\t\t\t\t\treturn this['value']('string', '\"' + value.toString() + '\"');\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"boolean\": function (value) {\n\t\t\t\treturn this['value']('boolean', value.toString());\n\t\t\t},\n\t\t\t\"link\": function( value ) {\n\t\t\t\t\treturn this['value'](\"string\", { tag: \"A\", href: value, target: \"_blank\", text: '\"' + value + '\"' } );\n\t\t\t},\n\t\t\t\"value\": function (type, value) {\n\t\t\t\tif (/^(http|https|file):\\/\\/[^\\s]+$/.test(value)) {\n\t\t\t\t}\n\t\t\t\treturn { tag: \"SPAN\", cls: \"uiJsonPretty-\" + type, text: value };\n\t\t\t}\n\t\t}\n\t});\n\n})( this.jQuery, this.app );\n\n(function( $, app ) {\n\n\tvar ui = app.ns(\"ui\");\n\tvar ut = app.ns(\"ut\");\n\n\tui.PanelForm = ui.AbstractWidget.extend({\n\t\tdefaults: {\n\t\t\tfields: null\t// (required) instanceof app.ux.FieldCollection\n\t\t},\n\t\tinit: function(parent) {\n\t\t\tthis._super();\n\t\t\tthis.el = $.joey(this._main_template());\n\t\t\tthis.attach( parent );\n\t\t},\n\t\t_main_template: function() {\n\t\t\treturn { tag: \"DIV\", id: this.id(), cls: \"uiPanelForm\", children: this.config.fields.fields.map(this._field_template, this) };\n\t\t},\n\t\t_field_template: function(field) {\n\t\t\treturn { tag: \"LABEL\", cls: \"uiPanelForm-field\", children: [\n\t\t\t\t{ tag: \"DIV\", cls: \"uiPanelForm-label\", children: [ field.label, ut.require_template(field) ] },\n\t\t\t\tfield\n\t\t\t]};\n\t\t}\n\t});\n\n})( this.jQuery, this.app );\n\n(function( app ){\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.HelpPanel = ui.InfoPanel.extend({\n\t\tdefaults: {\n\t\t\tref: \"\",\n\t\t\topen: true,\n\t\t\tautoRemove: true,\n\t\t\tmodal: false,\n\t\t\twidth: 500,\n\t\t\theight: 450,\n\t\t\ttitle: i18n.text(\"General.Help\")\n\t\t},\n\t\tinit: function() {\n\t\t\tthis._super();\n\t\t\tthis.body.append(i18n.text(this.config.ref));\n\t\t}\n\t});\n\n})( this.app );\n\n(function( app ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.JsonPanel = ui.InfoPanel.extend({\n\t\tdefaults: {\n\t\t\tjson: null, // (required)\n\t\t\tmodal: false,\n\t\t\topen: true,\n\t\t\tautoRemove: true,\n\t\t\theight: 500,\n\t\t\twidth: 600\n\t\t},\n\n\t\t_baseCls: \"uiPanel uiInfoPanel uiJsonPanel\",\n\n\t\t_body_template: function() {\n\t\t\tvar body = this._super();\n\t\t\tbody.children = [ new ui.JsonPretty({ obj: this.config.json }) ];\n\t\t\treturn body;\n\t\t}\n\t});\n\n})( this.app );\n\n(function( $, app, i18n ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.SidebarSection = ui.AbstractWidget.extend({\n\t\tdefaults: {\n\t\t\ttitle: \"\",\n\t\t\thelp: null,\n\t\t\tbody: null,\n\t\t\topen: false\n\t\t},\n\t\tinit: function() {\n\t\t\tthis._super();\n\t\t\tthis.el = $.joey( this._main_template() );\n\t\t\tthis.body = this.el.children(\".uiSidebarSection-body\");\n\t\t\tthis.config.open && ( this.el.addClass(\"shown\") && this.body.css(\"display\", \"block\") );\n\t\t},\n\t\t_showSection_handler: function( ev ) {\n\t\t\tvar shown = $( ev.target ).closest(\".uiSidebarSection\")\n\t\t\t\t.toggleClass(\"shown\")\n\t\t\t\t\t.children(\".uiSidebarSection-body\").slideToggle(200, function() { this.fire(\"animComplete\", this); }.bind(this))\n\t\t\t\t.end()\n\t\t\t\t.hasClass(\"shown\");\n\t\t\tthis.fire(shown ? \"show\" : \"hide\", this);\n\t\t},\n\t\t_showHelp_handler: function( ev ) {\n\t\t\tnew ui.HelpPanel({ref: this.config.help});\n\t\t\tev.stopPropagation();\n\t\t},\n\t\t_main_template: function() { return (\n\t\t\t{ tag: \"DIV\", cls: \"uiSidebarSection\", children: [\n\t\t\t\t(this.config.title && { tag: \"DIV\", cls: \"uiSidebarSection-head\", onclick: this._showSection_handler, children: [\n\t\t\t\t\tthis.config.title,\n\t\t\t\t\t( this.config.help && { tag: \"SPAN\", cls: \"uiSidebarSection-help pull-right\", onclick: this._showHelp_handler, text: i18n.text(\"General.HelpGlyph\") } )\n\t\t\t\t] }),\n\t\t\t\t{ tag: \"DIV\", cls: \"uiSidebarSection-body\", children: [ this.config.body ] }\n\t\t\t] }\n\t\t); }\n\t});\n\n})( this.jQuery, this.app, this.i18n );\n\n(function( $, app ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.ResultTable = ui.Table.extend({\n\t\tdefaults: {\n\t\t\twidth: 500,\n\t\t\theight: 400\n\t\t},\n\n\t\tinit: function() {\n\t\t\tthis._super();\n\t\t\tthis.on(\"rowClick\", this._showPreview_handler);\n\t\t\tthis.selectedRow = null;\n\t\t\t$(document).bind(\"keydown\", this._nav_handler);\n\t\t},\n\t\tremove: function() {\n\t\t\t$(document).unbind(\"keydown\", this._nav_handler);\n\t\t\tthis._super();\n\t\t},\n\t\tattach: function(parent) {\n\t\t\tif(parent) {\n\t\t\t\tvar height = parent.height() || ( $(document).height() - parent.offset().top - 41 ); // 41 = height in px of .uiTable-tools + uiTable-header\n\t\t\t\tvar width = parent.width();\n\t\t\t\tthis.el.width( width );\n\t\t\t\tthis.body.width( width ).height( height );\n\t\t\t}\n\t\t\tthis._super(parent);\n\t\t},\n\t\tshowPreview: function(row) {\n\t\t\trow.addClass(\"selected\");\n\t\t\tthis.preview = new app.ui.JsonPanel({\n\t\t\t\ttitle: i18n.text(\"Browser.ResultSourcePanelTitle\"),\n\t\t\t\tjson: row.data(\"row\")._source,\n\t\t\t\tonClose: function() { row.removeClass(\"selected\"); }\n\t\t\t});\n\t\t},\n\t\t_nav_handler: function(jEv) {\n\t\t\tif(jEv.keyCode !== 40 && jEv.keyCode !== 38) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.selectedRow && this.preview && this.preview.remove();\n\t\t\tif(jEv.keyCode === 40) { // up arrow\n\t\t\t\tthis.selectedRow = this.selectedRow ? this.selectedRow.next(\"TR\") : this.body.find(\"TR:first\");\n\t\t\t} else if(jEv.keyCode === 38) { // down arrow\n\t\t\t\tthis.selectedRow = this.selectedRow ? this.selectedRow.prev(\"TR\") : this.body.find(\"TR:last\");\n\t\t\t}\n\t\t\tthis.selectedRow && this.showPreview(this.selectedRow);\n\t\t},\n\t\t_showPreview_handler: function(obj, data) {\n\t\t\tthis.showPreview(this.selectedRow = data.row);\n\t\t}\n\t});\n\n})( this.jQuery, this.app );\n\n(function( $, app, i18n ) {\n\n\tvar ui = app.ns(\"ui\");\n\tvar ut = app.ns(\"ut\");\n\n\tui.QueryFilter = ui.AbstractWidget.extend({\n\t\tdefaults: {\n\t\t\tmetadata: null,   // (required) instanceof app.data.MetaData\n\t\t\tquery: null       // (required) instanceof app.data.Query that the filters will act apon\n\t\t},\n\t\tinit: function() {\n\t\t\tthis._super();\n\t\t\tthis.metadata = this.config.metadata;\n\t\t\tthis.query = this.config.query;\n\t\t\tthis.el = $(this._main_template());\n\t\t},\n\t\thelpTypeMap: {\n\t\t\t\"date\" : \"QueryFilter.DateRangeHelp\"\n\t\t},\n\t\trequestUpdate: function(jEv) {\n\t\t\tif(jEv && jEv.originalEvent) { // we only want to update on real user interaction not generated events\n\t\t\t\tthis.query.setPage(1);\n\t\t\t\tthis.query.query();\n\t\t\t}\n\t\t},\n\t\tgetSpec: function(fieldName) {\n\t\t\treturn this.metadata.fields[fieldName];\n\t\t},\n\t\t_selectAlias_handler: function(jEv) {\n\t\t\tvar indices = (jEv.target.selectedIndex === 0) ? [] : this.metadata.getIndices($(jEv.target).val());\n\t\t\t$(\".uiQueryFilter-index\").each(function(i, el) {\n\t\t\t\tvar jEl = $(el);\n\t\t\t\tif(indices.contains(jEl.text()) !== jEl.hasClass(\"selected\")) {\n\t\t\t\t\tjEl.click();\n\t\t\t\t}\n\t\t\t});\n\t\t\tthis.requestUpdate(jEv);\n\t\t},\n\t\t_selectIndex_handler: function(jEv) {\n\t\t\tvar jEl = $(jEv.target).closest(\".uiQueryFilter-index\");\n\t\t\tjEl.toggleClass(\"selected\");\n\t\t\tvar selected = jEl.hasClass(\"selected\");\n\t\t\tthis.query.setIndex(jEl.text(), selected);\n\t\t\tif(selected) {\n\t\t\t\tvar types = this.metadata.getTypes(this.query.indices);\n\t\t\t\tthis.el.find(\"DIV.uiQueryFilter-type.selected\").each(function(n, el) {\n\t\t\t\t\tif(! types.contains($(el).text())) {\n\t\t\t\t\t\t$(el).click();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t\tthis.requestUpdate(jEv);\n\t\t},\n\t\t_selectType_handler: function(jEv) {\n\t\t\tvar jEl = $(jEv.target).closest(\".uiQueryFilter-type\");\n\t\t\tjEl.toggleClass(\"selected\");\n\t\t\tvar type = jEl.text(), selected = jEl.hasClass(\"selected\");\n\t\t\tthis.query.setType(type, selected);\n\t\t\tif(selected) {\n\t\t\t\tvar indices = this.metadata.types[type].indices;\n\t\t\t\t// es throws a 500 if searching an index for a type it does not contain - so we prevent that\n\t\t\t\tthis.el.find(\"DIV.uiQueryFilter-index.selected\").each(function(n, el) {\n\t\t\t\t\tif(! indices.contains($(el).text())) {\n\t\t\t\t\t\t$(el).click();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\t// es throws a 500 if you specify types from different indices with _all\n\t\t\t\tjEl.siblings(\".uiQueryFilter-type.selected\").forEach(function(el) {\n\t\t\t\t\tif(this.metadata.types[$(el).text()].indices.intersection(indices).length === 0) {\n\t\t\t\t\t\t$(el).click();\n\t\t\t\t\t}\n\t\t\t\t}, this);\n\t\t\t}\n\t\t\tthis.requestUpdate(jEv);\n\t\t},\n\t\t_openFilter_handler: function(section) {\n\t\t\tvar field_name = section.config.title;\n\t\t\tif(! section.loaded) {\n\t\t\t\tvar spec = this.getSpec(field_name);\n\t\t\t\tif(spec.core_type === \"string\") {\n\t\t\t\t\tsection.body.append(this._textFilter_template(spec));\n\t\t\t\t} else if(spec.core_type === \"date\") {\n\t\t\t\t\tsection.body.append(this._dateFilter_template(spec));\n\t\t\t\t\tsection.body.append(new ui.DateHistogram({ printEl: section.body.find(\"INPUT\"), cluster: this.cluster, query: this.query, spec: spec }));\n\t\t\t\t} else if(spec.core_type === \"number\") {\n\t\t\t\t\tsection.body.append(this._numericFilter_template(spec));\n\t\t\t\t} else if(spec.core_type === 'boolean') {\n\t\t\t\t\tsection.body.append(this._booleanFilter_template(spec));\n\t\t\t\t} else if (spec.core_type === 'multi_field') {\n\t\t\t\t\tsection.body.append(this._multiFieldFilter_template(section, spec));\n\t\t\t\t} \n\t\t\t\tsection.loaded = true;\n\t\t\t}\n\t\t\tsection.on(\"animComplete\", function(section) { section.body.find(\"INPUT\").focus(); });\n\t\t},\n\t\t_textFilterChange_handler: function(jEv) {\n\t\t\tvar jEl = $(jEv.target).closest(\"INPUT\");\n\t\t\tvar val = jEl.val();\n\t\t\tvar spec = jEl.data(\"spec\");\n\t\t\tvar uqids = jEl.data(\"uqids\") || [];\n\t\t\tuqids.forEach(function(uqid) {\n\t\t\t\tuqid && this.query.removeClause(uqid);\n\t\t\t}, this);\n\t\t\tif(val.length) {\n\t\t\t\tif(jEl[0] === document.activeElement && jEl[0].selectionStart === jEl[0].selectionEnd) {\n\t\t\t\t\tval = val.replace(new RegExp(\"(.{\"+jEl[0].selectionStart+\"})\"), \"$&*\");\n\t\t\t\t}\n\t\t\t\tuqids = val.split(/\\s+/).map(function(term) {\n\t\t\t\t\t// Figure out the actual field name - needed for multi_field, because\n\t\t\t\t\t// querying for \"field.field\" will not work. Simply \"field\" must be used\n\t\t\t\t\t// if nothing is aliased.\n\t\t\t\t\tvar fieldNameParts = spec.field_name.split('.');\n\t\t\t\t\tvar part = fieldNameParts.length - 1;\n\t\t\t\t\tvar name = fieldNameParts[part];\n\t\t\t\t\twhile (part >= 1) {\n\t\t\t\t\t\tif (fieldNameParts[part] !== fieldNameParts[part - 1]) {\n\t\t\t\t\t\t\tname = fieldNameParts[part - 1] + \".\" + name;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tpart--;\n\t\t\t\t\t}\n\t\t\t\t\treturn term && this.query.addClause(term, name, \"wildcard\", \"must\");\n\t\t\t\t}, this);\n\t\t\t}\n\t\t\tjEl.data(\"uqids\", uqids);\n\t\t\tthis.requestUpdate(jEv);\n\t\t},\n\t\t_dateFilterChange_handler: function(jEv) {\n\t\t\tvar jEl = $(jEv.target).closest(\"INPUT\");\n\t\t\tvar val = jEl.val();\n\t\t\tvar spec = jEl.data(\"spec\");\n\t\t\tvar uqid = jEl.data(\"uqid\") || null;\n\t\t\tvar range = window.dateRangeParser.parse(val);\n\t\t\tvar lastRange = jEl.data(\"lastRange\");\n\t\t\tif(!range || (lastRange && lastRange.start === range.start && lastRange.end === range.end)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tuqid && this.query.removeClause(uqid);\n\t\t\tif((range.start && range.end) === null) {\n\t\t\t\tuqid = null;\n\t\t\t} else {\n\t\t\t\tvar value = {};\n\t\t\t\tif( range.start ) {\n\t\t\t\t\tvalue[\"gte\"] = range.start;\n\t\t\t\t}\n\t\t\t\tif( range.end ) {\n\t\t\t\t\tvalue[\"lte\"] = range.end;\n\t\t\t\t}\n\t\t\t\tuqid = this.query.addClause( value, spec.field_name, \"range\", \"must\");\n\t\t\t}\n\t\t\tjEl.data(\"lastRange\", range);\n\t\t\tjEl.siblings(\".uiQueryFilter-rangeHintFrom\")\n\t\t\t\t.text(i18n.text(\"QueryFilter.DateRangeHint.from\", range.start && new Date(range.start).toUTCString()));\n\t\t\tjEl.siblings(\".uiQueryFilter-rangeHintTo\")\n\t\t\t\t.text(i18n.text(\"QueryFilter.DateRangeHint.to\", range.end && new Date(range.end).toUTCString()));\n\t\t\tjEl.data(\"uqid\", uqid);\n\t\t\tthis.requestUpdate(jEv);\n\t\t},\n\t\t_numericFilterChange_handler: function(jEv) {\n\t\t\tvar jEl = $(jEv.target).closest(\"INPUT\");\n\t\t\tvar val = jEl.val();\n\t\t\tvar spec = jEl.data(\"spec\");\n\t\t\tvar uqid = jEl.data(\"uqid\") || null;\n\t\t\tvar lastRange = jEl.data(\"lastRange\");\n\t\t\tvar range = (function(val) {\n\t\t\t\tvar ops = val.split(/->|<>|</).map( function(v) { return parseInt(v.trim(), 10); });\n\t\t\t\tif(/<>/.test(val)) {\n\t\t\t\t\treturn { gte: (ops[0] - ops[1]), lte: (ops[0] + ops[1]) };\n\t\t\t\t} else if(/->|</.test(val)) {\n\t\t\t\t\treturn { gte: ops[0], lte: ops[1] };\n\t\t\t\t} else {\n\t\t\t\t\treturn { gte: ops[0], lte: ops[0] };\n\t\t\t\t}\n\t\t\t})(val || \"\");\n\t\t\tif(!range || (lastRange && lastRange.lte === range.lte && lastRange.gte === range.gte)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tjEl.data(\"lastRange\", range);\n\t\t\tuqid && this.query.removeClause(uqid);\n\t\t\tuqid = this.query.addClause( range, spec.field_name, \"range\", \"must\");\n\t\t\tjEl.data(\"uqid\", uqid);\n\t\t\tthis.requestUpdate(jEv);\n\t\t},\n\t\t_booleanFilterChange_handler: function( jEv ) {\n\t\t\tvar jEl = $(jEv.target).closest(\"SELECT\");\n\t\t\tvar val = jEl.val();\n\t\t\tvar spec = jEl.data(\"spec\");\n\t\t\tvar uqid = jEl.data(\"uqid\") || null;\n\t\t\tuqid && this.query.removeClause(uqid);\n\t\t\tif(val === \"true\" || val === \"false\") {\n\t\t\t\tjEl.data(\"uqid\", this.query.addClause(val, spec.field_name, \"term\", \"must\") );\n\t\t\t}\n\t\t\tthis.requestUpdate(jEv);\n\t\t},\n\t\t_main_template: function() {\n\t\t\treturn { tag: \"DIV\", id: this.id(), cls: \"uiQueryFilter\", children: [\n\t\t\t\tthis._aliasSelector_template(),\n\t\t\t\tthis._indexSelector_template(),\n\t\t\t\tthis._typesSelector_template(),\n\t\t\t\tthis._filters_template()\n\t\t\t] };\n\t\t},\n\t\t_aliasSelector_template: function() {\n\t\t\tvar aliases = Object.keys(this.metadata.aliases).sort();\n\t\t\taliases.unshift( i18n.text(\"QueryFilter.AllIndices\") );\n\t\t\treturn { tag: \"DIV\", cls: \"uiQueryFilter-section uiQueryFilter-aliases\", children: [\n\t\t\t\t{ tag: \"SELECT\", onChange: this._selectAlias_handler, children: aliases.map(ut.option_template) }\n\t\t\t] };\n\t\t},\n\t\t_indexSelector_template: function() {\n\t\t\tvar indices = Object.keys( this.metadata.indices ).sort();\n\t\t\treturn { tag: \"DIV\", cls: \"uiQueryFilter-section uiQueryFilter-indices\", children: [\n\t\t\t\t{ tag: \"HEADER\", text: i18n.text(\"QueryFilter-Header-Indices\") },\n\t\t\t\t{ tag: \"DIV\", onClick: this._selectIndex_handler, children: indices.map( function( name ) {\n\t\t\t\t\treturn { tag: \"DIV\", cls: \"uiQueryFilter-booble uiQueryFilter-index\", text: name };\n\t\t\t\t})}\n\t\t\t] };\n\t\t},\n\t\t_typesSelector_template: function() {\n\t\t\tvar types = Object.keys( this.metadata.types ).sort();\n\t\t\treturn { tag: \"DIV\", cls: \"uiQueryFilter-section uiQueryFilter-types\", children: [\n\t\t\t\t{ tag: \"HEADER\", text: i18n.text(\"QueryFilter-Header-Types\") },\n\t\t\t\t{ tag: \"DIV\", onClick: this._selectType_handler, children: types.map( function( name ) {\n\t\t\t\t\treturn { tag: \"DIV\", cls: \"uiQueryFilter-booble uiQueryFilter-type\", text: name };\n\t\t\t\t})}\n\t\t\t] };\n\t\t},\n\t\t_filters_template: function() {\n\t\t\tvar _metadataFields = this.metadata.fields;\n\t\t\tvar fields = Object.keys( _metadataFields ).sort()\n\t\t\t\t.filter(function(d) { return (_metadataFields[d].core_type !== undefined); });\n\t\t\treturn { tag: \"DIV\", cls: \"uiQueryFilter-section uiQueryFilter-filters\", children: [\n\t\t\t\t{ tag: \"HEADER\", text: i18n.text(\"QueryFilter-Header-Fields\") },\n\t\t\t\t{ tag: \"DIV\", children: fields.map( function(name ) {\n\t\t\t\t\treturn new app.ui.SidebarSection({\n\t\t\t\t\t\ttitle: name,\n\t\t\t\t\t\thelp: this.helpTypeMap[this.metadata.fields[ name ].type],\n\t\t\t\t\t\tonShow: this._openFilter_handler\n\t\t\t\t\t});\n\t\t\t\t}, this ) }\n\t\t\t] };\n\t\t},\n\t\t_textFilter_template: function(spec) {\n\t\t\treturn { tag: \"INPUT\", data: { spec: spec }, onKeyup: this._textFilterChange_handler };\n\t\t},\n\t\t_dateFilter_template: function(spec) {\n\t\t\treturn { tag: \"DIV\", children: [\n\t\t\t\t{ tag: \"INPUT\", data: { spec: spec }, onKeyup: this._dateFilterChange_handler },\n\t\t\t\t{ tag: \"PRE\", cls: \"uiQueryFilter-rangeHintFrom\", text: i18n.text(\"QueryFilter.DateRangeHint.from\", \"\")},\n\t\t\t\t{ tag: \"PRE\", cls: \"uiQueryFilter-rangeHintTo\", text: i18n.text(\"QueryFilter.DateRangeHint.to\", \"\") }\n\t\t\t]};\n\t\t},\n\t\t_numericFilter_template: function(spec) {\n\t\t\treturn { tag: \"INPUT\", data: { spec: spec }, onKeyup: this._numericFilterChange_handler };\n\t\t},\n\t\t_booleanFilter_template: function(spec) {\n\t\t\treturn { tag: \"SELECT\", data: { spec: spec }, onChange: this._booleanFilterChange_handler,\n\t\t\t\tchildren: [ i18n.text(\"QueryFilter.AnyValue\"), \"true\", \"false\" ].map( function( val ) {\n\t\t\t\t\treturn { tag: \"OPTION\", value: val, text: val };\n\t\t\t\t})\n\t\t\t};\n\t\t},\n\t\t_multiFieldFilter_template: function(section, spec) {\n\t\t\treturn {\n\t\t\t\ttag : \"DIV\", cls : \"uiQueryFilter-subMultiFields\", children : acx.eachMap(spec.fields, function(name, data) {\n\t\t\t\t\tif (name === spec.field_name) {\n\t\t\t\t\t\tsection.config.title = spec.field_name + \".\" + name;\n\t\t\t\t\t\treturn this._openFilter_handler(section);\n\t\t\t\t\t}\n\t\t\t\t\treturn new app.ui.SidebarSection({\n\t\t\t\t\t\ttitle : data.field_name, help : this.helpTypeMap[data.type], onShow : this._openFilter_handler\n\t\t\t\t\t});\n\t\t\t\t}, this)\n\t\t\t};\n\t\t}\t\n\t});\n\n})( this.jQuery, this.app, this.i18n );\n\n(function( app ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.Page = ui.AbstractWidget.extend({\n\t\tshow: function() {\n\t\t\tthis.el.show();\n\t\t},\n\t\thide: function() {\n\t\t\tthis.el.hide();\n\t\t}\n\t});\n\n})( this.app );\n(function( $, app, i18n ){\n\n\tvar ui = app.ns(\"ui\");\n\tvar data = app.ns(\"data\");\n\n\tui.Browser = ui.Page.extend({\n\t\tdefaults: {\n\t\t\tcluster: null  // (required) instanceof app.services.Cluster\n\t\t},\n\t\tinit: function() {\n\t\t\tthis._super();\n\t\t\tthis.cluster = this.config.cluster;\n\t\t\tthis.query = new app.data.Query( { cluster: this.cluster } );\n\t\t\tthis._refreshButton = new ui.Button({\n\t\t\t\tlabel: i18n.text(\"General.RefreshResults\"),\n\t\t\t\tonclick: function( btn ) {\n\t\t\t\t\tthis.query.query();\n\t\t\t\t}.bind(this)\n\t\t\t});\n\t\t\tthis.el = $(this._main_template());\n\t\t\tnew data.MetaDataFactory({\n\t\t\t\tcluster: this.cluster,\n\t\t\t\tonReady: function(metadata) {\n\t\t\t\t\tthis.metadata = metadata;\n\t\t\t\t\tthis.store = new data.QueryDataSourceInterface( { metadata: metadata, query: this.query } );\n\t\t\t\t\tthis.queryFilter = new ui.QueryFilter({ metadata: metadata, query: this.query });\n\t\t\t\t\tthis.queryFilter.attach(this.el.find(\"> .uiBrowser-filter\") );\n\t\t\t\t\tthis.resultTable = new ui.ResultTable( {\n\t\t\t\t\t\tonHeaderClick: this._changeSort_handler,\n\t\t\t\t\t\tstore: this.store\n\t\t\t\t\t} );\n\t\t\t\t\tthis.resultTable.attach( this.el.find(\"> .uiBrowser-table\") );\n\t\t\t\t\tthis.updateResults();\n\t\t\t\t}.bind(this)\n\t\t\t});\n\t\t},\n\t\tupdateResults: function() {\n\t\t\tthis.query.query();\n\t\t},\n\t\t_changeSort_handler: function(table, wEv) {\n\t\t\tthis.query.setSort(wEv.column, wEv.dir === \"desc\");\n\t\t\tthis.query.setPage(1);\n\t\t\tthis.query.query();\n\t\t},\n\t\t_main_template: function() {\n\t\t\treturn { tag: \"DIV\", cls: \"uiBrowser\", children: [\n\t\t\t\tnew ui.Toolbar({\n\t\t\t\t\tlabel: i18n.text(\"Browser.Title\"),\n\t\t\t\t\tleft: [ ],\n\t\t\t\t\tright: [ this._refreshButton ]\n\t\t\t\t}),\n\t\t\t\t{ tag: \"DIV\", cls: \"uiBrowser-filter\" },\n\t\t\t\t{ tag: \"DIV\", cls: \"uiBrowser-table\" }\n\t\t\t] };\n\t\t}\n\t});\n\n})( this.jQuery, this.app, this.i18n );\n\n(function( $, app, i18n, raphael ) {\n\n\tvar ui = app.ns(\"ui\");\n\tvar ut = app.ns(\"ut\");\n\tvar services = app.ns(\"services\");\n\n\tui.AnyRequest = ui.Page.extend({\n\t\tdefaults: {\n\t\t\tcluster: null,       // (required) instanceof app.services.Cluster\n\t\t\tpath: \"_search\",     // default uri to send a request to\n\t\t\tquery: { query: { match_all: { }}},\n\t\t\ttransform: \"  return root;\" // default transformer function (does nothing)\n\t\t},\n\t\tinit: function(parent) {\n\t\t\tthis._super();\n\t\t\tthis.prefs = services.Preferences.instance();\n\t\t\tthis.history = this.prefs.get(\"anyRequest-history\") || [ { type: \"POST\", path: this.config.path, query : JSON.stringify(this.config.query), transform: this.config.transform } ];\n\t\t\tthis.el = $.joey(this._main_template());\n\t\t\tthis.base_uriEl = this.el.find(\"INPUT[name=base_uri]\");\n\t\t\tthis.pathEl = this.el.find(\"INPUT[name=path]\");\n\t\t\tthis.typeEl = this.el.find(\"SELECT[name=method]\");\n\t\t\tthis.dataEl = this.el.find(\"TEXTAREA[name=body]\");\n\t\t\tthis.prettyEl = this.el.find(\"INPUT[name=pretty]\");\n\t\t\tthis.transformEl = this.el.find(\"TEXTAREA[name=transform]\");\n\t\t\tthis.asGraphEl = this.el.find(\"INPUT[name=asGraph]\");\n\t\t\tthis.asTableEl = this.el.find(\"INPUT[name=asTable]\");\n\t\t\tthis.asJsonEl = this.el.find(\"INPUT[name=asJson]\");\n\t\t\tthis.cronEl = this.el.find(\"SELECT[name=cron]\");\n\t\t\tthis.outEl = this.el.find(\"DIV.uiAnyRequest-out\");\n\t\t\tthis.errEl = this.el.find(\"DIV.uiAnyRequest-jsonErr\");\n\t\t\tthis.typeEl.val(\"GET\");\n\t\t\tthis.attach(parent);\n\t\t\tthis.setHistoryItem(this.history[this.history.length - 1]);\n\t\t},\n\t\tsetHistoryItem: function(item) {\n\t\t\tthis.pathEl.val(item.path);\n\t\t\tthis.typeEl.val(item.type);\n\t\t\tthis.dataEl.val(item.query);\n\t\t\tthis.transformEl.val(item.transform);\n\t\t},\n\t\t_request_handler: function( ev ) {\n\t\t\tif(! this._validateJson_handler()) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tvar path = this.pathEl.val(),\n\t\t\t\t\ttype = this.typeEl.val(),\n\t\t\t\t\tquery = JSON.stringify(JSON.parse(this.dataEl.val())),\n\t\t\t\t\ttransform = this.transformEl.val(),\n\t\t\t\t\tbase_uri = this.base_uriEl.val();\n\t\t\tif( ev ) { // if the user click request\n\t\t\t\tif(this.timer) {\n\t\t\t\t\twindow.clearTimeout(this.timer); // stop any cron jobs\n\t\t\t\t}\n\t\t\t\tdelete this.prevData; // remove data from previous cron runs\n\t\t\t\tthis.outEl.text(i18n.text(\"AnyRequest.Requesting\"));\n\t\t\t\tif( ! /\\/$/.test( base_uri )) {\n\t\t\t\t\tbase_uri += \"/\";\n\t\t\t\t\tthis.base_uriEl.val( base_uri );\n\t\t\t\t}\n\t\t\t\tfor(var i = 0; i < this.history.length; i++) {\n\t\t\t\t\tif(this.history[i].path === path &&\n\t\t\t\t\t\tthis.history[i].type === type &&\n\t\t\t\t\t\tthis.history[i].query === query &&\n\t\t\t\t\t\tthis.history[i].transform === transform) {\n\t\t\t\t\t\tthis.history.splice(i, 1);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthis.history.push({\n\t\t\t\t\tpath: path,\n\t\t\t\t\ttype: type,\n\t\t\t\t\tquery: query,\n\t\t\t\t\ttransform: transform\n\t\t\t\t});\n\t\t\t\tthis.history.slice(250); // make sure history does not get too large\n\t\t\t\tthis.prefs.set( \"anyRequest-history\", this.history );\n\t\t\t\tthis.el.find(\"UL.uiAnyRequest-history\")\n\t\t\t\t\t.empty()\n\t\t\t\t\t.append($( { tag: \"UL\", children: this.history.map(this._historyItem_template, this) }).children())\n\t\t\t\t\t.children().find(\":last-child\").each(function(i, j) { j.scrollIntoView(false); }).end()\n\t\t\t\t\t.scrollLeft(0);\n\t\t\t}\n\t\t\tif (type === 'GET') { query = null; }\n\t\t\tthis.config.cluster.request({\n\t\t\t\turl: base_uri + path,\n\t\t\t\ttype: type,\n\t\t\t\tdata: query,\n\t\t\t\tsuccess: this._responseWriter_handler,\n\t\t\t\terror: this._responseError_handler\n\t\t\t});\n\t\t},\n\t\t_responseError_handler: function (response) {\n\t\t\tvar obj;\n\t\t\ttry {\n\t\t\t\tobj = JSON.parse(response.responseText);\n\t\t\t\tif (obj) {\n\t\t\t\t\tthis._responseWriter_handler(obj);\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t}\n\t\t},\n\t\t_responseWriter_handler: function(data) {\n\t\t\tthis.outEl.empty();\n\t\t\ttry {\n\t\t\t\tdata = (new Function(\"root\", \"prev\", this.transformEl.val()))(data, this.prevData)\n\t\t\t} catch(e) {\n\t\t\t\tthis.errEl.text(e.message);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif(this.asGraphEl.attr(\"checked\")) {\n\t\t\t\tvar w = this.outEl.width();\n\t\t\t\traphael(this.outEl[0], w - 10, 300)\n\t\t\t\t\t.g.barchart(10, 10, w - 20, 280, [data]);\n\t\t\t}\n\t\t\tif(this.asTableEl.attr(\"checked\")) {\n\t\t\t\ttry {\n\t\t\t\t\tvar store = new app.data.ResultDataSourceInterface();\n\t\t\t\t\tthis.outEl.append(new app.ui.ResultTable({\n\t\t\t\t\t\twidth: this.outEl.width() - 23,\n\t\t\t\t\t\tstore: store\n\t\t\t\t\t} ) );\n\t\t\t\t\tstore.results(data);\n\t\t\t\t} catch(e) {\n\t\t\t\t\tthis.errEl.text(\"Results Table Failed: \" + e.message);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(this.asJsonEl.attr(\"checked\")) {\n\t\t\t\tthis.outEl.append(new ui.JsonPretty({ obj: data }));\n\t\t\t}\n\t\t\tif(this.cronEl.val() > 0) {\n\t\t\t\tthis.timer = window.setTimeout(function(){\n\t\t\t\t\tthis._request_handler();\n\t\t\t\t}.bind(this), this.cronEl.val());\n\t\t\t}\n\t\t\tthis.prevData = data;\n\t\t},\n\t\t_validateJson_handler: function( ev ) {\n\t\t\t/* if the textarea is empty, we replace its value by an empty JSON object : \"{}\" and the request goes on as usual */\n\t\t\tvar jsonData = this.dataEl.val().trim();\n\t\t\tvar j;\n\t\t\tif(jsonData === \"\") {\n\t\t\t\tjsonData = \"{}\";\n\t\t\t\tthis.dataEl.val( jsonData );\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tj = JSON.parse(jsonData);\n\t\t\t} catch(e) {\n\t\t\t\tthis.errEl.text(e.message);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tthis.errEl.text(\"\");\n\t\t\tif(this.prettyEl.attr(\"checked\")) {\n\t\t\t\tthis.dataEl.val(JSON.stringify(j, null, \"  \"));\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\t\t_historyClick_handler: function( ev ) {\n\t\t\tvar item = $( ev.target ).closest( \"LI\" ).data( \"item\" );\n\t\t\tthis.setHistoryItem( item );\n\t\t},\n\t\t_main_template: function() {\n\t\t\treturn { tag: \"DIV\", cls: \"anyRequest\", children: [\n\t\t\t\t{ tag: \"DIV\", cls: \"uiAnyRequest-request\", children: [\n\t\t\t\t\tnew app.ui.SidebarSection({\n\t\t\t\t\t\topen: false,\n\t\t\t\t\t\ttitle: i18n.text(\"AnyRequest.History\"),\n\t\t\t\t\t\tbody: { tag: \"UL\", onclick: this._historyClick_handler, cls: \"uiAnyRequest-history\", children: this.history.map(this._historyItem_template, this)\t}\n\t\t\t\t\t}),\n\t\t\t\t\tnew app.ui.SidebarSection({\n\t\t\t\t\t\topen: true,\n\t\t\t\t\t\ttitle: i18n.text(\"AnyRequest.Query\"),\n\t\t\t\t\t\tbody: { tag: \"DIV\", children: [\n\t\t\t\t\t\t\t{ tag: \"INPUT\", type: \"text\", name: \"base_uri\", value: this.config.cluster.config.base_uri },\n\t\t\t\t\t\t\t{ tag: \"BR\" },\n\t\t\t\t\t\t\t{ tag: \"INPUT\", type: \"text\", name: \"path\", value: this.config.path },\n\t\t\t\t\t\t\t{ tag: \"SELECT\", name: \"method\", children: [\"POST\", \"GET\", \"PUT\", \"HEAD\", \"DELETE\"].map(ut.option_template) },\n\t\t\t\t\t\t\t{ tag: \"TEXTAREA\", name: \"body\", rows: 20, text: JSON.stringify(this.config.query) },\n\t\t\t\t\t\t\t{ tag: \"BUTTON\", css: { cssFloat: \"right\" }, type: \"button\", children: [ { tag: \"B\", text: i18n.text(\"AnyRequest.Request\") } ], onclick: this._request_handler },\n\t\t\t\t\t\t\t{ tag: \"BUTTON\", type: \"button\", text: i18n.text(\"AnyRequest.ValidateJSON\"), onclick: this._validateJson_handler },\n\t\t\t\t\t\t\t{ tag: \"LABEL\", children: [ { tag: \"INPUT\", type: \"checkbox\", name: \"pretty\" }, i18n.text(\"AnyRequest.Pretty\") ] },\n\t\t\t\t\t\t\t{ tag: \"DIV\", cls: \"uiAnyRequest-jsonErr\" }\n\t\t\t\t\t\t]}\n\t\t\t\t\t}),\n\t\t\t\t\tnew app.ui.SidebarSection({\n\t\t\t\t\t\ttitle: i18n.text(\"AnyRequest.Transformer\"),\n\t\t\t\t\t\thelp: \"AnyRequest.TransformerHelp\",\n\t\t\t\t\t\tbody: { tag: \"DIV\", children: [\n\t\t\t\t\t\t\t{ tag: \"CODE\", text: \"function(root, prev) {\" },\n\t\t\t\t\t\t\t{ tag: \"BR\" },\n\t\t\t\t\t\t\t{ tag: \"TEXTAREA\", name: \"transform\", rows: 5, text: this.config.transform },\n\t\t\t\t\t\t\t{ tag: \"BR\" },\n\t\t\t\t\t\t\t{ tag: \"CODE\", text: \"}\" }\n\t\t\t\t\t\t] }\n\t\t\t\t\t}),\n\t\t\t\t\tnew app.ui.SidebarSection({\n\t\t\t\t\t\ttitle: i18n.text(\"AnyRequest.RepeatRequest\"),\n\t\t\t\t\t\tbody: { tag: \"DIV\", children: [\n\t\t\t\t\t\t\ti18n.text(\"AnyRequest.RepeatRequestSelect\"), \" \",\n\t\t\t\t\t\t\t{ tag: \"SELECT\", name: \"cron\", children: [\n\t\t\t\t\t\t\t\t{ value: 0, text: \"do not repeat\" },\n\t\t\t\t\t\t\t\t{ value: 1000, text: \"second\" },\n\t\t\t\t\t\t\t\t{ value: 1000 * 2, text: \"2 seconds\" },\n\t\t\t\t\t\t\t\t{ value: 1000 * 5, text: \"5 seconds\" },\n\t\t\t\t\t\t\t\t{ value: 1000 * 20, text: \"20 seconds\" },\n\t\t\t\t\t\t\t\t{ value: 1000 * 60, text: \"minute\" },\n\t\t\t\t\t\t\t\t{ value: 1000 * 60 * 10, text: \"10 minutes\" },\n\t\t\t\t\t\t\t\t{ value: 1000 * 60 * 60, text: \"hour\" }\n\t\t\t\t\t\t\t].map(function(op) { return $.extend({ tag: \"OPTION\"}, op); }) }\n\t\t\t\t\t\t] }\n\t\t\t\t\t}),\n\t\t\t\t\tnew app.ui.SidebarSection({\n\t\t\t\t\t\ttitle: i18n.text(\"AnyRequest.DisplayOptions\"),\n\t\t\t\t\t\thelp: \"AnyRequest.DisplayOptionsHelp\",\n\t\t\t\t\t\tbody: { tag: \"DIV\", children: [\n\t\t\t\t\t\t\t{ tag: \"LABEL\", children: [ { tag: \"INPUT\", type: \"checkbox\", checked: true, name: \"asJson\" }, i18n.text(\"AnyRequest.AsJson\") ] },\n\t\t\t\t\t\t\t{ tag: \"BR\" },\n\t\t\t\t\t\t\t{ tag: \"LABEL\", children: [ { tag: \"INPUT\", type: \"checkbox\", name: \"asGraph\" }, i18n.text(\"AnyRequest.AsGraph\") ] },\n\t\t\t\t\t\t\t{ tag: \"BR\" },\n\t\t\t\t\t\t\t{ tag: \"LABEL\", children: [ { tag: \"INPUT\", type: \"checkbox\", name: \"asTable\" }, i18n.text(\"AnyRequest.AsTable\") ] }\n\t\t\t\t\t\t] }\n\t\t\t\t\t})\n\t\t\t\t] },\n\t\t\t\t{ tag: \"DIV\", cls: \"uiAnyRequest-out\" }\n\t\t\t] };\n\t\t},\n\t\t_historyItem_template: function(item) {\n\t\t\treturn { tag: \"LI\", cls: \"booble\", data: { item: item }, children: [\n\t\t\t\t{ tag: \"SPAN\", text: item.path },\n\t\t\t\t\" \",\n\t\t\t\t{ tag: \"EM\", text: item.query },\n\t\t\t\t\" \",\n\t\t\t\t{ tag: \"SPAN\", text: item.transform }\n\t\t\t] };\n\t\t}\n\t});\n\t\n})( this.jQuery, this.app, this.i18n, this.Raphael );\n\n(function( app, i18n, joey ) {\n\n\tvar ui = app.ns(\"ui\");\n\tvar ut = app.ns(\"ut\");\n\n\tui.NodesView = ui.AbstractWidget.extend({\n\t\tdefaults: {\n\t\t\tinteractive: true,\n\t\t\taliasRenderer: \"list\",\n\t\t\tscaleReplicas: 1,\n\t\t\tcluster: null,\n\t\t\tdata: null\n\t\t},\n\t\tinit: function() {\n\t\t\tthis._super();\n\t\t\tthis.interactive = this.config.interactive;\n\t\t\tthis.cluster = this.config.cluster;\n\t\t\tthis._aliasRenderFunction = {\n\t\t\t\t\"none\": this._aliasRender_template_none,\n\t\t\t\t\"list\": this._aliasRender_template_list,\n\t\t\t\t\"full\": this._aliasRender_template_full\n\t\t\t}[ this.config.aliasRenderer ];\n\t\t\tthis._styleSheetEl = joey({ tag: \"STYLE\", text: \".uiNodesView-nullReplica, .uiNodesView-replica { zoom: \" + this.config.scaleReplicas + \" }\" });\n\t\t\tthis.el = $( this._main_template( this.config.data.cluster, this.config.data.indices ) );\n\t\t},\n\n\t\t_newAliasAction_handler: function( index ) {\n\t\t\tvar fields = new app.ux.FieldCollection({\n\t\t\t\tfields: [\n\t\t\t\t\tnew ui.TextField({ label: i18n.text(\"AliasForm.AliasName\"), name: \"alias\", require: true })\n\t\t\t\t]\n\t\t\t});\n\t\t\tvar dialog = new ui.DialogPanel({\n\t\t\t\ttitle: i18n.text(\"AliasForm.NewAliasForIndexName\", index.name),\n\t\t\t\tbody: new ui.PanelForm({ fields: fields }),\n\t\t\t\tonCommit: function(panel, args) {\n\t\t\t\t\tif(fields.validate()) {\n\t\t\t\t\t\tvar data = fields.getData();\n\t\t\t\t\t\tvar command = {\n\t\t\t\t\t\t\t\"actions\" : [\n\t\t\t\t\t\t\t\t{ \"add\" : { \"index\" : index.name, \"alias\" : data[\"alias\"] } }\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t};\n\t\t\t\t\t\tthis.config.cluster.post('_aliases', JSON.stringify(command), function(d) {\n\t\t\t\t\t\t\tdialog.close();\n\t\t\t\t\t\t\talert(JSON.stringify(d));\n\t\t\t\t\t\t\tthis.fire(\"redraw\");\n\t\t\t\t\t\t}.bind(this) );\n\t\t\t\t\t}\n\t\t\t\t}.bind(this)\n\t\t\t}).open();\n\t\t},\n\t\t_postIndexAction_handler: function(action, index, redraw) {\n\t\t\tthis.cluster.post(encodeURIComponent( index.name ) + \"/\" + encodeURIComponent( action ), null, function(r) {\n\t\t\t\talert(JSON.stringify(r));\n\t\t\t\tredraw && this.fire(\"redraw\");\n\t\t\t}.bind(this));\n\t\t},\n\t\t_optimizeIndex_handler: function(index) {\n\t\t\tvar fields = new app.ux.FieldCollection({\n\t\t\t\tfields: [\n\t\t\t\t\tnew ui.TextField({ label: i18n.text(\"OptimizeForm.MaxSegments\"), name: \"max_num_segments\", value: \"1\", require: true }),\n\t\t\t\t\tnew ui.CheckField({ label: i18n.text(\"OptimizeForm.ExpungeDeletes\"), name: \"only_expunge_deletes\", value: false }),\n\t\t\t\t\tnew ui.CheckField({ label: i18n.text(\"OptimizeForm.FlushAfter\"), name: \"flush\", value: true }),\n\t\t\t\t\tnew ui.CheckField({ label: i18n.text(\"OptimizeForm.WaitForMerge\"), name: \"wait_for_merge\", value: false })\n\t\t\t\t]\n\t\t\t});\n\t\t\tvar dialog = new ui.DialogPanel({\n\t\t\t\ttitle: i18n.text(\"OptimizeForm.OptimizeIndex\", index.name),\n\t\t\t\tbody: new ui.PanelForm({ fields: fields }),\n\t\t\t\tonCommit: function( panel, args ) {\n\t\t\t\t\tif(fields.validate()) {\n\t\t\t\t\t\tthis.cluster.post(encodeURIComponent( index.name ) + \"/_optimize\", fields.getData(), function(r) {\n\t\t\t\t\t\t\talert(JSON.stringify(r));\n\t\t\t\t\t\t});\n\t\t\t\t\t\tdialog.close();\n\t\t\t\t\t}\n\t\t\t\t}.bind(this)\n\t\t\t}).open();\n\t\t},\n\t\t_forceMergeIndex_handler: function(index) {\n                        var fields = new app.ux.FieldCollection({\n                                fields: [\n                                        new ui.TextField({ label: i18n.text(\"ForceMergeForm.MaxSegments\"), name: \"max_num_segments\", value: \"1\", require: true }),\n                                        new ui.CheckField({ label: i18n.text(\"ForceMergeForm.ExpungeDeletes\"), name: \"only_expunge_deletes\", value: false }),\n                                        new ui.CheckField({ label: i18n.text(\"ForceMergeForm.FlushAfter\"), name: \"flush\", value: true })\n                                ]\n                        });\n                        var dialog = new ui.DialogPanel({\n                                title: i18n.text(\"ForceMergeForm.ForceMergeIndex\", index.name),\n                                body: new ui.PanelForm({ fields: fields }),\n                                onCommit: function( panel, args ) {\n                                        if(fields.validate()) {\n\n                                                this.cluster.post(encodeURIComponent( index.name ) + \"/_forcemerge?\"+jQuery.param(fields.getData()), null, function(r) {\n                                                        alert(JSON.stringify(r));\n                                                });\n                                                dialog.close();\n                                        }\n                                }.bind(this)\n                        }).open();\n\t\t},\n\t\t_testAnalyser_handler: function(index) {\n\t\t\tif(this.cluster._version_parts[0] <= 5) {\n\t\t\t\tthis.cluster.get(encodeURIComponent( index.name ) + \"/_analyze?text=\" + encodeURIComponent( prompt( i18n.text(\"IndexCommand.TextToAnalyze\") ) ), function(r) {\n\t\t\t\t\tnew ui.JsonPanel({ json: r, title: \"\" });\n\t\t\t\t}); \n\t\t\t} else {\n\t\t\t\tvar command = {\n\t\t\t\t\t\"analyzer\" : prompt( i18n.text(\"IndexCommand.AnalyzerToUse\") ),\n\t\t\t\t\t\"text\": prompt( i18n.text(\"IndexCommand.TextToAnalyze\") )\n\t\t\t\t};\n\t\t\t\tthis.cluster.post(encodeURIComponent(index.name) + \"/_analyze\", JSON.stringify(command), function(r) {\n\t\t\t\t\tnew ui.JsonPanel({ json: r, title: \"\" });\n\t\t\t\t});\n\t\t\t}\t\t\n\t\t},\n\t\t_deleteIndexAction_handler: function(index) {\n\t\t\tif( prompt( i18n.text(\"AliasForm.DeleteAliasMessage\", i18n.text(\"Command.DELETE\"), index.name ) ) === i18n.text(\"Command.DELETE\") ) {\n\t\t\t\tthis.cluster[\"delete\"](encodeURIComponent( index.name ), null, function(r) {\n\t\t\t\t\talert(JSON.stringify(r));\n\t\t\t\t\tthis.fire(\"redraw\");\n\t\t\t\t}.bind(this) );\n\t\t\t}\n\t\t},\n\t\t_shutdownNode_handler: function(node) {\n\t\t\tif(prompt( i18n.text(\"IndexCommand.ShutdownMessage\", i18n.text(\"Command.SHUTDOWN\"), node.cluster.name ) ) === i18n.text(\"Command.SHUTDOWN\") ) {\n\t\t\t\tthis.cluster.post( \"_cluster/nodes/\" + encodeURIComponent( node.name ) + \"/_shutdown\", null, function(r) {\n\t\t\t\t\talert(JSON.stringify(r));\n\t\t\t\t\tthis.fire(\"redraw\");\n\t\t\t\t}.bind(this));\n\t\t\t}\n\t\t},\n\t\t_deleteAliasAction_handler: function( index, alias ) {\n\t\t\tif( confirm( i18n.text(\"Command.DeleteAliasMessage\" ) ) ) {\n\t\t\t\tvar command = {\n\t\t\t\t\t\"actions\" : [\n\t\t\t\t\t\t{ \"remove\" : { \"index\" : index.name, \"alias\" : alias.name } }\n\t\t\t\t\t]\n\t\t\t\t};\n\t\t\t\tthis.config.cluster.post('_aliases', JSON.stringify(command), function(d) {\n\t\t\t\t\talert(JSON.stringify(d));\n\t\t\t\t\tthis.fire(\"redraw\");\n\t\t\t\t}.bind(this) );\n\t\t\t}\n\t\t},\n\n\t\t_replica_template: function(replica) {\n\t\t\tvar r = replica.replica;\n\t\t\treturn { tag: \"DIV\",\n\t\t\t\tcls: \"uiNodesView-replica\" + (r.primary ? \" primary\" : \"\") + ( \" state-\" + r.state ),\n\t\t\t\ttext: r.shard.toString(),\n\t\t\t\tonclick: function() { new ui.JsonPanel({\n\t\t\t\t\tjson: replica.status || r,\n\t\t\t\t\ttitle: r.index + \"/\" + r.node + \" [\" + r.shard + \"]\" });\n\t\t\t\t}\n\t\t\t};\n\t\t},\n\t\t_routing_template: function(routing) {\n\t\t\tvar cell = { tag: \"TD\", cls: \"uiNodesView-routing\" + (routing.open ? \"\" : \" close\"), children: [] };\n\t\t\tfor(var i = 0; i < routing.replicas.length; i++) {\n\t\t\t\tif(i % routing.max_number_of_shards === 0 && i > 0) {\n\t\t\t\t\tcell.children.push({ tag: \"BR\" });\n\t\t\t\t}\n\t\t\t\tif( routing.replicas[i] ) {\n\t\t\t\t\tcell.children.push(this._replica_template(routing.replicas[i]));\n\t\t\t\t} else {\n\t\t\t\t\tcell.children.push( { tag: \"DIV\", cls: \"uiNodesView-nullReplica\" } );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn cell;\n\t\t},\n\t\t_nodeControls_template: function( node ) { return (\n\t\t\t{ tag: \"DIV\", cls: \"uiNodesView-controls\", children: [\n\t\t\t\tnew ui.MenuButton({\n\t\t\t\t\tlabel: i18n.text(\"NodeInfoMenu.Title\"),\n\t\t\t\t\tmenu: new ui.MenuPanel({\n\t\t\t\t\t\titems: [\n\t\t\t\t\t\t\t{ text: i18n.text(\"NodeInfoMenu.ClusterNodeInfo\"), onclick: function() { new ui.JsonPanel({ json: node.cluster, title: node.name });} },\n\t\t\t\t\t\t\t{ text: i18n.text(\"NodeInfoMenu.NodeStats\"), onclick: function() { new ui.JsonPanel({ json: node.stats, title: node.name });} }\n\t\t\t\t\t\t]\n\t\t\t\t\t})\n\t\t\t\t}),\n\t\t\t\tnew ui.MenuButton({\n\t\t\t\t\tlabel: i18n.text(\"NodeActionsMenu.Title\"),\n\t\t\t\t\tmenu: new ui.MenuPanel({\n\t\t\t\t\t\titems: [\n\t\t\t\t\t\t\t{ text: i18n.text(\"NodeActionsMenu.Shutdown\"), onclick: function() { this._shutdownNode_handler(node); }.bind(this) }\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_nodeIcon_template: function( node ) {\n\t\t\tvar icon, alt;\n\t\t\tif( node.name === \"Unassigned\" ) {\n\t\t\t\ticon = \"fa-exclamation-triangle\";\n\t\t\t\talt = i18n.text( \"NodeType.Unassigned\" );\n\t\t\t} else if( node.cluster.settings && \"tribe\" in node.cluster.settings) {\n\t\t\t\ticon = \"fa-sitemap\";\n\t\t\t\talt = i18n.text(\"NodeType.Tribe\" );\n\t\t\t} else {\n\t\t\t\ticon = \"fa-\" + (node.master_node ? \"star\" : \"circle\") + (node.data_node ? \"\" : \"-o\" );\n\t\t\t\talt = i18n.text( node.master_node ? ( node.data_node ? \"NodeType.Master\" : \"NodeType.Coord\" ) : ( node.data_node ? \"NodeType.Worker\" : \"NodeType.Client\" ) );\n\t\t\t}\n\t\t\treturn { tag: \"TD\", title: alt, cls: \"uiNodesView-icon\", children: [\n\t\t\t\t{ tag: \"SPAN\", cls: \"fa fa-2x \" + icon }\n\t\t\t] };\n\t\t},\n\t\t_node_template: function(node) {\n\t\t\treturn { tag: \"TR\", cls: \"uiNodesView-node\" + (node.master_node ? \" master\": \"\"), children: [\n\t\t\t\tthis._nodeIcon_template( node ),\n\t\t\t\t{ tag: \"TH\", children: node.name === \"Unassigned\" ? [\n\t\t\t\t\t{ tag: \"H3\", text: node.name }\n\t\t\t\t] : [\n\t\t\t\t\t{ tag: \"H3\", text: node.cluster.name },\n\t\t\t\t\t{ tag: \"DIV\", text: node.cluster.hostname },\n\t\t\t\t\tthis.interactive ? this._nodeControls_template( node ) : null\n\t\t\t\t] }\n\t\t\t].concat(node.routings.map(this._routing_template, this))};\n\t\t},\n\t\t_indexHeaderControls_template: function( index ) { return (\n\t\t\t{ tag: \"DIV\", cls: \"uiNodesView-controls\", children: [\n\t\t\t\tnew ui.MenuButton({\n\t\t\t\t\tlabel: i18n.text(\"IndexInfoMenu.Title\"),\n\t\t\t\t\tmenu: new ui.MenuPanel({\n\t\t\t\t\t\titems: [\n\t\t\t\t\t\t\t{ text: i18n.text(\"IndexInfoMenu.Status\"), onclick: function() { new ui.JsonPanel({ json: index.status, title: index.name }); } },\n\t\t\t\t\t\t\t{ text: i18n.text(\"IndexInfoMenu.Metadata\"), onclick: function() { new ui.JsonPanel({ json: index.metadata, title: index.name }); } }\n\t\t\t\t\t\t]\n\t\t\t\t\t})\n\t\t\t\t}),\n\t\t\t\tnew ui.MenuButton({\n\t\t\t\t\tlabel: i18n.text(\"IndexActionsMenu.Title\"),\n\t\t\t\t\tmenu: new ui.MenuPanel({\n\t\t\t\t\t\titems: [\n\t\t\t\t\t\t\t{ text: i18n.text(\"IndexActionsMenu.NewAlias\"), onclick: function() { this._newAliasAction_handler(index); }.bind(this) },\n\t\t\t\t\t\t\t{ text: i18n.text(\"IndexActionsMenu.Refresh\"), onclick: function() { this._postIndexAction_handler(\"_refresh\", index, false); }.bind(this) },\n\t\t\t\t\t\t\t{ text: i18n.text(\"IndexActionsMenu.Flush\"), onclick: function() { this._postIndexAction_handler(\"_flush\", index, false); }.bind(this) },\n\t\t\t\t\t\t\t{ text: this.cluster.versionAtLeast(\"5.0.0.\") ? i18n.text(\"IndexActionsMenu.ForceMerge\") : i18n.text(\"IndexActionsMenu.Optimize\"), onclick: this.cluster.versionAtLeast(\"5.0.0.\") ? function () { this._forceMergeIndex_handler(index); }.bind(this) : function () { this._optimizeIndex_handler(index); }.bind(this) },\n\t\t\t\t\t\t\t{ text: i18n.text(\"IndexActionsMenu.Snapshot\"), disabled: closed, onclick: function() { this._postIndexAction_handler(\"_gateway/snapshot\", index, false); }.bind(this) },\n\t\t\t\t\t\t\t{ text: i18n.text(\"IndexActionsMenu.Analyser\"), onclick: function() { this._testAnalyser_handler(index); }.bind(this) },\n\t\t\t\t\t\t\t{ text: (index.state === \"close\") ? i18n.text(\"IndexActionsMenu.Open\") : i18n.text(\"IndexActionsMenu.Close\"), onclick: function() { this._postIndexAction_handler((index.state === \"close\") ? \"_open\" : \"_close\", index, true); }.bind(this) },\n\t\t\t\t\t\t\t{ text: i18n.text(\"IndexActionsMenu.Delete\"), onclick: function() { this._deleteIndexAction_handler(index); }.bind(this) }\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_indexHeader_template: function( index ) {\n\t\t\tvar closed = index.state === \"close\";\n\t\t\tvar line1 = closed ? \"index: close\" : ( \"size: \" + (index.status && index.status.primaries && index.status.total ? ut.byteSize_template( index.status.primaries.store.size_in_bytes ) + \" (\" + ut.byteSize_template( index.status.total.store.size_in_bytes ) + \")\" : \"unknown\" ) );\n\t\t\tvar line2 = closed ? \"\\u00A0\" : ( \"docs: \" + (index.status && index.status.primaries && index.status.primaries.docs && index.status.total && index.status.total.docs ? index.status.primaries.docs.count.toLocaleString() + \" (\" + (index.status.total.docs.count + index.status.total.docs.deleted).toLocaleString() + \")\" : \"unknown\" ) );\n\t\t\treturn index.name ? { tag: \"TH\", cls: (closed ? \"close\" : \"\"), children: [\n\t\t\t\t{ tag: \"H3\", text: index.name },\n\t\t\t\t{ tag: \"DIV\", text: line1 },\n\t\t\t\t{ tag: \"DIV\", text: line2 },\n\t\t\t\tthis.interactive ? this._indexHeaderControls_template( index ) : null\n\t\t\t] } : [ { tag: \"TD\" }, { tag: \"TH\" } ];\n\t\t},\n\t\t_aliasRender_template_none: function( cluster, indices ) {\n\t\t\treturn null;\n\t\t},\n\t\t_aliasRender_template_list: function( cluster, indices ) {\n\t\t\treturn cluster.aliases.length && { tag: \"TBODY\", children: [\n\t\t\t\t{ tag: \"TR\", children: [\n\t\t\t\t\t{ tag: \"TD\" }\n\t\t\t\t].concat( indices.map( function( index ) {\n\t\t\t\t\treturn { tag: \"TD\", children: index.metadata && index.metadata.aliases.map( function( alias ) {\n\t\t\t\t\t\treturn { tag: \"LI\", text: alias };\n\t\t\t\t\t} ) };\n\t\t\t\t})) }\n\t\t\t] };\n\t\t},\n\t\t_aliasRender_template_full: function( cluster, indices ) {\n\t\t\treturn cluster.aliases.length && { tag: \"TBODY\", children: cluster.aliases.map( function(alias, row) {\n\t\t\t\treturn { tag: \"TR\", children: [ { tag: \"TD\" },{ tag: \"TD\" } ].concat(alias.indices.map(function(index, i) {\n\t\t\t\t\tif (index) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttag: \"TD\",\n\t\t\t\t\t\t\tcss: { background: \"#\" + \"9ce9c7fc9\".substr((row+6)%7,3) },\n\t\t\t\t\t\t\tcls: \"uiNodesView-hasAlias\" + ( alias.min === i ? \" min\" : \"\" ) + ( alias.max === i ? \" max\" : \"\" ),\n\t\t\t\t\t\t\ttext: alias.name,\n\t\t\t\t\t\t\tchildren: this.interactive ? [\n\t\t\t\t\t\t\t\t{\ttag: 'SPAN',\n\t\t\t\t\t\t\t\t\ttext: i18n.text(\"General.CloseGlyph\"),\n\t\t\t\t\t\t\t\t\tcls: 'uiNodesView-hasAlias-remove',\n\t\t\t\t\t\t\t\t\tonclick: this._deleteAliasAction_handler.bind( this, index, alias )\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]: null\n\t\t\t\t\t\t};\n\t\t\t\t\t}\telse {\n\t\t\t\t\t\treturn { tag: \"TD\" };\n\t\t\t\t\t}\n\t\t\t\t}, this ) ) };\n\t\t\t}, this )\t};\n\t\t},\n\t\t_main_template: function(cluster, indices) {\n\t\t\treturn { tag: \"TABLE\", cls: \"table uiNodesView\", children: [\n\t\t\t\tthis._styleSheetEl,\n\t\t\t\t{ tag: \"THEAD\", children: [ { tag: \"TR\", children: indices.map(this._indexHeader_template, this) } ] },\n\t\t\t\tthis._aliasRenderFunction( cluster, indices ),\n\t\t\t\t{ tag: \"TBODY\", children: cluster.nodes.map(this._node_template, this) }\n\t\t\t] };\n\t\t}\n\n\t});\n\n})( this.app, this.i18n, this.joey );\n\n(function( $, app, i18n ) {\n\n\tvar ui = app.ns(\"ui\");\n\tvar services = app.ns(\"services\");\n\n\t// ( master ) master = true, data = true \n\t// ( coordinator ) master = true, data = false\n\t// ( worker ) master = false, data = true;\n\t// ( client ) master = false, data = false;\n\t// http enabled ?\n\n\tfunction nodeSort_name(a, b) {\n\t\tif (!(a.cluster && b.cluster)) {\n\t\t\treturn 0;\n\t\t}\n\t\treturn a.cluster.name.toString().localeCompare( b.cluster.name.toString() );\n\t}\n\n\tfunction nodeSort_addr( a, b ) {\n\t\tif (!a.cluster.transport_address) {\n\t\t\treturn -1;\n\t\t}\n\t\tif (!b.cluster.transport_address) {\n\t\t\treturn 1;\n\t\t}\n\t\tif (!(a.cluster && b.cluster)) {\n\t\t\treturn 0;\n\t\t}\n\t\treturn a.cluster.transport_address.toString().localeCompare( b.cluster.transport_address.toString() );\n\t}\n\n\tfunction nodeSort_type( a, b ) {\n\t\tif (!(a.cluster && b.cluster)) {\n\t\t\treturn 0;\n\t\t}\n\t\tif( a.master_node ) {\n\t\t\treturn -1;\n\t\t} else if( b.master_node ) {\n\t\t\treturn 1;\n\t\t} else if( a.data_node && !b.data_node ) {\n\t\t\treturn -1;\n\t\t} else if( b.data_node && !a.data_node ) {\n\t\t\treturn 1;\n\t\t} else {\n\t\t\treturn a.cluster.name.toString().localeCompare( b.cluster.name.toString() );\n\t\t}\n\t}\n\n\tvar NODE_SORT_TYPES = {\n\t\t\"Sort.ByName\": nodeSort_name,\n\t\t\"Sort.ByAddress\": nodeSort_addr,\n\t\t\"Sort.ByType\": nodeSort_type\n\t};\n\n\tfunction nodeFilter_none( a ) {\n\t\treturn true;\n\t}\n\n\tfunction nodeFilter_clients( a ) {\n\t\treturn (a.master_node || a.data_node );\n\t}\n\n\n\tui.ClusterOverview = ui.Page.extend({\n\t\tdefaults: {\n\t\t\tcluster: null // (reqired) an instanceof app.services.Cluster\n\t\t},\n\t\tinit: function() {\n\t\t\tthis._super();\n\t\t\tthis.cluster = this.config.cluster;\n\t\t\tthis.prefs = services.Preferences.instance();\n\t\t\tthis._clusterState = this.config.clusterState;\n\t\t\tthis._clusterState.on(\"data\", this.draw_handler );\n\t\t\tthis._refreshButton = new ui.RefreshButton({\n\t\t\t\tonRefresh: this.refresh.bind(this),\n\t\t\t\tonChange: function( btn ) {\n\t\t\t\t\tif( btn.value === -1 ) {\n\t\t\t\t\t\tthis.draw_handler();\n\t\t\t\t\t}\n\t\t\t\t}.bind( this )\n\t\t\t});\n\t\t\tvar nodeSortPref = this.prefs.get(\"clusterOverview-nodeSort\") || Object.keys(NODE_SORT_TYPES)[0];\n\t\t\tthis._nodeSort = NODE_SORT_TYPES[ nodeSortPref ];\n\t\t\tthis._nodeSortMenu = new ui.MenuButton({\n\t\t\t\tlabel: i18n.text( \"Preference.SortCluster\" ),\n\t\t\t\tmenu: new ui.SelectMenuPanel({\n\t\t\t\t\tvalue: nodeSortPref,\n\t\t\t\t\titems: Object.keys( NODE_SORT_TYPES ).map( function( k ) {\n\t\t\t\t\t\treturn { text: i18n.text( k ), value: k };\n\t\t\t\t\t}),\n\t\t\t\t\tonSelect: function( panel, event ) {\n\t\t\t\t\t\tthis._nodeSort = NODE_SORT_TYPES[ event.value ];\n\t\t\t\t\t\tthis.prefs.set(\"clusterOverview-nodeSort\", event.value );\n\t\t\t\t\t\tthis.draw_handler();\n\t\t\t\t\t}.bind(this)\n\t\t\t\t})\n\t\t\t});\n\t\t\tthis._indicesSort = this.prefs.get( \"clusterOverview-indicesSort\") || \"desc\";\n\t\t\tthis._indicesSortMenu = new ui.MenuButton({\n\t\t\t\tlabel: i18n.text( \"Preference.SortIndices\" ),\n\t\t\t\tmenu: new ui.SelectMenuPanel({\n\t\t\t\t\tvalue: this._indicesSort,\n\t\t\t\t\titems: [\n\t\t\t\t\t\t{ value: \"desc\", text: i18n.text( \"SortIndices.Descending\" ) },\n\t\t\t\t\t\t{ value: \"asc\", text: i18n.text( \"SortIndices.Ascending\" ) } ],\n\t\t\t\t\tonSelect: function( panel, event ) {\n\t\t\t\t\t\tthis._indicesSort = event.value;\n\t\t\t\t\t\tthis.prefs.set( \"clusterOverview-indicesSort\", this._indicesSort );\n\t\t\t\t\t\tthis.draw_handler();\n\t\t\t\t\t}.bind(this)\n\t\t\t\t})\n\t\t\t});\n\t\t\tthis._aliasRenderer = this.prefs.get( \"clusterOverview-aliasRender\" ) || \"full\";\n\t\t\tthis._aliasMenu = new ui.MenuButton({\n\t\t\t\tlabel: i18n.text( \"Preference.ViewAliases\" ),\n\t\t\t\tmenu: new ui.SelectMenuPanel({\n\t\t\t\t\tvalue: this._aliasRenderer,\n\t\t\t\t\titems: [\n\t\t\t\t\t\t{ value: \"full\", text: i18n.text( \"ViewAliases.Grouped\" ) },\n\t\t\t\t\t\t{ value: \"list\", text: i18n.text( \"ViewAliases.List\" ) },\n\t\t\t\t\t\t{ value: \"none\", text: i18n.text( \"ViewAliases.None\" ) } ],\n\t\t\t\t\tonSelect: function( panel, event ) {\n\t\t\t\t\t\tthis._aliasRenderer = event.value;\n\t\t\t\t\t\tthis.prefs.set( \"clusterOverview-aliasRender\", this._aliasRenderer );\n\t\t\t\t\t\tthis.draw_handler();\n\t\t\t\t\t}.bind(this)\n\t\t\t\t})\n\t\t\t});\n\t\t\tthis._indexFilter = new ui.TextField({\n\t\t\t\tvalue: this.prefs.get(\"clusterOverview-indexFilter\"),\n\t\t\t\tplaceholder: i18n.text( \"Overview.IndexFilter\" ),\n\t\t\t\tonchange: function( indexFilter ) {\n\t\t\t\t\tthis.prefs.set(\"clusterOverview-indexFilter\", indexFilter.val() );\n\t\t\t\t\tthis.draw_handler();\n\t\t\t\t}.bind(this)\n\t\t\t});\n\t\t\tthis.el = $(this._main_template());\n\t\t\tthis.tablEl = this.el.find(\".uiClusterOverview-table\");\n\t\t\tthis.refresh();\n\t\t},\n\t\tremove: function() {\n\t\t\tthis._clusterState.removeObserver( \"data\", this.draw_handler );\n\t\t},\n\t\trefresh: function() {\n\t\t\tthis._refreshButton.disable();\n\t\t\tthis._clusterState.refresh();\n\t\t},\n\t\tdraw_handler: function() {\n\t\t\tvar data = this._clusterState;\n\t\t\tvar indexFilter;\n\t\t\ttry {\n\t\t\t\tvar indexFilterRe = new RegExp( this._indexFilter.val() );\n\t\t\t\tindexFilter = function(s) { return indexFilterRe.test(s); };\n\t\t\t} catch(e) {\n\t\t\t\tindexFilter = function() { return true; };\n\t\t\t}\n\t\t\tvar clusterState = data.clusterState;\n\t\t\tvar status = data.status;\n\t\t\tvar nodeStats = data.nodeStats;\n\t\t\tvar clusterNodes = data.clusterNodes;\n\t\t\tvar nodes = [];\n\t\t\tvar indices = [];\n\t\t\tvar cluster = {};\n\t\t\tvar nodeIndices = {};\n\t\t\tvar indexIndices = {}, indexIndicesIndex = 0;\n\t\t\tfunction newNode(n) {\n\t\t\t\treturn {\n\t\t\t\t\tname: n,\n\t\t\t\t\troutings: [],\n\t\t\t\t\tmaster_node: clusterState.master_node === n\n\t\t\t\t};\n\t\t\t}\n\t\t\tfunction newIndex(i) {\n\t\t\t\treturn {\n\t\t\t\t\tname: i,\n\t\t\t\t\treplicas: []\n\t\t\t\t};\n\t\t\t}\n\t\t\tfunction getIndexForNode(n) {\n\t\t\t\treturn nodeIndices[n] = (n in nodeIndices) ? nodeIndices[n] : nodes.push(newNode(n)) - 1;\n\t\t\t}\n\t\t\tfunction getIndexForIndex(routings, i) {\n\t\t\t\tvar index = indexIndices[i] = (i in indexIndices) ?\n\t\t\t\t\t\t(routings[indexIndices[i]] = routings[indexIndices[i]] || newIndex(i)) && indexIndices[i]\n\t\t\t\t\t\t: ( ( routings[indexIndicesIndex] = newIndex(i) )  && indexIndicesIndex++ );\n\t\t\t\tindices[index] = i;\n\t\t\t\treturn index;\n\t\t\t}\n\t\t\t$.each(clusterNodes.nodes, function(name, node) {\n\t\t\t\tgetIndexForNode(name);\n\t\t\t});\n\n\t\t\tvar indexNames = [];\n\t\t\t$.each(clusterState.routing_table.indices, function(name, index){\n\t\t\t\tindexNames.push(name);\n\t\t\t});\n\t\t\tindexNames.sort();\n\t\t\tif (this._indicesSort === \"desc\") indexNames.reverse();\n\t\t\tindexNames.filter( indexFilter ).forEach(function(name) {\n\t\t\t\tvar indexObject = clusterState.routing_table.indices[name];\n\t\t\t\t$.each(indexObject.shards, function(name, shard) {\n\t\t\t\t\tshard.forEach(function(replica){\n\t\t\t\t\t\tvar node = replica.node;\n\t\t\t\t\t\tif(node === null) { node = \"Unassigned\"; }\n\t\t\t\t\t\tvar index = replica.index;\n\t\t\t\t\t\tvar shard = replica.shard;\n\t\t\t\t\t\tvar routings = nodes[getIndexForNode(node)].routings;\n\t\t\t\t\t\tvar indexIndex = getIndexForIndex(routings, index);\n\t\t\t\t\t\tvar replicas = routings[indexIndex].replicas;\n\t\t\t\t\t\tif(node === \"Unassigned\" || !indexObject.shards[shard]) {\n\t\t\t\t\t\t\treplicas.push({ replica: replica });\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treplicas[shard] = {\n\t\t\t\t\t\t\t\treplica: replica,\n\t\t\t\t\t\t\t\tstatus: indexObject.shards[shard].filter(function(replica) {\n\t\t\t\t\t\t\t\t\treturn replica.node === node;\n\t\t\t\t\t\t\t\t})[0]\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\t\t\tindices = indices.map(function(index){\n\t\t\t\treturn {\n\t\t\t\t\tname: index,\n\t\t\t\t\tstate: \"open\",\n\t\t\t\t\tmetadata: clusterState.metadata.indices[index],\n\t\t\t\t\tstatus: status.indices[index]\n\t\t\t\t};\n\t\t\t}, this);\n\t\t\t$.each(clusterState.metadata.indices, function(name, index) {\n\t\t\t\tif(index.state === \"close\" && indexFilter( name )) {\n\t\t\t\t\tindices.push({\n\t\t\t\t\t\tname: name,\n\t\t\t\t\t\tstate: \"close\",\n\t\t\t\t\t\tmetadata: index,\n\t\t\t\t\t\tstatus: null\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\t\t\tnodes.forEach(function(node) {\n\t\t\t\tnode.stats = nodeStats.nodes[node.name];\n\t\t\t\tvar cluster = clusterNodes.nodes[node.name];\n\t\t\t\tnode.cluster = cluster || { name: \"<unknown>\" };\n\t\t\t\tnode.data_node = !( cluster && cluster.attributes && cluster.attributes.data === \"false\" );\n\t\t\t\tfor(var i = 0; i < indices.length; i++) {\n\t\t\t\t\tnode.routings[i] = node.routings[i] || { name: indices[i].name, replicas: [] };\n\t\t\t\t\tif (indices[i].metadata.settings) {\n\t\t\t\t\t\tnode.routings[i].max_number_of_shards = indices[i].metadata.settings[\"index.number_of_shards\"];\n\t\t\t\t\t}\n\t\t\t\t\tnode.routings[i].open = indices[i].state === \"open\";\n\t\t\t\t}\n\t\t\t});\n\t\t\tvar aliasesIndex = {};\n\t\t\tvar aliases = [];\n\t\t\tvar indexClone = indices.map(function() { return false; });\n\t\t\t$.each(clusterState.metadata.indices, function(name, index) {\n\t\t\t\tindex.aliases.forEach(function(alias) {\n\t\t\t\t\tvar aliasIndex = aliasesIndex[alias] = (alias in aliasesIndex) ? aliasesIndex[alias] : aliases.push( { name: alias, max: -1, min: 999, indices: [].concat(indexClone) }) - 1;\n\t\t\t\t\tvar indexIndex = indexIndices[name];\n\t\t\t\t\tvar aliasRow = aliases[aliasIndex];\n\t\t\t\t\taliasRow.min = Math.min(aliasRow.min, indexIndex);\n\t\t\t\t\taliasRow.max = Math.max(aliasRow.max, indexIndex);\n\t\t\t\t\taliasRow.indices[indexIndex] = indices[indexIndex];\n\t\t\t\t});\n\t\t\t});\n\t\t\tcluster.aliases = aliases;\n\t\t\tcluster.nodes = nodes\n\t\t\t\t.filter( nodeFilter_none )\n\t\t\t\t.sort( this._nodeSort );\n\t\t\tindices.unshift({ name: null });\n\t\t\tthis._drawNodesView( cluster, indices );\n\t\t\tthis._refreshButton.enable();\n\t\t},\n\t\t_drawNodesView: function( cluster, indices ) {\n\t\t\tthis._nodesView && this._nodesView.remove();\n\t\t\tthis._nodesView = new ui.NodesView({\n\t\t\t\tonRedraw: function() {\n\t\t\t\t\tthis.refresh();\n\t\t\t\t}.bind(this),\n\t\t\t\tinteractive: ( this._refreshButton.value === -1 ),\n\t\t\t\taliasRenderer: this._aliasRenderer,\n\t\t\t\tcluster: this.cluster,\n\t\t\t\tdata: {\n\t\t\t\t\tcluster: cluster,\n\t\t\t\t\tindices: indices\n\t\t\t\t}\n\t\t\t});\n\t\t\tthis._nodesView.attach( this.tablEl );\n\t\t},\n\t\t_main_template: function() {\n\t\t\treturn { tag: \"DIV\", id: this.id(), cls: \"uiClusterOverview\", children: [\n\t\t\t\tnew ui.Toolbar({\n\t\t\t\t\tlabel: i18n.text(\"Overview.PageTitle\"),\n\t\t\t\t\tleft: [\n\t\t\t\t\t\tthis._nodeSortMenu,\n\t\t\t\t\t\tthis._indicesSortMenu,\n\t\t\t\t\t\tthis._aliasMenu,\n\t\t\t\t\t\tthis._indexFilter\n\t\t\t\t\t],\n\t\t\t\t\tright: [\n\t\t\t\t\t\tthis._refreshButton\n\t\t\t\t\t]\n\t\t\t\t}),\n\t\t\t\t{ tag: \"DIV\", cls: \"uiClusterOverview-table\" }\n\t\t\t] };\n\t\t}\n\t});\n\n})( this.jQuery, this.app, this.i18n );\n\n(function( app, i18n, raphael ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.DateHistogram = ui.AbstractWidget.extend({\n\t\tdefaults: {\n\t\t\tprintEl: null, // (optional) if supplied, clicking on elements in the histogram changes the query\n\t\t\tcluster: null, // (required)\n\t\t\tquery: null,   // (required) the current query\n\t\t\tspec: null     // (required) // date field spec\n\t\t},\n\t\tinit: function() {\n\t\t\tthis._super();\n\t\t\tthis.el = $(this._main_template());\n\t\t\tthis.query = this.config.query.clone();\n\t\t\t// check if the index/types have changed and rebuild the histogram\n\t\t\tthis.config.query.on(\"results\", function(query) {\n\t\t\t\tif(this.queryChanged) {\n\t\t\t\t\tthis.buildHistogram(query);\n\t\t\t\t\tthis.queryChanged = false;\n\t\t\t\t}\n\t\t\t}.bind(this));\n\t\t\tthis.config.query.on(\"setIndex\", function(query, params) {\n\t\t\t\tthis.query.setIndex(params.index, params.add);\n\t\t\t\tthis.queryChanged = true;\n\t\t\t}.bind(this));\n\t\t\tthis.config.query.on(\"setType\", function(query, params) {\n\t\t\t\tthis.query.setType(params.type, params.add);\n\t\t\t\tthis.queryChanged = true;\n\t\t\t}.bind(this));\n\t\t\tthis.query.search.size = 0;\n\t\t\tthis.query.on(\"results\", this._stat_handler);\n\t\t\tthis.query.on(\"results\", this._aggs_handler);\n\t\t\tthis.buildHistogram();\n\t\t},\n\t\tbuildHistogram: function(query) {\n\t\t\tthis.statAggs = this.query.addAggs({\n\t\t\t\tstats: { field: this.config.spec.field_name }\n\t\t\t});\n\t\t\tthis.query.query();\n\t\t\tthis.query.removeAggs(this.statAggs);\n\t\t},\n\t\t_stat_handler: function(query, results) {\n\t\t\tif(! results.aggregations[this.statAggs]) { return; }\n\t\t\tthis.stats = results.aggregations[this.statAggs];\n\t\t\t// here we are calculating the approximate range  that will give us less than 121 columns\n\t\t\tvar rangeNames = [ \"year\", \"year\", \"month\", \"day\", \"hour\", \"minute\" ];\n\t\t\tvar rangeFactors = [100000, 12, 30, 24, 60, 60000 ];\n\t\t\tthis.intervalRange = 1;\n\t\t\tvar range = this.stats.max - this.stats.min;\n\t\t\tdo {\n\t\t\t\tthis.intervalName = rangeNames.pop();\n\t\t\t\tvar factor = rangeFactors.pop();\n\t\t\t\tthis.intervalRange *= factor;\n\t\t\t\trange = range / factor;\n\t\t\t} while(range > 70);\n\t\t\tthis.dateAggs = this.query.addAggs({\n\t\t\t\tdate_histogram : {\n\t\t\t\t\tfield: this.config.spec.field_name,\n\t\t\t\t\tinterval: this.intervalName\n\t\t\t\t}\n\t\t\t});\n\t\t\tthis.query.query();\n\t\t\tthis.query.removeAggs(this.dateAggs);\n\t\t},\n\t\t_aggs_handler: function(query, results) {\n\t\t\tif(! results.aggregations[this.dateAggs]) { return; }\n\t\t\tvar buckets = [], range = this.intervalRange;\n\t\t\tvar min = Math.floor(this.stats.min / range) * range;\n\t\t\tvar prec = [ \"year\", \"month\", \"day\", \"hour\", \"minute\", \"second\" ].indexOf(this.intervalName);\n\t\t\tresults.aggregations[this.dateAggs].buckets.forEach(function(entry) {\n\t\t\t\tbuckets[parseInt((entry.key - min) / range , 10)] = entry.doc_count;\n\t\t\t}, this);\n\t\t\tfor(var i = 0; i < buckets.length; i++) {\n\t\t\t\tbuckets[i] = buckets[i] || 0;\n\t\t\t}\n\t\t\tthis.el.removeClass(\"loading\");\n\t\t\tvar el = this.el.empty();\n\t\t\tvar w = el.width(), h = el.height();\n\t\t\tvar r = raphael(el[0], w, h );\n\t\t\tvar printEl = this.config.printEl;\n\t\t\tquery = this.config.query;\n\t\t\tr.g.barchart(0, 0, w, h, [buckets], { gutter: \"0\", vgutter: 0 }).hover(\n\t\t\t\tfunction() {\n\t\t\t\t\tthis.flag = r.g.popup(this.bar.x, h - 5, this.value || \"0\").insertBefore(this);\n\t\t\t\t}, function() {\n\t\t\t\t\tthis.flag.animate({opacity: 0}, 200, \">\", function () {this.remove();});\n\t\t\t\t}\n\t\t\t).click(function() {\n\t\t\t\tif(printEl) {\n\t\t\t\t\tprintEl.val(window.dateRangeParser.print(min + this.bar.index * range, prec));\n\t\t\t\t\tprintEl.trigger(\"keyup\");\n\t\t\t\t\tquery.query();\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\t\t_main_template: function() { return (\n\t\t\t{ tag: \"DIV\", cls: \"uiDateHistogram loading\", css: { height: \"50px\" }, children: [\n\t\t\t\ti18n.text(\"General.LoadingAggs\")\n\t\t\t] }\n\t\t); }\n\t});\n\n})( this.app, this.i18n, this.Raphael );\n(function( $, app, i18n ) {\n\n\tvar ui = app.ns(\"ui\");\n\tvar services = app.ns(\"services\");\n\n\tui.ClusterConnect = ui.AbstractWidget.extend({\n\t\tdefaults: {\n\t\t\tcluster: null\n\t\t},\n\t\tinit: function() {\n\t\t\tthis._super();\n\t\t\tthis.prefs = services.Preferences.instance();\n\t\t\tthis.cluster = this.config.cluster;\n\t\t\tthis.el = $.joey(this._main_template());\n\t\t\tthis.cluster.get( \"\", this._node_handler );\n\t\t},\n\n\t\t_node_handler: function(data) {\n\t\t\tif(data) {\n\t\t\t\tthis.prefs.set(\"app-base_uri\", this.cluster.base_uri);\n\t\t\t\tif(data.version && data.version.number)\n\t\t\t\t\tthis.cluster.setVersion(data.version.number);\n\t\t\t}\n\t\t},\n\n\t\t_reconnect_handler: function() {\n\t\t\tvar base_uri = this.el.find(\".uiClusterConnect-uri\").val();\n\t\t\tvar url;\n\t\t\tif(base_uri.indexOf(\"?\") !== -1) {\n\t\t\t\turl = base_uri.substring(0, base_uri.indexOf(\"?\")-1);\n\t\t\t} else {\n\t\t\t\turl = base_uri;\n\t\t\t}\n\t\t\tvar argstr = base_uri.substring(base_uri.indexOf(\"?\")+1, base_uri.length);\n\t\t\tvar args = argstr.split(\"&\").reduce(function(r, p) {\n\t\t\t\tr[decodeURIComponent(p.split(\"=\")[0])] = decodeURIComponent(p.split(\"=\")[1]);\n\t\t\t\treturn r;\n\t\t\t}, {});\n\t\t\t$(\"body\").empty().append(new app.App(\"body\", { id: \"es\",\n\t\t\t\tbase_uri: url,\n\t\t\t \tauth_user : args[\"auth_user\"] || \"\",\n\t\t\t \tauth_password : args[\"auth_password\"] || \"\"\n\t\t\t}));\n\t\t},\n\n\t\t_main_template: function() {\n\t\t\treturn { tag: \"SPAN\", cls: \"uiClusterConnect\", children: [\n\t\t\t\t{ tag: \"INPUT\", type: \"text\", cls: \"uiClusterConnect-uri\", onkeyup: function( ev ) {\n\t\t\t\t\tif(ev.which === 13) {\n\t\t\t\t\t\tev.preventDefault();\n\t\t\t\t\t\tthis._reconnect_handler();\n\t\t\t\t\t}\n\t\t\t\t}.bind(this), id: this.id(\"baseUri\"), value: this.cluster.base_uri },\n\t\t\t\t{ tag: \"BUTTON\", type: \"button\", text: i18n.text(\"Header.Connect\"), onclick: this._reconnect_handler }\n\t\t\t]};\n\t\t}\n\t});\n\n})( this.jQuery, this.app, this.i18n );\n\n\n(function( $, app, i18n ) {\n\n\tvar ui = app.ns(\"ui\");\n\tvar data = app.ns(\"data\");\n\n\tvar StructuredQuery = ui.AbstractWidget.extend({\n\t\tdefaults: {\n\t\t\tcluster: null  // (required) instanceof app.services.Cluster\n\t\t},\n\t\t_baseCls: \"uiStructuredQuery\",\n\t\tinit: function(parent) {\n\t\t\tthis._super();\n\t\t\tthis.selector = new ui.IndexSelector({\n\t\t\t\tonIndexChanged: this._indexChanged_handler,\n\t\t\t\tcluster: this.config.cluster\n\t\t\t});\n\t\t\tthis.el = $(this._main_template());\n\t\t\tthis.out = this.el.find(\"DIV.uiStructuredQuery-out\");\n\t\t\tthis.attach( parent );\n\t\t},\n\t\t\n\t\t_indexChanged_handler: function( index ) {\n\t\t\tthis.filter && this.filter.remove();\n\t\t\tthis.filter = new ui.FilterBrowser({\n\t\t\t\tcluster: this.config.cluster,\n\t\t\t\tindex: index,\n\t\t\t\tonStartingSearch: function() { this.el.find(\"DIV.uiStructuredQuery-out\").text( i18n.text(\"General.Searching\") ); this.el.find(\"DIV.uiStructuredQuery-src\").hide(); }.bind(this),\n\t\t\t\tonSearchSource: this._searchSource_handler,\n\t\t\t\tonResults: this._results_handler\n\t\t\t});\n\t\t\tthis.el.find(\".uiStructuredQuery-body\").append(this.filter);\n\t\t},\n\t\t\n\t\t_results_handler: function( filter, event ) {\n\t\t\tvar typeMap = {\n\t\t\t\t\"json\": this._jsonResults_handler,\n\t\t\t\t\"table\": this._tableResults_handler,\n\t\t\t\t\"csv\": this._csvResults_handler\n\t\t\t};\n\t\t\ttypeMap[ event.type ].call( this, event.data, event.metadata );\n\t\t},\n\t\t_jsonResults_handler: function( results ) {\n\t\t\tthis.el.find(\"DIV.uiStructuredQuery-out\").empty().append( new ui.JsonPretty({ obj: results }));\n\t\t},\n\t\t_csvResults_handler: function( results ) {\n\t\t\tthis.el.find(\"DIV.uiStructuredQuery-out\").empty().append( new ui.CSVTable({ results: results }));\n\t\t},\n\t\t_tableResults_handler: function( results, metadata ) {\n\t\t\t// hack up a QueryDataSourceInterface so that StructuredQuery keeps working without using a Query object\n\t\t\tvar qdi = new data.QueryDataSourceInterface({ metadata: metadata, query: new data.Query() });\n\t\t\tvar tab = new ui.Table( {\n\t\t\t\tstore: qdi,\n\t\t\t\theight: 400,\n\t\t\t\twidth: this.out.innerWidth()\n\t\t\t} ).attach(this.out.empty());\n\t\t\tqdi._results_handler(qdi.config.query, results);\n\t\t},\n\t\t\n\t\t_showRawJSON : function() {\n\t\t\tif($(\"#rawJsonText\").length === 0) {\n\t\t\t\tvar hiddenButton = $(\"#showRawJSON\");\n\t\t\t\tvar jsonText = $({tag: \"P\", type: \"p\", id: \"rawJsonText\"});\n\t\t\t\tjsonText.text(hiddenButton[0].value);\n\t\t\t\thiddenButton.parent().append(jsonText);\n\t\t\t}\n\t\t},\n\t\t\n\t\t_searchSource_handler: function(src) {\n\t\t\tvar searchSourceDiv = this.el.find(\"DIV.uiStructuredQuery-src\");\n\t\t\tsearchSourceDiv.empty().append(new app.ui.JsonPretty({ obj: src }));\n\t\t\tif(typeof JSON !== \"undefined\") {\n\t\t\t\tvar showRawJSON = $({ tag: \"BUTTON\", type: \"button\", text: i18n.text(\"StructuredQuery.ShowRawJson\"), id: \"showRawJSON\", value: JSON.stringify(src), onclick: this._showRawJSON });\n\t\t\t\tsearchSourceDiv.append(showRawJSON);\n\t\t\t}\n\t\t\tsearchSourceDiv.show();\n\t\t},\n\t\t\n\t\t_main_template: function() {\n\t\t\treturn { tag: \"DIV\", cls: this._baseCls, children: [\n\t\t\t\tthis.selector,\n\t\t\t\t{ tag: \"DIV\", cls: \"uiStructuredQuery-body\" },\n\t\t\t\t{ tag: \"DIV\", cls: \"uiStructuredQuery-src\", css: { display: \"none\" } },\n\t\t\t\t{ tag: \"DIV\", cls: \"uiStructuredQuery-out\" }\n\t\t\t]};\n\t\t}\n\t});\n\n\tui.StructuredQuery = ui.Page.extend({\n\t\tinit: function() {\n\t\t\tthis.q = new StructuredQuery( this.config );\n\t\t\tthis.el = this.q.el;\n\t\t}\n\t});\n\n})( this.jQuery, this.app, this.i18n );\n\n(function( $, app, i18n ) {\n\n\tvar ui = app.ns(\"ui\");\n\tvar data = app.ns(\"data\");\n\tvar ut = app.ns(\"ut\");\n\n\tui.FilterBrowser = ui.AbstractWidget.extend({\n\t\tdefaults: {\n\t\t\tcluster: null,  // (required) instanceof app.services.Cluster\n\t\t\tindex: \"\" // (required) name of the index to query\n\t\t},\n\n\t\tinit: function(parent) {\n\t\t\tthis._super();\n\t\t\tthis._cluster = this.config.cluster;\n\t\t\tthis.el = $(this._main_template());\n\t\t\tthis.filtersEl = this.el.find(\".uiFilterBrowser-filters\");\n\t\t\tthis.attach( parent );\n\t\t\tnew data.MetaDataFactory({ cluster: this._cluster, onReady: function(metadata, eventData) {\n\t\t\t\tthis.metadata = metadata;\n\t\t\t\tthis._createFilters_handler(eventData.originalData.metadata.indices);\n\t\t\t}.bind(this) });\n\t\t},\n\n\t\t_createFilters_handler: function(data) {\n\t\t\tvar filters = [];\n\t\t\tfunction scan_properties(path, obj) {\n\t\t\t\tif (obj.properties) {\n\t\t\t\t\tfor (var prop in obj.properties) {\n\t\t\t\t\t\tscan_properties(path.concat(prop), obj.properties[prop]);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// handle multi_field \n\t\t\t\t\tif (obj.fields) {\n\t\t\t\t\t\tfor (var subField in obj.fields) {\n\t\t\t\t\t\t\tfilters.push({ path: (path[path.length - 1] !== subField) ? path.concat(subField) : path, type: obj.fields[subField].type, meta: obj.fields[subField] });\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tfilters.push({ path: path, type: obj.type, meta: obj });\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (data[this.config.index]){\n\t\t\t\tfor(var type in data[this.config.index].mappings) {\n\t\t\t\t\tscan_properties([type], data[this.config.index].mappings[type]);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfilters.sort( function(a, b) {\n\t\t\t\tvar x = a.path.join(\".\");\n\t\t\t\tvar y = b.path.join(\".\");\n\t\t\t\treturn (x < y) ? -1 : (x > y) ? 1 : 0;\n\t\t\t});\n\n\t\t\tthis.filters = [\n\t\t\t\t{ path: [\"match_all\"], type: \"match_all\", meta: {} },\n\t\t\t\t{ path: [\"_all\"], type: \"_all\", meta: {}}\n\t\t\t].concat(filters);\n\n\t\t\tthis._addFilterRow_handler();\n\t\t},\n\t\t\n\t\t_addFilterRow_handler: function() {\n\t\t\tthis.filtersEl.append(this._filter_template());\n\t\t},\n\t\t\n\t\t_removeFilterRow_handler: function(jEv) {\n\t\t\t$(jEv.target).closest(\"DIV.uiFilterBrowser-row\").remove();\n\t\t\tif(this.filtersEl.children().length === 0) {\n\t\t\t\tthis._addFilterRow_handler();\n\t\t\t}\n\t\t},\n\t\t\n\t\t_search_handler: function() {\n\t\t\tvar search = new data.BoolQuery();\n\t\t\tsearch.setSize( this.el.find(\".uiFilterBrowser-outputSize\").val() )\n\t\t\tthis.fire(\"startingSearch\");\n\t\t\tthis.filtersEl.find(\".uiFilterBrowser-row\").each(function(i, row) {\n\t\t\t\trow = $(row);\n\t\t\t\tvar bool = row.find(\".bool\").val();\n\t\t\t\tvar field = row.find(\".field\").val();\n\t\t\t\tvar op = row.find(\".op\").val();\n\t\t\t\tvar value = {};\n\t\t\t\tif(field === \"match_all\") {\n\t\t\t\t\top = \"match_all\";\n\t\t\t\t} else if(op === \"range\") {\n\t\t\t\t\tvar lowqual = row.find(\".lowqual\").val(),\n\t\t\t\t\t\thighqual = row.find(\".highqual\").val();\n\t\t\t\t\tif(lowqual.length) {\n\t\t\t\t\t\tvalue[row.find(\".lowop\").val()] = lowqual;\n\t\t\t\t\t}\n\t\t\t\t\tif(highqual.length) {\n\t\t\t\t\t\tvalue[row.find(\".highop\").val()] = highqual;\n\t\t\t\t\t}\n\t\t\t\t} else if(op === \"fuzzy\") {\n\t\t\t\t\tvar qual = row.find(\".qual\").val(),\n\t\t\t\t\t\tfuzzyqual = row.find(\".fuzzyqual\").val();\n\t\t\t\t\tif(qual.length) {\n\t\t\t\t\t\tvalue[\"value\"] = qual;\n\t\t\t\t\t}\n\t\t\t\t\tif(fuzzyqual.length) {\n\t\t\t\t\t\tvalue[row.find(\".fuzzyop\").val()] = fuzzyqual;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tvalue = row.find(\".qual\").val();\n\t\t\t\t}\n\t\t\t\tsearch.addClause(value, field, op, bool);\n\t\t\t});\n\t\t\tif(this.el.find(\".uiFilterBrowser-showSrc\").attr(\"checked\")) {\n\t\t\t\tthis.fire(\"searchSource\", search.search);\n\t\t\t}\n\t\t\tthis._cluster.post( this.config.index + \"/_search\", search.getData(), this._results_handler );\n\t\t},\n\t\t\n\t\t_results_handler: function( data ) {\n\t\t\tvar type = this.el.find(\".uiFilterBrowser-outputFormat\").val();\n\t\t\tthis.fire(\"results\", this, { type: type, data: data, metadata: this.metadata });\n\t\t},\n\t\t\n\t\t_changeQueryField_handler: function(jEv) {\n\t\t\tvar select = $(jEv.target);\n\t\t\tvar spec = select.children(\":selected\").data(\"spec\");\n\t\t\tselect.siblings().remove(\".op,.qual,.range,.fuzzy\");\n\t\t\tvar ops = [];\n\t\t\tif(spec.type === 'match_all') {\n\t\t\t} else if(spec.type === '_all') {\n\t\t\t\tops = [\"query_string\"];\n\t\t\t} else if(spec.type === 'string' || spec.type === 'text' || spec.type === 'keyword') {\n\t\t\t\tops = [\"match\", \"term\", \"wildcard\", \"prefix\", \"fuzzy\", \"range\", \"query_string\", \"text\", \"missing\"];\n\t\t\t} else if(spec.type === 'long' || spec.type === 'integer' || spec.type === 'float' ||\n\t\t\t\t\tspec.type === 'byte' || spec.type === 'short' || spec.type === 'double') {\n\t\t\t\tops = [\"term\", \"range\", \"fuzzy\", \"query_string\", \"missing\"];\n\t\t\t} else if(spec.type === 'date') {\n\t\t\t\tops = [\"term\", \"range\", \"fuzzy\", \"query_string\", \"missing\"];\n\t\t\t} else if(spec.type === 'geo_point') {\n\t\t\t\tops = [\"missing\"];\n\t\t\t} else if(spec.type === 'ip') {\n\t\t\t\tops = [\"term\", \"range\", \"fuzzy\", \"query_string\", \"missing\"];\n\t\t\t} else if(spec.type === 'boolean') {\n\t\t\t\tops = [\"term\"]\n\t\t\t}\n\t\t\tselect.after({ tag: \"SELECT\", cls: \"op\", onchange: this._changeQueryOp_handler, children: ops.map(ut.option_template) });\n\t\t\tselect.next().change();\n\t\t},\n\t\t\n\t\t_changeQueryOp_handler: function(jEv) {\n\t\t\tvar op = $(jEv.target), opv = op.val();\n\t\t\top.siblings().remove(\".qual,.range,.fuzzy\");\n\t\t\tif(opv === 'match' || opv === 'term' || opv === 'wildcard' || opv === 'prefix' || opv === \"query_string\" || opv === 'text') {\n\t\t\t\top.after({ tag: \"INPUT\", cls: \"qual\", type: \"text\" });\n\t\t\t} else if(opv === 'range') {\n\t\t\t\top.after(this._range_template());\n\t\t\t} else if(opv === 'fuzzy') {\n\t\t\t\top.after(this._fuzzy_template());\n\t\t\t}\n\t\t},\n\t\t\n\t\t_main_template: function() {\n\t\t\treturn { tag: \"DIV\", children: [\n\t\t\t\t{ tag: \"DIV\", cls: \"uiFilterBrowser-filters\" },\n\t\t\t\t{ tag: \"BUTTON\", type: \"button\", text: i18n.text(\"General.Search\"), onclick: this._search_handler },\n\t\t\t\t{ tag: \"LABEL\", children:\n\t\t\t\t\ti18n.complex(\"FilterBrowser.OutputType\", { tag: \"SELECT\", cls: \"uiFilterBrowser-outputFormat\", children: [\n\t\t\t\t\t\t{ text: i18n.text(\"Output.Table\"), value: \"table\" },\n\t\t\t\t\t\t{ text: i18n.text(\"Output.JSON\"), value: \"json\" },\n\t\t\t\t\t\t{ text: i18n.text(\"Output.CSV\"), value: \"csv\" }\n\t\t\t\t\t].map(function( o ) { return $.extend({ tag: \"OPTION\" }, o ); } ) } )\n\t\t\t\t},\n\t\t\t\t{ tag: \"LABEL\", children:\n\t\t\t\t\ti18n.complex(\"FilterBrowser.OutputSize\", { tag: \"SELECT\", cls: \"uiFilterBrowser-outputSize\",\n\t\t\t\t\t\tchildren: [ \"10\", \"50\", \"250\", \"1000\", \"5000\", \"25000\" ].map( ut.option_template )\n\t\t\t\t\t} )\n\t\t\t\t},\n\t\t\t\t{ tag: \"LABEL\", children: [ { tag: \"INPUT\", type: \"checkbox\", cls: \"uiFilterBrowser-showSrc\" }, i18n.text(\"Output.ShowSource\") ] }\n\t\t\t]};\n\t\t},\n\t\t\n\t\t_filter_template: function() {\n\t\t\treturn { tag: \"DIV\", cls: \"uiFilterBrowser-row\", children: [\n\t\t\t\t{ tag: \"SELECT\", cls: \"bool\", children: [\"must\", \"must_not\", \"should\"].map(ut.option_template) },\n\t\t\t\t{ tag: \"SELECT\", cls: \"field\", onchange: this._changeQueryField_handler, children: this.filters.map(function(f) {\n\t\t\t\t\treturn { tag: \"OPTION\", data: { spec: f }, value: f.path.join(\".\"), text: f.path.join(\".\") };\n\t\t\t\t})},\n\t\t\t\t{ tag: \"BUTTON\", type: \"button\", text: \"+\", onclick: this._addFilterRow_handler },\n\t\t\t\t{ tag: \"BUTTON\", type: \"button\", text: \"-\", onclick: this._removeFilterRow_handler }\n\t\t\t]};\n\t\t},\n\t\t\n\t\t_range_template: function() {\n\t\t\treturn { tag: \"SPAN\", cls: \"range\", children: [\n\t\t\t\t{ tag: \"SELECT\", cls: \"lowop\", children: [\"gt\", \"gte\"].map(ut.option_template) },\n\t\t\t\t{ tag: \"INPUT\", type: \"text\", cls: \"lowqual\" },\n\t\t\t\t{ tag: \"SELECT\", cls: \"highop\", children: [\"lt\", \"lte\"].map(ut.option_template) },\n\t\t\t\t{ tag: \"INPUT\", type: \"text\", cls: \"highqual\" }\n\t\t\t]};\n\t\t},\n\n\t\t_fuzzy_template: function() {\n\t\t\treturn { tag: \"SPAN\", cls: \"fuzzy\", children: [\n\t\t\t\t{ tag: \"INPUT\", cls: \"qual\", type: \"text\" },\n\t\t\t\t{ tag: \"SELECT\", cls: \"fuzzyop\", children: [\"max_expansions\", \"min_similarity\"].map(ut.option_template) },\n\t\t\t\t{ tag: \"INPUT\", cls: \"fuzzyqual\", type: \"text\" }\n\t\t\t]};\n\t\t}\n\t});\n\t\n})( this.jQuery, this.app, this.i18n );\n\n(function( $, app, i18n ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.IndexSelector = ui.AbstractWidget.extend({\n\t\tinit: function(parent) {\n\t\t\tthis._super();\n\t\t\tthis.el = $(this._main_template());\n\t\t\tthis.attach( parent );\n\t\t\tthis.cluster = this.config.cluster;\n\t\t\tthis.update();\n\t\t},\n\t\tupdate: function() {\n\t\t\tthis.cluster.get( \"_stats\", this._update_handler );\n\t\t},\n\t\t\n\t\t_update_handler: function(data) {\n\t\t\tvar options = [];\n\t\t\tvar index_names = Object.keys(data.indices).sort();\n\t\t\tfor(var i=0; i < index_names.length; i++) { \n\t\t\t\tname = index_names[i];\n\t\t\t\toptions.push(this._option_template(name, data.indices[name])); \n\t\t\t}\n\t\t\tthis.el.find(\".uiIndexSelector-select\").empty().append(this._select_template(options));\n\t\t\tthis._indexChanged_handler();\n\t\t},\n\t\t\n\t\t_main_template: function() {\n\t\t\treturn { tag: \"DIV\", cls: \"uiIndexSelector\", children: i18n.complex( \"IndexSelector.SearchIndexForDocs\", { tag: \"SPAN\", cls: \"uiIndexSelector-select\" } ) };\n\t\t},\n\n\t\t_indexChanged_handler: function() {\n\t\t\tthis.fire(\"indexChanged\", this.el.find(\"SELECT\").val());\n\t\t},\n\n\t\t_select_template: function(options) {\n\t\t\treturn { tag: \"SELECT\", children: options, onChange: this._indexChanged_handler };\n\t\t},\n\t\t\n\t\t_option_template: function(name, index) {\n\t\t\treturn  { tag: \"OPTION\", value: name, text: i18n.text(\"IndexSelector.NameWithDocs\", name, index.primaries.docs.count ) };\n\t\t}\n\t});\n\n})( this.jQuery, this.app, this.i18n );\n\n(function( $, app, i18n ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.Header = ui.AbstractWidget.extend({\n\t\tdefaults: {\n\t\t\tcluster: null,\n\t\t\tclusterState: null\n\t\t},\n\t\t_baseCls: \"uiHeader\",\n\t\tinit: function() {\n\t\t\tthis._clusterConnect = new ui.ClusterConnect({\n\t\t\t\tcluster: this.config.cluster\n\t\t\t});\n\t\t\tvar quicks = [\n\t\t\t\t{ text: i18n.text(\"Nav.Info\"), path: \"\" },\n\t\t\t\t{ text: i18n.text(\"Nav.Status\"), path: \"_stats\" },\n\t\t\t\t{ text: i18n.text(\"Nav.NodeStats\"), path: \"_nodes/stats\" },\n\t\t\t\t{ text: i18n.text(\"Nav.ClusterNodes\"), path: \"_nodes\" },\n\t\t\t\t{ text: i18n.text(\"Nav.Plugins\"), path: \"_nodes/plugins\" },\n\t\t\t\t{ text: i18n.text(\"Nav.ClusterState\"), path: \"_cluster/state\" },\n\t\t\t\t{ text: i18n.text(\"Nav.ClusterHealth\"), path: \"_cluster/health\" },\n\t\t\t\t{ text: i18n.text(\"Nav.Templates\"), path: \"_template\" }\n\t\t\t];\n\t\t\tvar cluster = this.config.cluster;\n\t\t\tvar quickPanels = {};\n\t\t\tvar menuItems = quicks.map( function( item ) {\n\t\t\t\treturn { text: item.text, onclick: function() {\n\t\t\t\t\tcluster.get( item.path, function( data ) {\n\t\t\t\t\t\tquickPanels[ item.path ] && quickPanels[ item.path ].el && quickPanels[ item.path ].remove();\n\t\t\t\t\t\tquickPanels[ item.path ] = new ui.JsonPanel({\n\t\t\t\t\t\t\ttitle: item.text,\n\t\t\t\t\t\t\tjson: data\n\t\t\t\t\t\t});\n\t\t\t\t\t} );\n\t\t\t\t} };\n\t\t\t}, this );\n\t\t\tthis._quickMenu = new ui.MenuButton({\n\t\t\t\tlabel: i18n.text(\"NodeInfoMenu.Title\"),\n\t\t\t\tmenu: new ui.MenuPanel({\n\t\t\t\t\titems: menuItems\n\t\t\t\t})\n\t\t\t});\n\t\t\tthis.el = $.joey( this._main_template() );\n\t\t\tthis.nameEl = this.el.find(\".uiHeader-name\");\n\t\t\tthis.statEl = this.el.find(\".uiHeader-status\");\n\t\t\tthis._clusterState = this.config.clusterState;\n\t\t\tthis._clusterState.on(\"data\", function( state ) {\n\t\t\t\tvar shards = state.status._shards;\n\t\t\t\tvar colour = state.clusterHealth.status;\n\t\t\t\tvar name = state.clusterState.cluster_name;\n\t\t\t\tthis.nameEl.text( name );\n\t\t\t\tthis.statEl\n\t\t\t\t\t.text( i18n.text(\"Header.ClusterHealth\", colour, shards.successful, shards.total ) )\n\t\t\t\t\t.css( \"background\", colour );\n\t\t\t}.bind(this));\n\t\t\tthis.statEl.text( i18n.text(\"Header.ClusterNotConnected\") ).css(\"background\", \"grey\");\n\t\t\tthis._clusterState.refresh();\n\t\t},\n\t\t_main_template: function() { return (\n\t\t\t{ tag: \"DIV\", cls: this._baseCls, children: [\n\t\t\t\tthis._clusterConnect,\n\t\t\t\t{ tag: \"SPAN\", cls: \"uiHeader-name\" },\n\t\t\t\t{ tag: \"SPAN\", cls: \"uiHeader-status\" },\n\t\t\t\t{ tag: \"H1\", text: i18n.text(\"General.Elasticsearch\") },\n\t\t\t\t{ tag: \"SPAN\", cls: \"pull-right\", children: [\n\t\t\t\t\tthis._quickMenu\n\t\t\t\t] }\n\t\t\t] }\n\t\t); }\n\t} );\n\n})( this.jQuery, this.app, this.i18n );\n\n(function( $, app, i18n ) {\n\t\n\tvar ui = app.ns(\"ui\");\n\tvar ut = app.ns(\"ut\");\n\n\tui.IndexOverview = ui.Page.extend({\n\t\tdefaults: {\n\t\t\tcluster: null\n\t\t},\n\t\tinit: function() {\n\t\t\tthis._super();\n\t\t\tthis.cluster = this.config.cluster;\n\t\t\tthis._clusterState = this.config.clusterState;\n\t\t\tthis._clusterState.on(\"data\", this._refresh_handler );\n\t\t\tthis.el = $(this._main_template());\n\t\t\tthis._refresh_handler();\n\t\t},\n\t\tremove: function() {\n\t\t\tthis._clusterState.removeObserver( \"data\", this._refresh_handler );\n\t\t},\n\t\t_refresh_handler: function() {\n\t\t\tvar state = this._clusterState;\n\t\t\tvar view = {\n\t\t\t\tindices: acx.eachMap( state.status.indices, function( name, index ) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tname: name,\n\t\t\t\t\t\tstate: index\n\t\t\t\t\t};\n\t\t\t\t}).sort( function( a, b ) {\n\t\t\t\t\treturn a.name < b.name ? -1 : 1;\n\t\t\t\t})\n\t\t\t};\n\t\t\tthis._indexViewEl && this._indexViewEl.remove();\n\t\t\tthis._indexViewEl = $( this._indexTable_template( view ) );\n\t\t\tthis.el.find(\".uiIndexOverview-table\").append( this._indexViewEl );\n\t\t},\n\t\t_newIndex_handler: function() {\n\t\t\tvar fields = new app.ux.FieldCollection({\n\t\t\t\tfields: [\n\t\t\t\t\tnew ui.TextField({ label: i18n.text(\"ClusterOverView.IndexName\"), name: \"_name\", require: true }),\n\t\t\t\t\tnew ui.TextField({\n\t\t\t\t\t\tlabel: i18n.text(\"ClusterOverview.NumShards\"),\n\t\t\t\t\t\tname: \"number_of_shards\",\n\t\t\t\t\t\tvalue: \"5\",\n\t\t\t\t\t\trequire: function( val ) { return parseInt( val, 10 ) >= 1; }\n\t\t\t\t\t}),\n\t\t\t\t\tnew ui.TextField({\n\t\t\t\t\t\tlabel: i18n.text(\"ClusterOverview.NumReplicas\"),\n\t\t\t\t\t\tname: \"number_of_replicas\",\n\t\t\t\t\t\tvalue: \"1\",\n\t\t\t\t\t\trequire: function( val ) { return parseInt( val, 10 ) >= 0; }\n\t\t\t\t\t})\n\t\t\t\t]\n\t\t\t});\n\t\t\tvar dialog = new ui.DialogPanel({\n\t\t\t\ttitle: i18n.text(\"ClusterOverview.NewIndex\"),\n\t\t\t\tbody: new ui.PanelForm({ fields: fields }),\n\t\t\t\tonCommit: function(panel, args) {\n\t\t\t\t\tif(fields.validate()) {\n\t\t\t\t\t\tvar data = fields.getData();\n\t\t\t\t\t\tvar name = data[\"_name\"];\n\t\t\t\t\t\tdelete data[\"_name\"];\n\t\t\t\t\t\tthis.config.cluster.put( encodeURIComponent( name ), JSON.stringify({ settings: { index: data } }), function(d) {\n\t\t\t\t\t\t\tdialog.close();\n\t\t\t\t\t\t\talert(JSON.stringify(d));\n\t\t\t\t\t\t\tthis._clusterState.refresh();\n\t\t\t\t\t\t}.bind(this) );\n\t\t\t\t\t}\n\t\t\t\t}.bind(this)\n\t\t\t}).open();\n\t\t},\n\t\t_indexTable_template: function( view ) { return (\n\t\t\t{ tag: \"TABLE\", cls: \"table\", children: [\n\t\t\t\t{ tag: \"THEAD\", children: [\n\t\t\t\t\t{ tag: \"TR\", children: [\n\t\t\t\t\t\t{ tag: \"TH\" },\n\t\t\t\t\t\t{ tag: \"TH\", children: [\n\t\t\t\t\t\t\t{ tag: \"H3\", text: \"Size\" }\n\t\t\t\t\t\t] },\n\t\t\t\t\t\t{ tag: \"TH\", children: [\n\t\t\t\t\t\t\t{ tag: \"H3\", text: \"Docs\" }\n\t\t\t\t\t\t] }\n\t\t\t\t\t] }\n\t\t\t\t] },\n\t\t\t\t{ tag: \"TBODY\", cls: \"striped\", children: view.indices.map( this._index_template, this ) }\n\t\t\t] }\n\t\t); },\n\n\t\t_index_template: function( index ) { return (\n\t\t\t{ tag: \"TR\", children: [\n\t\t\t\t{ tag: \"TD\", children: [\n\t\t\t\t\t{ tag: \"H3\", text: index.name }\n\t\t\t\t] },\n\t\t\t\t{ tag: \"TD\", text: ut.byteSize_template( index.state.primaries.store.size_in_bytes ) + \"/\" + ut.byteSize_template( index.state.total.store.size_in_bytes ) },\n\t\t\t\t{ tag: \"TD\", text: ut.count_template( index.state.primaries.docs.count ) }\n\t\t\t] }\n\t\t); },\n\t\t_main_template: function() {\n\t\t\treturn { tag: \"DIV\", id: this.id(), cls: \"uiIndexOverview\", children: [\n\t\t\t\tnew ui.Toolbar({\n\t\t\t\t\tlabel: i18n.text(\"IndexOverview.PageTitle\"),\n\t\t\t\t\tleft: [\n\t\t\t\t\t\tnew ui.Button({\n\t\t\t\t\t\t\tlabel: i18n.text(\"ClusterOverview.NewIndex\"),\n\t\t\t\t\t\t\tonclick: this._newIndex_handler\n\t\t\t\t\t\t}),\n\t\t\t\t\t]\n\t\t\t\t}),\n\t\t\t\t{ tag: \"DIV\", cls: \"uiIndexOverview-table\", children: this._indexViewEl }\n\t\t\t] };\n\t\t}\n\n\t});\n\n})( this.jQuery, this.app, this.i18n );\n\n(function( app, i18n ) {\n\n\tvar ui = app.ns(\"ui\");\n\tvar services = app.ns(\"services\");\n\n\tapp.App = ui.AbstractWidget.extend({\n\t\tdefaults: {\n\t\t\tbase_uri: null\n\t\t},\n\t\tinit: function(parent) {\n\t\t\tthis._super();\n\t\t\tthis.prefs = services.Preferences.instance();\n\t\t\tthis.base_uri = this.config.base_uri || this.prefs.get(\"app-base_uri\") || \"http://localhost:9200\";\n\t\t\tif( this.base_uri.charAt( this.base_uri.length - 1 ) !== \"/\" ) {\n\t\t\t\t// XHR request fails if the URL is not ending with a \"/\"\n\t\t\t\tthis.base_uri += \"/\";\n\t\t\t}\n\t\t\tif( this.config.auth_user ) {\n\t\t\t\tvar credentials = window.btoa( this.config.auth_user + \":\" + this.config.auth_password );\n\t\t\t\t$.ajaxSetup({\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t\"Authorization\": \"Basic \" + credentials\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t\tthis.cluster = new services.Cluster({ base_uri: this.base_uri });\n\t\t\tthis._clusterState = new services.ClusterState({\n\t\t\t\tcluster: this.cluster\n\t\t\t});\n\n\t\t\tthis._header = new ui.Header({ cluster: this.cluster, clusterState: this._clusterState });\n\t\t\tthis.$body = $.joey( this._body_template() );\n\t\t\tthis.el = $.joey(this._main_template());\n\t\t\tthis.attach( parent );\n\t\t\tthis.instances = {};\n\t\t\tthis.el.find(\".uiApp-headerMenuItem:first\").click();\n\t\t\tif( this.config.dashboard ) {\n\t\t\t\tif( this.config.dashboard === \"cluster\" ) {\n\t\t\t\t\tvar page = this.instances[\"ClusterOverview\"];\n\t\t\t\t\tpage._refreshButton.set( 5000 );\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\tnavigateTo: function( type, config, ev ) {\n\t\t\tif( ev.target.classList.contains( \"uiApp-headerNewMenuItem\" ) ) {\n\t\t\t\tthis.showNew( type, config, ev );\n\t\t\t} else {\n\t\t\t\tvar ref = type + \"0\";\n\t\t\t\tif(! this.instances[ ref ]) {\n\t\t\t\t\tthis.createPage( type, 0, config );\n\t\t\t\t}\n\t\t\t\tthis.show( ref, ev );\n\t\t\t}\n\t\t},\n\n\t\tcreatePage: function( type, id, config ) {\n\t\t\tvar page = this.instances[ type + id ] = new ui[ type ]( config );\n\t\t\tthis.$body.append( page );\n\t\t\treturn page;\n\t\t},\n\n\t\tshow: function( ref, ev ) {\n\t\t\t$( ev.target ).closest(\"DIV.uiApp-headerMenuItem\").addClass(\"active\").siblings().removeClass(\"active\");\n\t\t\tfor(var p in this.instances) {\n\t\t\t\tthis.instances[p][ p === ref ? \"show\" : \"hide\" ]();\n\t\t\t}\n\t\t},\n\n\t\tshowNew: function( type, config, jEv ) {\n\t\t\tvar ref, page, $tab,\n\t\t\t\ttype_index = 0;\n\n\t\t\twhile ( ! page ) {\n\t\t\t\tref = type + ( ++type_index );\n\t\t\t\tif (! ( ref in this.instances ) ) {\n\t\t\t\t\tpage = this.createPage( type, type_index, config );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add the tab and its click handlers\n\t\t\t$tab = $.joey({\n\t\t\t\ttag: \"DIV\",\n\t\t\t\tcls: \"uiApp-headerMenuItem pull-left\",\n\t\t\t\ttext: i18n.text(\"Nav.\" + type ) + \" \" + type_index,\n\t\t\t\tonclick: function( ev ) { this.show( ref, ev ); }.bind(this),\n\t\t\t\tchildren: [\n\t\t\t\t\t{ tag: \"A\", text: \" [-]\", onclick: function (ev) {\n\t\t\t\t\t\t$tab.remove();\n\t\t\t\t\t\tpage.remove();\n\t\t\t\t\t\tdelete this.instances[ ref ];\n\t\t\t\t\t}.bind(this) }\n\t\t\t\t]\n\t\t\t});\n\n\t\t\t$('.uiApp-headerMenu').append( $tab );\n\t\t\t$tab.trigger(\"click\");\n\t\t},\n\n\t\t_openAnyRequest_handler: function(ev) { this.navigateTo(\"AnyRequest\", { cluster: this.cluster }, ev ); },\n\t\t_openStructuredQuery_handler: function(ev) { this.navigateTo(\"StructuredQuery\", { cluster: this.cluster }, ev ); },\n\t\t_openBrowser_handler: function(ev) { this.navigateTo(\"Browser\", { cluster: this.cluster }, ev );  },\n\t\t_openClusterOverview_handler: function(ev) { this.navigateTo(\"ClusterOverview\", { cluster: this.cluster, clusterState: this._clusterState }, ev ); },\n\t\t_openIndexOverview_handler: function(ev) { this.navigateTo(\"IndexOverview\", { cluster: this.cluster, clusterState: this._clusterState }, ev ); },\n\n\t\t_body_template: function() { return (\n\t\t\t{ tag: \"DIV\", id: this.id(\"body\"), cls: \"uiApp-body\" }\n\t\t); },\n\n\t\t_main_template: function() {\n\t\t\treturn { tag: \"DIV\", cls: \"uiApp\", children: [\n\t\t\t\t{ tag: \"DIV\", id: this.id(\"header\"), cls: \"uiApp-header\", children: [\n\t\t\t\t\tthis._header,\n\t\t\t\t\t{ tag: \"DIV\", cls: \"uiApp-headerMenu\", children: [\n\t\t\t\t\t\t{ tag: \"DIV\", cls: \"uiApp-headerMenuItem pull-left\", text: i18n.text(\"Nav.Overview\"), onclick: this._openClusterOverview_handler },\n\t\t\t\t\t\t{ tag: \"DIV\", cls: \"uiApp-headerMenuItem pull-left\", text: i18n.text(\"Nav.Indices\"), onclick: this._openIndexOverview_handler },\n\t\t\t\t\t\t{ tag: \"DIV\", cls: \"uiApp-headerMenuItem pull-left\", text: i18n.text(\"Nav.Browser\"), onclick: this._openBrowser_handler },\n\t\t\t\t\t\t{ tag: \"DIV\", cls: \"uiApp-headerMenuItem pull-left\", text: i18n.text(\"Nav.StructuredQuery\"), onclick: this._openStructuredQuery_handler, children: [\n\t\t\t\t\t\t\t{ tag: \"A\", cls: \"uiApp-headerNewMenuItem \", text: ' [+]' }\n\t\t\t\t\t\t] },\n\t\t\t\t\t\t{ tag: \"DIV\", cls: \"uiApp-headerMenuItem pull-left\", text: i18n.text(\"Nav.AnyRequest\"), onclick: this._openAnyRequest_handler, children: [\n\t\t\t\t\t\t\t{ tag: \"A\", cls: \"uiApp-headerNewMenuItem \", text: ' [+]' }\n\t\t\t\t\t\t] },\n\t\t\t\t\t]}\n\t\t\t\t]},\n\t\t\t\tthis.$body\n\t\t\t]};\n\t\t}\n\t\t\n\t});\n\n})( this.app, this.i18n );\n"
  },
  {
    "path": "_site/background.js",
    "content": "chrome.browserAction.onClicked.addListener(function (tab) {\n    chrome.tabs.create({'url': chrome.extension.getURL('index.html')}, function (tab) {\n    });\n});\n  "
  },
  {
    "path": "_site/base/reset.css",
    "content": "BODY {\n\tfont-family: Verdana, sans-serif;\n\tfont-size: 73%;\n\tpadding: 0;\n\tmargin: 0;\n}\n\nINPUT, SELECT, TEXTAREA {\n\tborder: 1px solid #cecece;\n\tpadding: 1px 3px;\n\tbackground: white;\n}\n\nSELECT {\n\tpadding: 0;\n}\n\n.saf SELECT {\n\tmargin-top: 0;\n\tmargin-bottom: 0;\n}\n\nTEXTAREA, CODE {\n\tfont-family: monospace;\n\tfont-size: 13px;\n}\n\nBUTTON::-moz-focus-inner {\n\tborder: none;\n}\n\n.pull-left {\n\tfloat: left;\n}\n\n.pull-right {\n\tfloat: right;\n}\n\n.loading  {\n\tbackground-image: url(loading.gif);\n\tbackground-repeat: no-repeat;\n\ttext-indent: 20px;\n}\n"
  },
  {
    "path": "_site/i18n.js",
    "content": "(function() {\n\t/**\n\t * provides text formatting and i18n key storage features<br>\n\t * implements most of the Sun Java MessageFormat functionality.\n\t * @see <a href=\"http://java.sun.com/j2se/1.5.0/docs/api/java/text/MessageFormat.html\" target=\"sun\">Sun's Documentation</a>\n\t */\n\n\tvar keys = {};\n\tvar locale = undefined;\n\n\tvar format = function(message, args) {\n\t\tvar substitute = function() {\n\t\t\tvar format = arguments[1].split(',');\n\t\t\tvar substr = escape(args[format.shift()]);\n\t\t\tif(format.length === 0) {\n\t\t\t\treturn substr; // simple substitution eg {0}\n\t\t\t}\n\t\t\tswitch(format.shift()) {\n\t\t\t\tcase \"number\" : return (new Number(substr)).toLocaleString(locale);\n\t\t\t\tcase \"date\" : return (new Date(+substr)).toLocaleDateString(locale); // date and time require milliseconds since epoch\n\t\t\t\tcase \"time\" : return (new Date(+substr)).toLocaleTimeString(locale); //  eg i18n.text(\"Key\", +(new Date())); for current time\n\t\t\t}\n\t\t\tvar styles = format.join(\"\").split(\"|\").map(function(style) {\n\t\t\t\treturn style.match(/(-?[\\.\\d]+)(#|<)([^{}]*)/);\n\t\t\t});\n\t\t\tvar match = styles[0][3];\n\t\t\tfor(var i=0; i<styles.length; i++) {\n\t\t\t\tif((styles[i][2] === \"#\" && (+styles[i][1]) === (+substr)) ||\n\t\t\t\t\t\t(styles[i][2] === \"<\" && ((+styles[i][1]) < (+substr)))) {\n\t\t\t\t\tmatch = styles[i][3];\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn match;\n\t\t};\n\n\t\treturn message && message.replace(/'(')|'([^']+)'|([^{']+)|([^']+)/g, function(x, sq, qs, ss, sub) {\n\t\t\tdo {} while(sub && (sub !== (sub = (sub.replace(/\\{([^{}]+)\\}/, substitute)))));\n\t\t\treturn sq || qs || ss || unescape(sub);\n\t\t});\n\t};\n\n\tthis.i18n = {\n\n\t\tsetLocale: function(loc){\n\t\t\tlocale = loc;\n\t\t},\n\n\t\tsetKeys: function(strings) {\n\t\t\tfor(var key in strings) {\n\t\t\t\tkeys[key] = strings[key];\n\t\t\t}\n\t\t},\n\n\t\ttext: function() {\n\t\t\tvar args = Array.prototype.slice.call(arguments),\n\t\t\t\tkey = keys[args.shift()];\n\t\t\tif(args.length === 0) {\n\t\t\t\treturn key;\n\t\t\t}\n\t\t\treturn format(key, args);\n\t\t},\n\n\t\tcomplex: function() {\n\t\t\tvar args = Array.prototype.slice.call(arguments),\n\t\t\t\tkey = keys[args.shift()],\n\t\t\t\tret = [],\n\t\t\t\treplacer = function(x, pt, sub) { ret.push(pt || args[+sub]); return \"\"; };\n\t\t\tdo {} while(key && key !== (key = key.replace(/([^{]+)|\\{(\\d+)\\}/, replacer )));\n\t\t\treturn ret;\n\t\t}\n\n\t};\n\n})();\n\n(function() {\n\tvar args = location.search.substring(1).split(\"&\").reduce(function(r, p) {\n\t\tr[decodeURIComponent(p.split(\"=\")[0])] = decodeURIComponent(p.split(\"=\")[1]); return r;\n\t}, {});\n\tvar nav = window.navigator;\n\tvar userLang = args[\"lang\"] || ( nav.languages && nav.languages[0] ) || nav.language || nav.userLanguage;\n\tvar scripts = document.getElementsByTagName('script');\n\tvar data = [].find.call(scripts, elm => elm.dataset && elm.dataset.langs).dataset;\n\tif( ! data[\"langs\"] ) {\n\t\treturn;\n\t}\n\tvar langs = data[\"langs\"].split(/\\s*,\\s*/);\n\tvar script0 = scripts[0];\n\tfunction install( lang ) {\n\t\tvar s = document.createElement(\"script\");\n\t\ts.src = data[\"basedir\"] + \"/\" + lang + '_strings.js';\n\t\ts.async = false;\n\t\tscript0.parentNode.appendChild(s);\n\t\tscript0 = s;\n\n\t\ti18n.setLocale(lang);\n\t}\n\n\tinstall( langs.shift() ); // always install primary language\n\tuserLang && langs\n\t\t.filter( function( lang ) { return userLang.indexOf( lang ) === 0; } )\n\t\t.forEach( install );\n}());\n"
  },
  {
    "path": "_site/index.html",
    "content": "<!DOCTYPE html>\n\n<html>\n\t<head>\n\t\t<meta charset=\"UTF-8\">\n\t\t<title>elasticsearch-head</title>\n\t\t<link rel=\"stylesheet\" href=\"base/reset.css\">\n\t\t<link rel=\"stylesheet\" href=\"vendor.css\">\n\t\t<link rel=\"stylesheet\" href=\"app.css\">\n\t\t<script src=\"i18n.js\" data-baseDir=\"lang\" data-langs=\"en,fr,pt,zh,zh-TW,tr,ja,vi\"></script>\n\t\t<script src=\"vendor.js\"></script>\n\t\t<script src=\"app.js\"></script>\n\t\t<script>\n\t\t\twindow.onload = function() {\n\t\t\t\tif(location.href.contains(\"/_plugin/\")) {\n\t\t\t\t\tvar base_uri = location.href.replace(/_plugin\\/.*/, '');\n\t\t\t\t}\n\t\t\t\tvar args = location.search.substring(1).split(\"&\").reduce(function(r, p) {\n\t\t\t\t\tr[decodeURIComponent(p.split(\"=\")[0])] = decodeURIComponent(p.split(\"=\")[1]); return r;\n\t\t\t\t}, {});\n\t\t\t\tnew app.App(\"body\", {\n\t\t\t\t\tid: \"es\",\n\t\t\t\t\tbase_uri: args[\"base_uri\"] || base_uri,\n\t\t\t\t\tauth_user : args[\"auth_user\"] || \"\",\n\t\t\t\t\tauth_password : args[\"auth_password\"],\n\t\t\t\t\tdashboard: args[\"dashboard\"]\n\t\t\t\t});\n\t\t\t};\n\t\t</script>\n\t\t<link rel=\"icon\" href=\"base/favicon.png\" type=\"image/png\">\n\t</head>\n\t<body></body>\n</html>\n"
  },
  {
    "path": "_site/lang/en_strings.js",
    "content": "i18n.setKeys({\n\t\"General.Elasticsearch\": \"Elasticsearch\",\n\t\"General.LoadingAggs\": \"Loading Aggregations...\",\n\t\"General.Searching\": \"Searching...\",\n\t\"General.Search\": \"Search\",\n\t\"General.Help\": \"Help\",\n\t\"General.HelpGlyph\": \"?\",\n\t\"General.CloseGlyph\": \"X\",\n\t\"General.RefreshResults\": \"Refresh\",\n\t\"General.ManualRefresh\": \"Manual Refresh\",\n\t\"General.RefreshQuickly\": \"Refresh quickly\",\n\t\"General.Refresh5seconds\": \"Refresh every 5 seconds\",\n\t\"General.Refresh1minute\": \"Refresh every minute\",\n\t\"AliasForm.AliasName\": \"Alias Name\",\n\t\"AliasForm.NewAliasForIndex\": \"New Alias for {0}\",\n\t\"AliasForm.DeleteAliasMessage\": \"type ''{0}'' to delete {1}. There is no undo\",\n\t\"AnyRequest.DisplayOptions\" : \"Display Options\",\n\t\"AnyRequest.AsGraph\" : \"Graph Results\",\n\t\"AnyRequest.AsJson\" : \"Show Raw JSON\",\n\t\"AnyRequest.AsTable\" : \"Show Search Results Table\",\n\t\"AnyRequest.History\" : \"History\",\n\t\"AnyRequest.RepeatRequest\" : \"Repeat Request\",\n\t\"AnyRequest.RepeatRequestSelect\" : \"Repeat request every \",\n\t\"AnyRequest.Transformer\" : \"Result Transformer\",\n\t\"AnyRequest.Pretty\": \"Pretty\",\n\t\"AnyRequest.Query\" : \"Query\",\n\t\"AnyRequest.Request\": \"Request\",\n\t\"AnyRequest.Requesting\": \"Requesting...\",\n\t\"AnyRequest.ValidateJSON\": \"Validate JSON\",\n\t\"Browser.Title\": \"Browser\",\n\t\"Browser.ResultSourcePanelTitle\": \"Result Source\",\n\t\"Command.DELETE\": \"DELETE\",\n\t\"Command.SHUTDOWN\": \"SHUTDOWN\",\n\t\"Command.DeleteAliasMessage\": \"Delete Alias?\",\n\t\"ClusterOverView.IndexName\": \"Index Name\",\n\t\"ClusterOverview.NumShards\": \"Number of Shards\",\n\t\"ClusterOverview.NumReplicas\": \"Number of Replicas\",\n\t\"ClusterOverview.NewIndex\": \"New Index\",\n\t\"IndexActionsMenu.Title\": \"Actions\",\n\t\"IndexActionsMenu.NewAlias\": \"New Alias...\",\n\t\"IndexActionsMenu.Refresh\": \"Refresh\",\n\t\"IndexActionsMenu.Flush\": \"Flush\",\n\t\"IndexActionsMenu.Optimize\": \"Optimize...\",\n\t\"IndexActionsMenu.ForceMerge\": \"ForceMerge...\",\n\t\"IndexActionsMenu.Snapshot\": \"Gateway Snapshot\",\n\t\"IndexActionsMenu.Analyser\": \"Test Analyser\",\n\t\"IndexActionsMenu.Open\": \"Open\",\n\t\"IndexActionsMenu.Close\": \"Close\",\n\t\"IndexActionsMenu.Delete\": \"Delete...\",\n\t\"IndexInfoMenu.Title\": \"Info\",\n\t\"IndexInfoMenu.Status\": \"Index Status\",\n\t\"IndexInfoMenu.Metadata\": \"Index Metadata\",\n\t\"IndexCommand.TextToAnalyze\": \"Text to Analyse\",\n\t\"IndexCommand.AnalyzerToUse\": \"Name of Analyzer (built-in or customized)\",\n\t\"IndexCommand.ShutdownMessage\": \"type ''{0}'' to shutdown {1}. Node can NOT be restarted from this interface\",\n\t\"IndexOverview.PageTitle\": \"Indices Overview\",\n\t\"IndexSelector.NameWithDocs\": \"{0} ({1} docs)\",\n\t\"IndexSelector.SearchIndexForDocs\": \"Search {0} for documents where:\",\n\t\"FilterBrowser.OutputType\": \"Output Results: {0}\",\n\t\"FilterBrowser.OutputSize\": \"Number of Results: {0}\",\n\t\"Header.ClusterHealth\": \"cluster health: {0} ({1} of {2})\",\n\t\"Header.ClusterNotConnected\": \"cluster health: not connected\",\n\t\"Header.Connect\": \"Connect\",\n\t\"Nav.AnyRequest\": \"Any Request\",\n\t\"Nav.Browser\": \"Browser\",\n\t\"Nav.ClusterHealth\": \"Cluster Health\",\n\t\"Nav.ClusterState\": \"Cluster State\",\n\t\"Nav.ClusterNodes\": \"Nodes Info\",\n\t\"Nav.Info\": \"Info\",\n\t\"Nav.NodeStats\": \"Nodes Stats\",\n\t\"Nav.Overview\": \"Overview\",\n\t\"Nav.Indices\": \"Indices\",\n\t\"Nav.Plugins\": \"Plugins\",\n\t\"Nav.Status\": \"Indices Stats\",\n\t\"Nav.Templates\": \"Templates\",\n\t\"Nav.StructuredQuery\": \"Structured Query\",\n\t\"NodeActionsMenu.Title\": \"Actions\",\n\t\"NodeActionsMenu.Shutdown\": \"Shutdown...\",\n\t\"NodeInfoMenu.Title\": \"Info\",\n\t\"NodeInfoMenu.ClusterNodeInfo\": \"Cluster Node Info\",\n\t\"NodeInfoMenu.NodeStats\": \"Node Stats\",\n\t\"NodeType.Client\": \"Client Node\",\n\t\"NodeType.Coord\": \"Coordinator\",\n\t\"NodeType.Master\": \"Master Node\",\n\t\"NodeType.Tribe\": \"Tribe Node\",\n\t\"NodeType.Worker\": \"Worker Node\",\n\t\"NodeType.Unassigned\": \"Unassigned\",\n\t\"OptimizeForm.OptimizeIndex\": \"Optimize {0}\",\n\t\"OptimizeForm.MaxSegments\": \"Maximum # Of Segments\",\n\t\"OptimizeForm.ExpungeDeletes\": \"Only Expunge Deletes\",\n\t\"OptimizeForm.FlushAfter\": \"Flush After Optimize\",\n\t\"OptimizeForm.WaitForMerge\": \"Wait For Merge\",\n\t\"ForceMergeForm.ForceMergeIndex\": \"ForceMerge {0}\",\n\t\"ForceMergeForm.MaxSegments\": \"Maximum # Of Segments\",\n\t\"ForceMergeForm.ExpungeDeletes\": \"Only Expunge Deletes\",\n\t\"ForceMergeForm.FlushAfter\": \"Flush After ForceMerge\",\n\t\"Overview.PageTitle\" : \"Cluster Overview\",\n\t\"Output.JSON\": \"JSON\",\n\t\"Output.Table\": \"Table\",\n\t\"Output.CSV\": \"CSV\",\n\t\"Output.ShowSource\": \"Show query source\",\n\t\"Preference.SortCluster\": \"Sort Cluster\",\n\t\"Sort.ByName\": \"By Name\",\n\t\"Sort.ByAddress\": \"By Address\",\n\t\"Sort.ByType\": \"By Type\",\n\t\"Preference.SortIndices\": \"Sort Indices\",\n\t\"SortIndices.Descending\": \"Descending\",\n\t\"SortIndices.Ascending\": \"Ascending\",\n\t\"Preference.ViewAliases\": \"View Aliases\",\n\t\"ViewAliases.Grouped\": \"Grouped\",\n\t\"ViewAliases.List\": \"List\",\n\t\"ViewAliases.None\": \"None\",\n\t\"Overview.IndexFilter\": \"Index Filter\",\n\t\"TableResults.Summary\": \"Searched {0} of {1} shards. {2} hits. {3} seconds\",\n\t\"QueryFilter.AllIndices\": \"All Indices\",\n\t\"QueryFilter.AnyValue\": \"any\",\n\t\"QueryFilter-Header-Indices\": \"Indices\",\n\t\"QueryFilter-Header-Types\": \"Types\",\n\t\"QueryFilter-Header-Fields\": \"Fields\",\n\t\"QueryFilter.DateRangeHint.from\": \"From : {0}\",\n\t\"QueryFilter.DateRangeHint.to\": \"  To : {0}\",\n\t\"Query.FailAndUndo\": \"Query Failed. Undoing last changes\",\n\t\"StructuredQuery.ShowRawJson\": \"Show Raw JSON\"\n});\n\ni18n.setKeys({\n\t\"AnyRequest.TransformerHelp\" : \"\\\n\t\t<p>The Result Transformer can be used to post process the raw json results from a request into a more useful format.</p>\\\n\t\t<p>The transformer should contain the body of a javascript function. The return value from the function becomes the new value passed to the json printer</p>\\\n\t\t<p>Example:<br>\\\n\t\t  <code>return root.hits.hits[0];</code> would traverse a result set to show just the first match<br>\\\n\t\t  <code>return Object.keys(root.nodes).reduce(function(tot, node) { return tot + root.nodes[node].os.mem.used_in_bytes; }, 0);</code> would return the total memory used across an entire cluster<br></p>\\\n\t\t<p>The following functions are available and can be useful processing arrays and objects<br>\\\n\t\t<ul>\\\n\t\t\t<li><i>Object.keys</i>(object) := array</li>\\\n\t\t\t<li>array.<i>forEach</i>(function(prop, index))</li>\\\n\t\t\t<li>array.<i>map</i>(function(prop, index)) := array</li>\\\n\t\t\t<li>array.<i>reduce</i>(function(accumulator, prop, index), initial_value) := final_value</li>\\\n\t\t</ul>\\\n\t\t<p>When Repeat Request is running, an extra parameter called prev is passed to the transformation function. This allows comparisons, and cumulative graphing</p>\\\n\t\t<p>Example:<br>\\\n\t\t<code>var la = [ root.nodes[Object.keys(root.nodes)[0]].os.load_average[0] ]; return prev ? la.concat(prev) : la;</code> would return the load average on the first cluster node over the last minute\\\n\t\tThis could be fed into the Graph to produce a load graph for the node\\\n\t\t\"\n});\n\ni18n.setKeys({\n\t\"AnyRequest.DisplayOptionsHelp\" : \"\\\n\t\t<p>Raw Json: shows complete results of the query and transformation in raw JSON format </p>\\\n\t\t<p>Graph Results: To produce a graph of your results, use the result transformer to produce an array of values</p>\\\n\t\t<p>Search Results Table: If your query is a search, you can display the results of the search in a table.</p>\\\n\t\t\"\n});\n\ni18n.setKeys({\n\t\"QueryFilter.DateRangeHelp\" : \"\\\n\t\t<p>Date fields accept a natural language query to produce a From and To date that form a range that the results are queried over.</p>\\\n\t\t<p>The following formats are supported:</p>\\\n\t\t<ul>\\\n\t\t\t<li><b>Keywords / Key Phrases</b><br>\\\n\t\t\t\t<code>now<br> today<br> tomorrow<br> yesterday<br> last / this / next + week / month / year</code><br>\\\n\t\t\t\tsearches for dates matching the keyword. <code>last year</code> would search all of last year.</li>\\\n\t\t\t<li><b>Ranges</b><br>\\\n\t\t\t\t<code>1000 secs<br> 5mins<br> 1day<br> 2days<br> 80d<br> 9 months<br> 2yrs</code> (spaces optional, many synonyms for range qualifiers)<br>\\\n\t\t\t\tCreate a search range centered on <code>now</code> extending into the past and future by the amount specified.</li>\\\n\t\t\t<li><b>DateTime and Partial DateTime</b><br>\\\n\t\t\t\t<code>2011<br> 2011-01<br> 2011-01-18<br> 2011-01-18 12<br> 2011-01-18 12:32<br> 2011-01-18 12:32:45</code><br>\\\n\t\t\t\tthese formats specify a specific date range. <code>2011</code> would search the whole of 2011, while <code>2011-01-18 12:32:45</code> would only search for results in that 1 second range</li>\\\n\t\t\t<li><b>Time and Time Partials</b><br>\\\n\t\t\t\t<code>12<br> 12:32<br> 12:32:45</code><br>\\\n\t\t\t\tthese formats search for a particular time during the current day. <code>12:32</code> would search that minute during today</li>\\\n\t\t\t<li><b>Date Ranges</b><br>\\\n\t\t\t\t<code>2010 -&gt; 2011<br> last week -&gt; next week<br> 2011-05 -&gt;<br> &lt; now</code><br>\\\n\t\t\t\tA Date Range is created by specifying two dates in any format (Keyword / DateTime / Time) separated by &lt; or -&gt; (both do the same thing). If either end of the date range is missing, it is the same as having no constraint in that direction.</li>\\\n\t\t\t<li><b>Date Range using Offset</b><br>\\\n\t\t\t\t<code>2010 -> 1yr<br> 3mins < now</code>\\\n\t\t\t\tSearches the specified date including the range in the direction specified.</li>\\\n\t\t\t<li><b>Anchored Ranges</b><br>\\\n\t\t\t\t<code>2010-05-13 05:13 <> 10m<br> now <> 1yr<br> lastweek <> 1month</code><br>\\\n\t\t\t\tSimilar to above except the range is extend in both directions from the anchor date</li>\\\n\t\t</ul>\\\n\t\"\n});\n"
  },
  {
    "path": "_site/lang/fr_strings.js",
    "content": "i18n.setKeys({\n//\t\"General.Elasticsearch\": \"Elasticsearch\",\n\t\"General.LoadingAggs\" : \"Chargement des facettes...\",\n\t\"General.Searching\": \"Recherche en cours...\",\n\t\"General.Search\": \"Recherche\",\n\t\"General.Help\": \"Aide\",\n//\t\"General.HelpGlyph\": \"?\",\n//\t\"General.CloseGlyph\": \"X\",\n\t\"General.RefreshResults\": \"Rafraîchir\",\n\t\"General.ManualRefresh\": \"Rafraîchissement manuel\",\n\t\"General.RefreshQuickly\": \"Rafraîchissement rapide\",\n\t\"General.Refresh5seconds\": \"Rafraîchissement toutes les 5 secondes\",\n\t\"General.Refresh1minute\": \"Rafraîchissement toutes les minutes\",\n\t\"AliasForm.AliasName\": \"Alias\",\n\t\"AliasForm.NewAliasForIndex\": \"Nouvel Alias pour {0}\",\n\t\"AliasForm.DeleteAliasMessage\": \"Entrez ''{0}'' pour effacer {1}. Attention, action irréversible.\",\n\t\"AnyRequest.DisplayOptions\" : \"Options d'affichage\",\n\t\"AnyRequest.AsGraph\" : \"En graphe\",\n\t\"AnyRequest.AsJson\" : \"En JSON brut\",\n\t\"AnyRequest.AsTable\" : \"En tableau\",\n\t\"AnyRequest.History\" : \"Historique\",\n\t\"AnyRequest.RepeatRequest\" : \"Répétition automatique de la requête\",\n\t\"AnyRequest.RepeatRequestSelect\" : \"Répéter la requête toutes les \",\n\t\"AnyRequest.Transformer\" : \"Transformation des résultats\",\n//\t\"AnyRequest.Pretty\": \"Pretty\",\n\t\"AnyRequest.Query\" : \"Recherche\",\n\t\"AnyRequest.Request\": \"Requête\",\n\t\"AnyRequest.Requesting\": \"Requête en cours...\",\n\t\"AnyRequest.ValidateJSON\": \"Valider le JSON\",\n\t\"Browser.Title\": \"Navigateur\",\n\t\"Browser.ResultSourcePanelTitle\": \"Résultat au format JSON\",\n\t\"Command.DELETE\": \"SUPPRIMER\",\n\t\"Command.SHUTDOWN\": \"ETEINDRE\",\n\t\"Command.DeleteAliasMessage\": \"Supprimer l'Alias?\",\n\t\"ClusterOverView.IndexName\": \"Index\",\n\t\"ClusterOverview.NumShards\": \"Nombre de shards\",\n\t\"ClusterOverview.NumReplicas\": \"Nombre de replica\",\n\t\"ClusterOverview.NewIndex\": \"Nouvel Index\",\n//\t\"IndexActionsMenu.Title\": \"Actions\",\n\t\"IndexActionsMenu.NewAlias\": \"Nouvel Alias...\",\n\t\"IndexActionsMenu.Refresh\": \"Rafraîchir\",\n\t\"IndexActionsMenu.Flush\": \"Flusher\",\n\t\"IndexActionsMenu.Optimize\": \"Optimiser...\",\n\t\"IndexActionsMenu.ForceMerge\": \"ForceMerge...\",\n\t\"IndexActionsMenu.Snapshot\": \"Dupliquer l'index (Snapshot)\",\n\t\"IndexActionsMenu.Analyser\": \"Tester un analyseur\",\n\t\"IndexActionsMenu.Open\": \"Ouvrir\",\n\t\"IndexActionsMenu.Close\": \"Fermer\",\n\t\"IndexActionsMenu.Delete\": \"Effacer...\",\n//\t\"IndexInfoMenu.Title\": \"Info\",\n\t\"IndexInfoMenu.Status\": \"Etat de l'Index\",\n\t\"IndexInfoMenu.Metadata\": \"Métadonnées de l'Index\",\n\t\"IndexCommand.TextToAnalyze\": \"Texte à analyser\",\n\t\"IndexCommand.ShutdownMessage\": \"Entrez ''{0}'' pour éteindre {1}. Le noeud NE PEUT PAS être redémarré depuis cette interface.\",\n//\t\"IndexSelector.NameWithDocs\": \"{0} ({1} docs)\",\n\t\"IndexSelector.SearchIndexForDocs\": \"Chercher dans {0} les documents correspondant à\",\n\t\"FilterBrowser.OutputType\": \"Format d'affichage des résultats {0}\",\n\t\"FilterBrowser.OutputSize\": \"Nombre de Résultats: {0}\",\n\t\"Header.ClusterHealth\": \"Santé du cluster: {0} ({1} {2})\",\n\t\"Header.ClusterNotConnected\": \"Santé du cluster: non connecté\",\n\t\"Header.Connect\": \"Se connecter\",\n\t\"Nav.AnyRequest\": \"Autres requêtes\",\n\t\"Nav.StructuredQuery\": \"Requêtes structurées\",\n\t\"Nav.Browser\": \"Navigateur\",\n\t\"Nav.ClusterHealth\": \"Santé du cluster\",\n\t\"Nav.ClusterState\": \"Etat du cluster\",\n\t\"Nav.ClusterNodes\": \"Noeuds du cluster\",\n//\t\"Nav.Info\": \"Info\",\n\t\"Nav.NodeStats\": \"Statistiques sur les noeuds\",\n\t\"Nav.Overview\": \"Aperçu\",\n\t\"Nav.Indices\": \"Index\",\n\t\"Nav.Plugins\": \"Plugins\",\n\t\"Nav.Status\": \"Etat\",\n\t\"Nav.Templates\": \"Templates\",\n\t\"Nav.StructuredQuery\": \"Recherche Structurée\",\n//\t\"NodeActionsMenu.Title\": \"Actions\",\n\t\"NodeActionsMenu.Shutdown\": \"Eteindre...\",\n//\t\"NodeInfoMenu.Title\": \"Info\",\n\t\"NodeInfoMenu.ClusterNodeInfo\": \"Infos sur le noeud du cluster\",\n\t\"NodeInfoMenu.NodeStats\": \"Statistiques du noeud\",\n\t\"NodeType.Client\": \"Noeud Client\",\n\t\"NodeType.Coord\": \"Coordinateur\",\n\t\"NodeType.Master\": \"Noeud Master\",\n\t\"NodeType.Tribe\": \"Noeud Tribe\",\n\t\"NodeType.Worker\": \"Noeud Worker\",\n\t\"NodeType.Unassigned\": \"Non assigné\",\n\t\"OptimizeForm.OptimizeIndex\": \"Optimiser {0}\",\n\t\"OptimizeForm.MaxSegments\": \"Nombre maximum de segments\",\n\t\"OptimizeForm.ExpungeDeletes\": \"Seulement purger les suppressions\",\n\t\"OptimizeForm.FlushAfter\": \"Flusher après l'optimisation\",\n\t\"OptimizeForm.WaitForMerge\": \"Attendre la fin de la fusion\",\n\t\"ForceMergeForm.ForceMergeIndex\": \"ForceMerge {0}\",\n\t\"ForceMergeForm.MaxSegments\": \"Nombre maximum de segments\",\n\t\"ForceMergeForm.ExpungeDeletes\": \"Seulement purger les suppressions\",\n\t\"ForceMergeForm.FlushAfter\": \"Flusher après ForceMerge\",\n\t\"Overview.PageTitle\" : \"Aperçu du cluster\",\n//\t\"Output.JSON\": \"JSON\",\n\t\"Output.Table\": \"Tableau\",\n\t\"Output.ShowSource\": \"Voir la requête source\",\n    \"TableResults.Summary\": \"Recherche sur {0} des {1} shards. {2} résultats. {3} secondes\",\n\t\"QueryFilter.AllIndices\": \"Tous les index\",\n\t\"QueryFilter.AnyValue\": \"Tout\",\n\t\"QueryFilter-Header-Indices\": \"Index\",\n//\t\"QueryFilter-Header-Types\": \"Types\",\n\t\"QueryFilter-Header-Fields\": \"Champs\",\n\t\"QueryFilter.DateRangeHint.from\": \"De : {0}\",\n\t\"QueryFilter.DateRangeHint.to\": \"  A : {0}\",\n\t\"Query.FailAndUndo\": \"Requête en échec. Annulation des dernières modifications.\",\n\t\"StructuredQuery.ShowRawJson\": \"Voir le JSON brut\"\n});\n\ni18n.setKeys({\n\t\"AnyRequest.TransformerHelp\" : \"\\\n\t\t<p>Le transformateur de résultats peut être utilisé pour modifier a posteriori les résultats JSON bruts dans un format plus utile.</p>\\\n\t\t<p>Le transformateur devrait contenir le corps d'une fonction javascript. La valeur de retour de la fonction devient la nouvelle valeur qui sera passée à l'afficheur des documents JSON.</p>\\\n\t\t<p>Exemple:<br>\\\n\t\t  <code>return root.hits.hits[0];</code> ne renverra que le premier élément de l'ensemble des résultats.<br>\\\n\t\t  <code>return Object.keys(root.nodes).reduce(function(tot, node) { return tot + root.nodes[node].os.mem.used_in_bytes; }, 0);</code> retournera la mémoire totale utilisée dans l'ensemble du cluster.<br></p>\\\n\t\t<p>Les fonctions suivantes sont disponibles et peuvent vous être utiles pour travailler sur les tableaux et les objets:<br>\\\n\t\t<ul>\\\n\t\t\t<li><i>Object.keys</i>(object) := array</li>\\\n\t\t\t<li>array.<i>forEach</i>(function(prop, index))</li>\\\n\t\t\t<li>array.<i>map</i>(function(prop, index)) := array</li>\\\n\t\t\t<li>array.<i>reduce</i>(function(accumulator, prop, index), initial_value) := final_value</li>\\\n\t\t</ul>\\\n\t\t<p>Lorsque vous activez la répétition automatique de la requête, un paramètre supplémentaire nommé prev est passé à la fonction de transformation. Cela permet les comparaisons et les graphes cumulatifs.</p>\\\n\t\t<p>Exemple:<br>\\\n\t\t<code>var la = [ root.nodes[Object.keys(root.nodes)[0]].os.load_average[0] ]; return prev ? la.concat(prev) : la;</code> retournera la charge moyenne du premier noeud du cluster pour la dernière minute écoulée.\\\n\t\tCela peut alimenter ensuite le graphe pour produire un graphe de charge du noeud.\\\n\t\t\"\n});\n\ni18n.setKeys({\n\t\"AnyRequest.DisplayOptionsHelp\" : \"\\\n\t\t<p>En JSON brut: affiche les résultats complets de la recherche éventuellement transformée au format JSON brut.</p>\\\n\t\t<p>En graphe: pour fabriquer un graphe de vos résultats, utilsez la transformation de résultats pour générer un tableau de valeurs.</p>\\\n\t\t<p>En tableau: si votre requête est une recherche, vous pouvez alors afficher les résultats dans un tableau.</p>\\\n\t\t\"\n});\n\ni18n.setKeys({\n\t\"QueryFilter.DateRangeHelp\" : \"\\\n\t\t<p>Les champs Date acceptent une requête en langage naturel pour produire un écart de date (from/to) correspondant.</p>\\\n\t\t<p>Les formats suivants sont acceptés :</p>\\\n\t\t<ul>\\\n\t\t\t<li><b>Mots clés</b><br>\\\n\t\t\t\t<code>now<br> today<br> tomorrow<br> yesterday<br> last / this / next + week / month / year</code><br>\\\n\t\t\t\tCherchera pour des dates correspondant au mot clé. <code>last year</code> cherchera sur toute l'année précédente.</li>\\\n\t\t\t<li><b>Ecarts</b><br>\\\n\t\t\t\t<code>1000 secs<br> 5mins<br> 1day<br> 2days<br> 80d<br> 9 months<br> 2yrs</code> (les espaces sont optionnels et il existe beaucoup de synonymes pour qualifier les écarts)<br>\\\n\t\t\t\tCréé un écart de date basé sur l'heure courante (maintenant) avec plus ou moins l'écart indiqué.</li>\\\n\t\t\t<li><b>Dates et Dates partielles</b><br>\\\n\t\t\t\t<code>2011<br> 2011-01<br> 2011-01-18<br> 2011-01-18 12<br> 2011-01-18 12:32<br> 2011-01-18 12:32:45</code><br>\\\n\t\t\t\tCes formats indiquent un écart de date spécifique. <code>2011</code> cherchera sur toute l'année 2011, alors que <code>2011-01-18 12:32:45</code> ne cherchera que pour la date précise à la seconde près.</li>\\\n\t\t\t<li><b>Heures et heures partielles</b><br>\\\n\t\t\t\t<code>12<br> 12:32<br> 12:32:45</code><br>\\\n\t\t\t\tCes formats indiquent un espace de temps pour la date du jour. <code>12:32</code> cherchera les éléments d'aujourd'hui à cette minute précise.</li>\\\n\t\t\t<li><b>Ecart de Date</b><br>\\\n\t\t\t\t<code>2010 -&gt; 2011<br> last week -&gt; next week<br> 2011-05 -&gt;<br> &lt; now</code><br>\\\n\t\t\t\tUn écart de date est créé en spécifiant deux dates dans n'importe lequel des formats précédents (Mot clé / Dates / Heures) séparées par &lt; ou -&gt; (les deux produisent le même effet). Si la date de fin n'est pas indiquée, alors il n'y aura aucune contrainte de fin.</li>\\\n\t\t\t<li><b>Ecart de date avec décalage</b><br>\\\n\t\t\t\t<code>2010 -> 1yr<br> 3mins < now</code>\\\n\t\t\t\tCherche en incluant un décalage de la date dans la direction indiquée.</li>\\\n\t\t\t<li><b>Ecart de date avec bornes</b><br>\\\n\t\t\t\t<code>2010-05-13 05:13 <> 10m<br> now <> 1yr<br> lastweek <> 1month</code><br>\\\n\t\t\t\tSimilaire à ci-dessus excepté que le décalage est appliqué dans les deux sens à partir de la date indiquée.</li>\\\n\t\t</ul>\\\n\t\"\n});\n"
  },
  {
    "path": "_site/lang/ja_strings.js",
    "content": "i18n.setKeys({\n//\t\"General.Elasticsearch\": \"Elasticsearch\",\n\t\"General.LoadingAggs\": \"Aggregations ロード中...\",\n\t\"General.Searching\": \"検索中...\",\n\t\"General.Search\": \"Search\",\n\t\"General.Help\": \"ヘルプ\",\n//\t\"General.HelpGlyph\": \"?\",\n//\t\"General.CloseGlyph\": \"X\",\n\t\"General.RefreshResults\": \"リフレッシュ\",\n\t\"General.ManualRefresh\": \"マニュアルモード\",\n\t\"General.RefreshQuickly\": \"クイックモード\",\n\t\"General.Refresh5seconds\": \"5秒毎にリフレッシュ\",\n\t\"General.Refresh1minute\": \"1分毎にリフレッシュ\",\n\t\"AliasForm.AliasName\": \"エイリアス名\",\n\t\"AliasForm.NewAliasForIndex\": \"{0} の新しいエイリアス\",\n\t\"AliasForm.DeleteAliasMessage\": \"インデックス ''{1}'' を削除するために ''{0}'' とタイプして下さい. この操作は undo できません.\",\n\t\"AnyRequest.DisplayOptions\" : \"表示オプション\",\n\t\"AnyRequest.AsGraph\" : \"グラフの表示\",\n\t\"AnyRequest.AsJson\" : \"生の JSON を表示\",\n\t\"AnyRequest.AsTable\" : \"テーブルの表示\",\n\t\"AnyRequest.History\" : \"履歴\",\n\t\"AnyRequest.RepeatRequest\" : \"繰り返しリクエストを投げる\",\n\t\"AnyRequest.RepeatRequestSelect\" : \"次の間隔でリクエストを繰り返す\",\n\t\"AnyRequest.Transformer\" : \"Result Transformer\",\n//\t\"AnyRequest.Pretty\": \"Pretty\",\n\t\"AnyRequest.Query\" : \"Query\",\n\t\"AnyRequest.Request\": \"Request\",\n\t\"AnyRequest.Requesting\": \"検索中...\",\n\t\"AnyRequest.ValidateJSON\": \"Validate JSON\",\n\t\"Browser.Title\": \"Browser\",\n\t\"Browser.ResultSourcePanelTitle\": \"Result Source\",\n\t\"Command.DELETE\": \"DELETE\",\n\t\"Command.SHUTDOWN\": \"SHUTDOWN\",\n\t\"Command.DeleteAliasMessage\": \"エイリアスを削除しますか?\",\n\t\"ClusterOverView.IndexName\": \"Index名\",\n\t\"ClusterOverview.NumShards\": \"Number of Shards\",\n\t\"ClusterOverview.NumReplicas\": \"Number of Replicas\",\n\t\"ClusterOverview.NewIndex\": \"インデックスの作成\",\n//\t\"IndexActionsMenu.Title\": \"Actions\",\n\t\"IndexActionsMenu.NewAlias\": \"新しいエイリアス...\",\n\t\"IndexActionsMenu.Refresh\": \"Refresh\",\n\t\"IndexActionsMenu.Flush\": \"Flush\",\n\t\"IndexActionsMenu.Optimize\": \"Optimize...\",\n\t\"IndexActionsMenu.ForceMerge\": \"ForceMerge...\",\n\t\"IndexActionsMenu.Snapshot\": \"Gateway Snapshot\",\n\t\"IndexActionsMenu.Analyser\": \"Analyserテスト\",\n//\t\"IndexActionsMenu.Open\": \"Open\",\n//\t\"IndexActionsMenu.Close\": \"Close\",\n//\t\"IndexActionsMenu.Delete\": \"Delete...\",\n//\t\"IndexInfoMenu.Title\": \"Info\",\n//\t\"IndexInfoMenu.Status\": \"Index Status\",\n//\t\"IndexInfoMenu.Metadata\": \"Index Metadata\",\n\t\"IndexCommand.TextToAnalyze\": \"Analyse するテキストを入力\",\n\t\"IndexCommand.ShutdownMessage\": \" {1} をシャットダウンするために ''{0}'' と入力して下さい. このインターフェースからはリスタートはできません.\",\n\t\"IndexOverview.PageTitle\": \"インデックスのOverview\",\n//\t\"IndexSelector.NameWithDocs\": \"{0} ({1} docs)\",\n\t\"IndexSelector.SearchIndexForDocs\": \"Search {0} for documents where:\",\n\t\"FilterBrowser.OutputType\": \"結果の出力形式: {0} \",\n\t\"FilterBrowser.OutputSize\": \"結果の取得サイズ: {0} \",\n\t\"Header.ClusterHealth\": \"cluster health: {0} ({1} of {2})\",\n\t\"Header.ClusterNotConnected\": \"cluster health: not connected\",\n\t\"Header.Connect\": \"接続\",\n\t\"Nav.AnyRequest\": \"Any Request\",\n\t\"Nav.Browser\": \"Browser\",\n\t\"Nav.ClusterHealth\": \"Cluster Health\",\n\t\"Nav.ClusterState\": \"Cluster State\",\n\t\"Nav.ClusterNodes\": \"Nodes Info\",\n//\t\"Nav.Info\": \"Info\",\n\t\"Nav.NodeStats\": \"Nodes Stats\",\n\t\"Nav.Overview\": \"Overview\",\n\t\"Nav.Indices\": \"Indices\",\n\t\"Nav.Plugins\": \"Plugins\",\n\t\"Nav.Status\": \"Indices Stats\",\n\t\"Nav.Templates\": \"Templates\",\n\t\"Nav.StructuredQuery\": \"Structured Query\",\n//\t\"NodeActionsMenu.Title\": \"Actions\",\n\t\"NodeActionsMenu.Shutdown\": \"シャットダウン...\",\n//\t\"NodeInfoMenu.Title\": \"Info\",\n\t\"NodeInfoMenu.ClusterNodeInfo\": \"Cluster Node Info\",\n//\t\"NodeInfoMenu.NodeStats\": \"Node Stats\",\n\t\"NodeType.Client\": \"Client Node\",\n\t\"NodeType.Coord\": \"Coordinator\",\n\t\"NodeType.Master\": \"Master Node\",\n\t\"NodeType.Tribe\": \"Tribe Node\",\n\t\"NodeType.Worker\": \"Worker Node\",\n\t\"NodeType.Unassigned\": \"Unassigned\",\n\t\"OptimizeForm.OptimizeIndex\": \"Optimize {0}\",\n\t\"OptimizeForm.MaxSegments\": \"Maximum # Of Segments\",\n\t\"OptimizeForm.ExpungeDeletes\": \"Only Expunge Deletes\",\n\t\"OptimizeForm.FlushAfter\": \"Flush After Optimize\",\n\t\"OptimizeForm.WaitForMerge\": \"Wait For Merge\",\n\t\"ForceMergeForm.ForceMergeIndex\": \"ForceMerge {0}\",\n\t\"ForceMergeForm.MaxSegments\": \"Maximum # Of Segments\",\n\t\"ForceMergeForm.ExpungeDeletes\": \"Only Expunge Deletes\",\n\t\"ForceMergeForm.FlushAfter\": \"Flush After ForceMerge\",\n\t\"ForceMergeForm.WaitForMerge\": \"Wait For Merge\",\n\t\"Overview.PageTitle\" : \"クラスタのOverview\",\n//\t\"Output.JSON\": \"JSON\",\n\t\"Output.Table\": \"表\",\n//\t\"Output.CSV\": \"CSV\",\n\t\"Output.ShowSource\": \"Query の source を表示\",\n\t\"Preference.SortCluster\": \"ノードのソート\",\n\t\"Sort.ByName\": \"名前順\",\n\t\"Sort.ByAddress\": \"アドレス順\",\n\t\"Sort.ByType\": \"タイプ順\",\n\t\"Preference.SortIndices\": \"インデックスのソート\",\n\t\"SortIndices.Descending\": \"降順(desc)\",\n\t\"SortIndices.Ascending\": \"昇順(asc)\",\n\t\"Preference.ViewAliases\": \"エイリアスの表示方法\",\n\t\"ViewAliases.Grouped\": \"標準\",\n\t\"ViewAliases.List\": \"リスト形式\",\n\t\"ViewAliases.None\": \"表示しない\",\n\t\"Overview.IndexFilter\": \"インデックスの絞り込み\",\n\t\"TableResults.Summary\": \"検索結果: {0} / {1} シャード. {2} ヒット. {3} 秒\",\n\t\"QueryFilter.AllIndices\": \"全インデックス\",\n\t\"QueryFilter.AnyValue\": \"any\",\n\t\"QueryFilter-Header-Indices\": \"Indices\",\n//\t\"QueryFilter-Header-Types\": \"Types\",\n\t\"QueryFilter-Header-Fields\": \"Fields\",\n\t\"QueryFilter.DateRangeHint.from\": \"From : {0}\",\n\t\"QueryFilter.DateRangeHint.to\": \"  To : {0}\",\n\t\"Query.FailAndUndo\": \"Query Failed. Undoing last changes\",\n\t\"StructuredQuery.ShowRawJson\": \"生の JSON を表示する\"\n});\n\ni18n.setKeys({\n\t\"AnyRequest.TransformerHelp\" : \"\\\n\t\t<p>Result Transformer は、ESから返ってきた JSON をより使いやすい形式に変換することができます.</p>\\\n\t\t<p>transformer には javascript の function の中身を記述します. 戻り値の新しい JSON が画面出力されます.</p>\\\n\t\t<p>例:<br>\\\n\t\t  <code>return root.hits.hits[0];</code> 検索結果の最初のドキュメントだけを表示するように JSON をトラバースする例<br>\\\n\t\t  <code>return Object.keys(root.nodes).reduce(function(tot, node) { return tot + root.nodes[node].os.mem.used_in_bytes; }, 0);</code> クラスタ全体でのトータル使用メモリを返す例<br></p>\\\n\t\t<p>以下の関数は、配列やオブジェクトを扱うのに便利です<br>\\\n\t\t<ul>\\\n\t\t\t<li><i>Object.keys</i>(object) := array</li>\\\n\t\t\t<li>array.<i>forEach</i>(function(prop, index))</li>\\\n\t\t\t<li>array.<i>map</i>(function(prop, index)) := array</li>\\\n\t\t\t<li>array.<i>reduce</i>(function(accumulator, prop, index), initial_value) := final_value</li>\\\n\t\t</ul>\\\n\t\t<p>繰り返しリクエストを投げた時, prev 引数に前の戻り値が入ります. 比較や、累積グラフの作成などに利用できます.</p>\\\n\t\t<p>例:<br>\\\n\t\t<code>var la = [ root.nodes[Object.keys(root.nodes)[0]].os.load_average[0] ]; return prev ? la.concat(prev) : la;</code> 最初のノードの load_average を配列で返します.\\\n\t\tこの配列をグラフの入力値に用いることで load_average の遷移をグラフとして視覚化することができます.\\\n\t\t\"\n});\n\ni18n.setKeys({\n\t\"AnyRequest.DisplayOptionsHelp\" : \"\\\n\t\t<p>生の JSON の表示: 検索結果を生の JSON で表示します </p>\\\n\t\t<p>グラフの表示: 検索結果をグラフで表示します. Result Transformer を使って、配列の値に変換する必要があります</p>\\\n\t\t<p>表の表示: 検索クエリの場合には、結果を表形式で表示できます</p>\\\n\t\t\"\n});\n\n//i18n.setKeys({\n//\t\"QueryFilter.DateRangeHelp\" : \"\\\n//\t\t<p>Date fields accept a natural language query to produce a From and To date that form a range that the results are queried over.</p>\\\n//\t\t<p>The following formats are supported:</p>\\\n//\t\t<ul>\\\n//\t\t\t<li><b>Keywords / Key Phrases</b><br>\\\n//\t\t\t\t<code>now<br> today<br> tomorrow<br> yesterday<br> last / this / next + week / month / year</code><br>\\\n//\t\t\t\tsearches for dates matching the keyword. <code>last year</code> would search all of last year.</li>\\\n//\t\t\t<li><b>Ranges</b><br>\\\n//\t\t\t\t<code>1000 secs<br> 5mins<br> 1day<br> 2days<br> 80d<br> 9 months<br> 2yrs</code> (spaces optional, many synonyms for range qualifiers)<br>\\\n//\t\t\t\tCreate a search range centered on <code>now</code> extending into the past and future by the amount specified.</li>\\\n//\t\t\t<li><b>DateTime and Partial DateTime</b><br>\\\n//\t\t\t\t<code>2011<br> 2011-01<br> 2011-01-18<br> 2011-01-18 12<br> 2011-01-18 12:32<br> 2011-01-18 12:32:45</code><br>\\\n//\t\t\t\tthese formats specify a specific date range. <code>2011</code> would search the whole of 2011, while <code>2011-01-18 12:32:45</code> would only search for results in that 1 second range</li>\\\n//\t\t\t<li><b>Time and Time Partials</b><br>\\\n//\t\t\t\t<code>12<br> 12:32<br> 12:32:45</code><br>\\\n//\t\t\t\tthese formats search for a particular time during the current day. <code>12:32</code> would search that minute during today</li>\\\n//\t\t\t<li><b>Date Ranges</b><br>\\\n//\t\t\t\t<code>2010 -&gt; 2011<br> last week -&gt; next week<br> 2011-05 -&gt;<br> &lt; now</code><br>\\\n//\t\t\t\tA Date Range is created by specifying two dates in any format (Keyword / DateTime / Time) separated by &lt; or -&gt; (both do the same thing). If either end of the date range is missing, it is the same as having no constraint in that direction.</li>\\\n//\t\t\t<li><b>Date Range using Offset</b><br>\\\n//\t\t\t\t<code>2010 -> 1yr<br> 3mins < now</code>\\\n//\t\t\t\tSearches the specified date including the range in the direction specified.</li>\\\n//\t\t\t<li><b>Anchored Ranges</b><br>\\\n//\t\t\t\t<code>2010-05-13 05:13 <> 10m<br> now <> 1yr<br> lastweek <> 1month</code><br>\\\n//\t\t\t\tSimilar to above except the range is extend in both directions from the anchor date</li>\\\n//\t\t</ul>\\\n//\t\"\n//});\n"
  },
  {
    "path": "_site/lang/pt_strings.js",
    "content": "i18n.setKeys({\n\t\"General.Elasticsearch\": \"Elasticsearch\",\n\t\"General.LoadingAggs\": \"Carregando Facetas...\",\n\t\"General.Searching\": \"Buscando...\",\n\t\"General.Search\": \"Busca\",\n\t\"General.Help\": \"Ajuda\",\n\t\"General.HelpGlyph\": \"?\",\n\t\"General.CloseGlyph\": \"X\",\n\t\"General.RefreshResults\": \"Atualizar\",\n\t\"General.ManualRefresh\": \"Atualização Manual\",\n\t\"General.RefreshQuickly\": \"Atualização rápida\",\n\t\"General.Refresh5seconds\": \"Atualização a cada 5 segundos\",\n\t\"General.Refresh1minute\": \"Atualização a cada minuto\",\n\t\"AliasForm.AliasName\": \"Apelido\",\n\t\"AliasForm.NewAliasForIndex\": \"Novo apelido para {0}\",\n\t\"AliasForm.DeleteAliasMessage\": \"digite ''{0}'' para deletar {1}. Não há como voltar atrás\",\n\t\"AnyRequest.DisplayOptions\" : \"Mostrar Opções\",\n\t\"AnyRequest.AsGraph\" : \"Mostrar como gráfico\",\n\t\"AnyRequest.AsJson\" : \"Mostrar JSON bruto\",\n\t\"AnyRequest.AsTable\" : \"Mostrar tabela de resultados da consulta\",\n\t\"AnyRequest.History\" : \"Histórico\",\n\t\"AnyRequest.RepeatRequest\" : \"Refazer requisição\",\n\t\"AnyRequest.RepeatRequestSelect\" : \"Repetir requisição a cada \",\n\t\"AnyRequest.Transformer\" : \"Transformador de resultado\",\n\t\"AnyRequest.Pretty\": \"Amigável\",\n\t\"AnyRequest.Query\" : \"Consulta\",\n\t\"AnyRequest.Request\": \"Requisição\",\n\t\"AnyRequest.Requesting\": \"Realizando requisição...\",\n\t\"AnyRequest.ValidateJSON\": \"Validar JSON\",\n\t\"Browser.Title\": \"Navegador\",\n\t\"Browser.ResultSourcePanelTitle\": \"Resultado\",\n\t\"Command.DELETE\": \"DELETAR\",\n\t\"Command.SHUTDOWN\": \"DESLIGAR\",\n\t\"Command.DeleteAliasMessage\": \"Remover apelido?\",\n\t\"ClusterOverView.IndexName\": \"Nome do índice\",\n\t\"ClusterOverview.NumShards\": \"Número de Shards\",\n\t\"ClusterOverview.NumReplicas\": \"Número de Réplicas\",\n\t\"ClusterOverview.NewIndex\": \"Novo índice\",\n\t\"IndexActionsMenu.Title\": \"Ações\",\n\t\"IndexActionsMenu.NewAlias\": \"Novo apelido...\",\n\t\"IndexActionsMenu.Refresh\": \"Atualizar\",\n\t\"IndexActionsMenu.Flush\": \"Flush\",\n\t\"IndexActionsMenu.Optimize\": \"Otimizar...\",\n\t\"IndexActionsMenu.ForceMerge\": \"ForceMerge...\",\n\t\"IndexActionsMenu.Snapshot\": \"Snapshot do Gateway\",\n\t\"IndexActionsMenu.Analyser\": \"Analizador de teste\",\n\t\"IndexActionsMenu.Open\": \"Abrir\",\n\t\"IndexActionsMenu.Close\": \"Fechar\",\n\t\"IndexActionsMenu.Delete\": \"Deletar...\",\n\t\"IndexInfoMenu.Title\": \"Info\",\n\t\"IndexInfoMenu.Status\": \"Status do índice\",\n\t\"IndexInfoMenu.Metadata\": \"Metadados do índice\",\n\t\"IndexCommand.TextToAnalyze\": \"Texto para analizar\",\n\t\"IndexCommand.ShutdownMessage\": \"digite ''{0}'' para desligar {1}. Nó NÃO PODE ser reiniciado à partir dessa interface\",\n\t\"IndexOverview.PageTitle\": \"Visão geral dos índices\",\n\t\"IndexSelector.NameWithDocs\": \"{0} ({1} documentoss)\",\n\t\"IndexSelector.SearchIndexForDocs\": \"Busca {0} por documentos onde:\",\n\t\"FilterBrowser.OutputType\": \"Resultados: {0}\",\n\t\"FilterBrowser.OutputSize\": \"Número de Resultados: {0}\",\n\t\"Header.ClusterHealth\": \"saúde do cluster: {0} ({1} {2})\",\n\t\"Header.ClusterNotConnected\": \"saúde do cluster: não conectado\",\n\t\"Header.Connect\": \"Conectar\",\n\t\"Nav.AnyRequest\": \"Qualquer requisição\",\n\t\"Nav.Browser\": \"Navegador\",\n\t\"Nav.ClusterHealth\": \"Saúde do Cluster\",\n\t\"Nav.ClusterState\": \"Estado do Cluster\",\n\t\"Nav.ClusterNodes\": \"Nós do Cluster\",\n\t\"Nav.Info\": \"Informações\",\n\t\"Nav.NodeStats\": \"Estatísticas do nó\",\n\t\"Nav.Overview\": \"Visão Geral\",\n\t\"Nav.Indices\": \"Índices\",\n\t\"Nav.Plugins\": \"Plugins\",\n\t\"Nav.Status\": \"Status\",\n\t\"Nav.Templates\": \"Modelos\",\n\t\"Nav.StructuredQuery\": \"Consulta Estruturada\",\n\t\"NodeActionsMenu.Title\": \"Ações\",\n\t\"NodeActionsMenu.Shutdown\": \"Desligar...\",\n\t\"NodeInfoMenu.Title\": \"Informações\",\n\t\"NodeInfoMenu.ClusterNodeInfo\": \"Informações do Nó do Cluster\",\n\t\"NodeInfoMenu.NodeStats\": \"Estatísticas do Nó\",\n\t\"NodeType.Client\": \"Nó cliente\",\n\t\"NodeType.Coord\": \"Coordenador\",\n\t\"NodeType.Master\": \"Nó mestre\",\n\t\"NodeType.Tribe\": \"Nó tribo\",\n\t\"NodeType.Worker\": \"Nó trabalhador\",\n\t\"NodeType.Unassigned\": \"Não atribuido\",\n\t\"OptimizeForm.OptimizeIndex\": \"Otimizar {0}\",\n\t\"OptimizeForm.MaxSegments\": \"# Máximo De Segmentos\",\n\t\"OptimizeForm.ExpungeDeletes\": \"Apenas Expurgar Exclusões\",\n\t\"OptimizeForm.FlushAfter\": \"Flush após Otimizar\",\n\t\"OptimizeForm.WaitForMerge\": \"Esperar Por Merge\",\n\t\"ForceMergeForm.ForceMergeIndex\": \"ForceMerge {0}\",\n\t\"ForceMergeForm.MaxSegments\": \"# Máximo De Segmentos\",\n\t\"ForceMergeForm.ExpungeDeletes\": \"Apenas Expurgar Exclusões\",\n\t\"ForceMergeForm.FlushAfter\": \"Flush após ForceMerge\",\n\t\"Overview.PageTitle\": \"Visão geral do Cluster\",\n\t\"Output.JSON\": \"JSON\",\n\t\"Output.Table\": \"Tabela\",\n\t\"Output.CSV\": \"CSV\",\n\t\"Output.ShowSource\": \"Mostrar consulta original\",\n\t\"Preference.SortCluster\": \"Ordenar Cluster\",\n\t\"Sort.ByName\": \"Por nome\",\n\t\"Sort.ByAddress\": \"Por endereço\",\n\t\"Sort.ByType\": \"Por tipo\",\n\t\"Preference.ViewAliases\": \"Ver Alias\",\n\t\"ViewAliases.Grouped\": \"Agrupado\",\n\t\"ViewAliases.List\": \"Lista\",\n\t\"ViewAliases.None\": \"Nenhum\",\n\t\"Overview.IndexFilter\": \"Filtar Índice\",\n\t\"TableResults.Summary\": \"Buscado {0} de {1} shards. {2} resultados. {3} segundos\",\n\t\"QueryFilter.AllIndices\": \"Todos os Índices\",\n\t\"QueryFilter.AnyValue\": \"qualquer\",\n\t\"QueryFilter-Header-Indices\": \"Índices\",\n\t\"QueryFilter-Header-Types\": \"Tipos\",\n\t\"QueryFilter-Header-Fields\": \"Campos\",\n\t\"QueryFilter.DateRangeHint.from\": \"De : {0}\",\n\t\"QueryFilter.DateRangeHint.to\": \"  A : {0}\",\n\t\"Query.FailAndUndo\": \"Consulta falhou. Desfazendo últimas alterações\",\n\t\"StructuredQuery.ShowRawJson\": \"Mostrar JSON bruto\"\n});\n\ni18n.setKeys({\n\t\"AnyRequest.TransformerHelp\" : \"\\\n\t\t<p>O Transformador de Resultados pode ser usado para transformar os resultados de uma consulta de json bruto para um formato mais útil.</p>\\\n\t\t<p>O transformador deve possuir o corpo de uma função javascript. O retorno da função se torna o novo valor passado para o json printer</p>\\\n\t\t<p>Exemplo:<br>\\\n\t\t  <code>return root.hits.hits[0];</code> irá alterar a resposta para mostrar apenas o primeiro resultado<br>\\\n\t\t  <code>return Object.keys(root.nodes).reduce(function(tot, node) { return tot + root.nodes[node].os.mem.used_in_bytes; }, 0);</code> irá retornar o total de memória utilizada pelo cluster<br></p>\\\n\t\t<p>As seguintes funções estão disponíveis e podem ser úteis no processamento de vetores e objetos<br>\\\n\t\t<ul>\\\n\t\t\t<li><i>Object.keys</i>(object) := array</li>\\\n\t\t\t<li>array.<i>forEach</i>(function(prop, index))</li>\\\n\t\t\t<li>array.<i>map</i>(function(prop, index)) := array</li>\\\n\t\t\t<li>array.<i>reduce</i>(function(accumulator, prop, index), initial_value) := final_value</li>\\\n\t\t</ul>\\\n\t\t<p>Durante a execução da opção Refazer Requisição, um parâmetro extra chamado prev é passado para a função de transformação. Isso permite fazer comparações e marcações cumulativas</p>\\\n\t\t<p>Exemplo:<br>\\\n\t\t<code>var la = [ root.nodes[Object.keys(root.nodes)[0]].os.load_average[0] ]; return prev ? la.concat(prev) : la;</code> irá retornar a carga média no primeiro nó do cluster no último minuto\\\n\t\tEssa informação pode ser inserida no Gráfico para fazer um gráfico de carga do nó\\\n\t\t\"\n});\n\ni18n.setKeys({\n\t\"AnyRequest.DisplayOptionsHelp\" : \"\\\n\t\t<p>Json Bruto: Exibe o resultado completo da consulta e da transformação no formato de JSON bruto</p>\\\n\t\t<p>Gráfico de Resultados: Para gerar um gráfico com seus resultados, utilize o tranformador de resultados para produzir um vetor de valores</p>\\\n\t\t<p>Tabela de Resultados da Consulta: Se sua consulta for uma busca, você pode exibir seus resultados no formato de uma tabela.</p>\\\n\t\t\"\n});\n\ni18n.setKeys({\n\t\"QueryFilter.DateRangeHelp\" : \"\\\n\t\t<p>Campos do tipo Data aceitam consultas em linguagem natural (em inglês) para produzir um <i>From</i> e um <i>To</i> de modo a formar um intervalo dentro do qual os resultados são filtrados.</p>\\\n\t\t<p>Os seguintes formatos são suportados:</p>\\\n\t\t<ul>\\\n\t\t\t<li><b>Palavras-chave</b><br>\\\n\t\t\t\t<code>now<br> today<br> tomorrow<br> yesterday<br> last / this / next + week / month / year</code><br>\\\n\t\t\t\tbuscam por datas de acordo com a palavra-chave. <code>last year</code> irá buscar tudo do último ano.</li>\\\n\t\t\t<li><b>Intervalos</b><br>\\\n\t\t\t\t<code>1000 secs<br> 5mins<br> 1day<br> 2days<br> 80d<br> 9 months<br> 2yrs</code> (espaços são opcionais, diversos sinônimos para qualificadores de intervalo)<br>\\\n\t\t\t\tCria um intervalo de busca a partir de agora (<code>now</code>), extendendo este intervalo no passado e no futuro de acordo com intervalo especificado.</li>\\\n\t\t\t<li><b>Data/Hora (<i>DateTime</i>) e Data/Hora parcial</b><br>\\\n\t\t\t\t<code>2011<br> 2011-01<br> 2011-01-18<br> 2011-01-18 12<br> 2011-01-18 12:32<br> 2011-01-18 12:32:45</code><br>\\\n\t\t\t\tesses formatos especificam um intervalo especifico. <code>2011</code> irá buscar todo o ano de 2011, enquanto <code>2011-01-18 12:32:45</code> irá buscar apenas por resultados dentro deste intervalo de 1 segundo</li>\\\n\t\t\t<li><b>Tempo (<i>Time</i>) e Tempo parcial</b><br>\\\n\t\t\t\t<code>12<br> 12:32<br> 12:32:45</code><br>\\\n\t\t\t\tesses formatos buscam por um horário específico no dia atual. <code>12:32</code> irá buscar este minuto específico do dia</li>\\\n\t\t\t<li><b>Intervalos de Data</b><br>\\\n\t\t\t\t<code>2010 -&gt; 2011<br> last week -&gt; next week<br> 2011-05 -&gt;<br> &lt; now</code><br>\\\n\t\t\t\tUm intervalo de data é criado especificando-se duas datas em qualquer formato (Palavras-chave, Data/Hora ou Tempo) separados por &lt; ou -&gt; (ambos fazem a mesma coisa). Se a data de início ou fim do intervalo não for especificada é a mesma coisa que não impor limites na busca nesta direção.</li>\\\n\t\t\t<li><b>Intervalo de Data com Deslocamento</b><br>\\\n\t\t\t\t<code>2010 -> 1yr<br> 3mins < now</code>\\\n\t\t\t\tBusca a data especificada incluindo o intervalo na direção determinada pelo deslocamento</li>\\\n\t\t\t<li><b>Intervalos Bidirecionais</b><br>\\\n\t\t\t\t<code>2010-05-13 05:13 <> 10m<br> now <> 1yr<br> lastweek <> 1month</code><br>\\\n\t\t\t\tIdêntico ao exemplo anterior porém o intervalo é extendido em ambas as direções a partir da data especificada</li>\\\n\t\t</ul>\\\n\t\"\n});\n"
  },
  {
    "path": "_site/lang/tr_strings.js",
    "content": "i18n.setKeys({\r\n\t\"General.Elasticsearch\": \"Elasticsearch\",\r\n\t\"General.LoadingAggs\": \"Gruplar Yükleniyor...\",\r\n\t\"General.Searching\": \"Aranıyor...\",\r\n\t\"General.Search\": \"Ara\",\r\n\t\"General.Help\": \"Yardım\",\r\n\t\"General.HelpGlyph\": \"?\",\r\n\t\"General.CloseGlyph\": \"X\",\r\n\t\"General.RefreshResults\": \"Yenile\",\r\n\t\"General.ManualRefresh\": \"Manuel Yenileme\",\r\n\t\"General.RefreshQuickly\": \"Hızlı yenile\",\r\n\t\"General.Refresh5seconds\": \"5 saniyede bir yenile\",\r\n\t\"General.Refresh1minute\": \"Her dakika yenile\",\r\n\t\"AliasForm.AliasName\": \"Alternatif İsim\",\r\n\t\"AliasForm.NewAliasForIndex\": \"{0} için yeni alternatif isim\",\r\n\t\"AliasForm.DeleteAliasMessage\": \"{1} silmek için ''{0}'' . Geriye dönüş yoktur.\",\r\n\t\"AnyRequest.DisplayOptions\" : \"Seçenekleri Göster\",\r\n\t\"AnyRequest.AsGraph\" : \"Sonuçları Çizdir\",\r\n\t\"AnyRequest.AsJson\" : \"JSON formatında göster\",\r\n\t\"AnyRequest.AsTable\" : \"Arama sonuçlarını tablo halinde göster\",\r\n\t\"AnyRequest.History\" : \"Geçmiş\",\r\n\t\"AnyRequest.RepeatRequest\" : \"İsteği Tekrarla\",\r\n\t\"AnyRequest.RepeatRequestSelect\" : \"İsteği sürekli tekrarla \",\r\n\t\"AnyRequest.Transformer\" : \"Sonuç Dönüştürücü\",\r\n\t\"AnyRequest.Pretty\": \"Düzenli\",\r\n\t\"AnyRequest.Query\" : \"Sorgu\",\r\n\t\"AnyRequest.Request\": \"Gönder\",\r\n\t\"AnyRequest.Requesting\": \"İsteniyor...\",\r\n\t\"AnyRequest.ValidateJSON\": \"JSON Doğrula\",\r\n\t\"Browser.Title\": \"Browser\",\r\n\t\"Browser.ResultSourcePanelTitle\": \"Sonuç Kaynağı\",\r\n\t\"Command.DELETE\": \"SİL\",\r\n\t\"Command.SHUTDOWN\": \"KAPA\",\r\n\t\"Command.DeleteAliasMessage\": \"Alternatif ismi sil?\",\r\n\t\"ClusterOverView.IndexName\": \"Indeks İsmi\",\r\n\t\"ClusterOverview.NumShards\": \"Sektör Sayısı\",\r\n\t\"ClusterOverview.NumReplicas\": \"Yedek Sayısı\",\r\n\t\"ClusterOverview.NewIndex\": \"Yeni Indeks\",\r\n\t\"IndexActionsMenu.Title\": \"İşlemler\",\r\n\t\"IndexActionsMenu.NewAlias\": \"Yeni Alternatif İsim...\",\r\n\t\"IndexActionsMenu.Refresh\": \"Yenile\",\r\n\t\"IndexActionsMenu.Flush\": \"Boşalt\",\r\n\t\"IndexActionsMenu.Optimize\": \"Optimize et...\",\r\n\t\"IndexActionsMenu.ForceMerge\": \"ForceMerge et...\",\r\n\t\"IndexActionsMenu.Snapshot\": \"Gateway Snapshot (Kopya Al)\",\r\n\t\"IndexActionsMenu.Analyser\": \"Analizi test et\",\r\n\t\"IndexActionsMenu.Open\": \"Aç\",\r\n\t\"IndexActionsMenu.Close\": \"Kapa\",\r\n\t\"IndexActionsMenu.Delete\": \"Sil...\",\r\n\t\"IndexInfoMenu.Title\": \"Bilgi\",\r\n\t\"IndexInfoMenu.Status\": \"Indeks Durumu\",\r\n\t\"IndexInfoMenu.Metadata\": \"Indeks Metaveri\",\r\n\t\"IndexCommand.TextToAnalyze\": \"Analiz edilecek metin\",\r\n\t\"IndexCommand.ShutdownMessage\": \"{1} kapatmak için ''{0}'' yazın . Nod bu arayüzden tekrar BAŞLATILAMAZ\",\r\n\t\"IndexOverview.PageTitle\": \"Indeksler Genel Bakış\",\r\n\t\"IndexSelector.NameWithDocs\": \"{0} ({1} döküman)\",\r\n\t\"IndexSelector.SearchIndexForDocs\": \"{0} indeksinde ara:\",\r\n\t\"FilterBrowser.OutputType\": \"Sonuç Formatı: {0}\",\r\n\t\"FilterBrowser.OutputSize\": \"Sonuç Sayısı: {0}\",\r\n\t\"Header.ClusterHealth\": \"Küme Durumu: {0} ({1} de {2})\",\r\n\t\"Header.ClusterNotConnected\": \"Küme Durumu: Bağlı Değil\",\r\n\t\"Header.Connect\": \"Bağlan\",\r\n\t\"Nav.AnyRequest\": \"Özel Sorgu\",\r\n\t\"Nav.Browser\": \"Görüntüle\",\r\n\t\"Nav.ClusterHealth\": \"Küme Durumu\",\r\n\t\"Nav.ClusterState\": \"Küme Statüsü\",\r\n\t\"Nav.ClusterNodes\": \"Nod Bilgileri\",\r\n\t\"Nav.Info\": \"Bilgi\",\r\n\t\"Nav.NodeStats\": \"Nod İstatistikleri\",\r\n\t\"Nav.Overview\": \"Genel Bakış\",\r\n\t\"Nav.Indices\": \"Indeksler\",\r\n\t\"Nav.Plugins\": \"Eklentiler\",\r\n\t\"Nav.Status\": \"Indeks İstatistikleri\",\r\n\t\"Nav.Templates\": \"Şablonlar\",\r\n\t\"Nav.StructuredQuery\": \"Yapılandırılmış Sorgu\",\r\n\t\"NodeActionsMenu.Title\": \"İşlemler\",\r\n\t\"NodeActionsMenu.Shutdown\": \"Kapat...\",\r\n\t\"NodeInfoMenu.Title\": \"Bilgi\",\r\n\t\"NodeInfoMenu.ClusterNodeInfo\": \"Küme Nod Bilgileri\",\r\n\t\"NodeInfoMenu.NodeStats\": \"Nod İstatistikleri\",\r\n\t\"NodeType.Client\": \"Client Nod\",\r\n\t\"NodeType.Coord\": \"Coordinator\",\r\n\t\"NodeType.Master\": \"Master Nod\",\r\n\t\"NodeType.Tribe\": \"Tribe Nod\",\r\n\t\"NodeType.Worker\": \"Worker Nod\",\r\n\t\"NodeType.Unassigned\": \"Sahipsiz\",\r\n\t\"OptimizeForm.OptimizeIndex\": \"{0} Optimize Et\",\r\n\t\"OptimizeForm.MaxSegments\": \"Maksimum Segment Sayısı\",\r\n\t\"OptimizeForm.ExpungeDeletes\": \"Silme İşlemi Artıklarını Temizle\",\r\n\t\"OptimizeForm.FlushAfter\": \"Optimize Ettikten Sonra Boşalt\",\r\n\t\"OptimizeForm.WaitForMerge\": \"Birleştirme İçin Bekle\",\r\n\t\"ForceMergeForm.ForceMergeIndex\": \"{0} ForceMerge Et\",\r\n\t\"ForceMergeForm.MaxSegments\": \"Maksimum Segment Sayısı\",\r\n\t\"ForceMergeForm.ExpungeDeletes\": \"Silme İşlemi Artıklarını Temizle\",\r\n\t\"ForceMergeForm.FlushAfter\": \"ForceMerge Ettikten Sonra Boşalt\",\r\n\t\"ForceMergeForm.WaitForMerge\": \"Birleştirme İçin Bekle\",\r\n\t\"Overview.PageTitle\" : \"Kümeler Genelbakış\",\r\n\t\"Output.JSON\": \"JSON\",\r\n\t\"Output.Table\": \"Tablo\",\r\n\t\"Output.CSV\": \"CSV\",\r\n\t\"Output.ShowSource\": \"Sorgu kaynağını göster\",\r\n\t\"Preference.SortCluster\": \"Kümeyi Sırala\",\r\n\t\"Sort.ByName\": \"İsme göre\",\r\n\t\"Sort.ByAddress\": \"Adrese göre\",\r\n\t\"Sort.ByType\": \"Tipe göre\",\r\n\t\"Preference.SortIndices\": \"Indeksleri sırala\",\r\n\t\"SortIndices.Descending\": \"Azalan\",\r\n\t\"SortIndices.Ascending\": \"Artan\",\r\n\t\"Preference.ViewAliases\": \"Alternatif isimleri görüntüle\",\r\n\t\"ViewAliases.Grouped\": \"Gruplanmış\",\r\n\t\"ViewAliases.List\": \"Liste\",\r\n\t\"ViewAliases.None\": \"Karışık\",\r\n\t\"Overview.IndexFilter\": \"Indeks Filtresi\",\r\n\t\"TableResults.Summary\": \"{0} parçanın {1} tanesi arandı. {2} sonuç. {3} saniye\",\r\n\t\"QueryFilter.AllIndices\": \"Tüm Indeksler\",\r\n\t\"QueryFilter.AnyValue\": \"herhangi\",\r\n\t\"QueryFilter-Header-Indices\": \"Indeksler\",\r\n\t\"QueryFilter-Header-Types\": \"Tipler\",\r\n\t\"QueryFilter-Header-Fields\": \"Alanlar\",\r\n\t\"QueryFilter.DateRangeHint.from\": \"{0}'dan\",\r\n\t\"QueryFilter.DateRangeHint.to\": \"  {0}'a\",\r\n\t\"Query.FailAndUndo\": \"Sorgu Başarısız. Son değişiklikler geri alınıyor.\",\r\n\t\"StructuredQuery.ShowRawJson\": \"Formatsız JSON göster\"\r\n});\r\n\r\ni18n.setKeys({\r\n\t\"AnyRequest.TransformerHelp\" : \"\\\r\n\t\t<p>Sonuç Dönüştürücü sorgudan dönen JSON sonuçlarını işleyip daha kullanışlı bir formata dönüştürmek için kullanılabilir.</p>\\\r\n\t\t<p>Dönüştürücü içierisinde javascript fonksiyonu tanımlanmalıdır. Bu fonksiyondan dönen yeni sonuç çıktı kısmına yazdırılır.</p>\\\r\n\t\t<p>Örnek:<br>\\\r\n\t\t  <code>return root.hits.hits[0];</code> sonucu dolaşarak ilk eşleşmeyi göster<br>\\\r\n\t\t  <code>return Object.keys(root.nodes).reduce(function(tot, node) { return tot + root.nodes[node].os.mem.used_in_bytes; }, 0);</code> tüm kümede kullanılan toplam belleği gösterir<br></p>\\\r\n\t\t<p>Aşağıdaki fonksiyonlar dizi ve objelerin işlenmesinde yardımcı olması için kullanılabilir<br>\\\r\n\t\t<ul>\\\r\n\t\t\t<li><i>Object.keys</i>(object) := array</li>\\\r\n\t\t\t<li>array.<i>forEach</i>(function(prop, index))</li>\\\r\n\t\t\t<li>array.<i>map</i>(function(prop, index)) := array</li>\\\r\n\t\t\t<li>array.<i>reduce</i>(function(accumulator, prop, index), initial_value) := final_value</li>\\\r\n\t\t</ul>\\\r\n\t\t<p>Sorgu tekrarlama çalışırken, prev isimli ekstra bir parametre dönüştürücü fonksiyonuna verilir. Bu sayede karşılaştırmalar ve toplu grafik gösterimleri yapılabilir.</p>\\\r\n\t\t<p>Örnek:<br>\\\r\n\t\t<code>var la = [ root.nodes[Object.keys(root.nodes)[0]].os.load_average[0] ]; return prev ? la.concat(prev) : la;</code> önceki dakika boyunca kümede bulunan ilk nod üzerindeki averaj yükü verir.\\\r\n\t\tBu sonuç nod için yük grafiği yaratılmasında kullanılabilir.\\\r\n\t\t\"\r\n});\r\n\r\ni18n.setKeys({\r\n\t\"AnyRequest.DisplayOptionsHelp\" : \"\\\r\n\t\t<p>Sade Json: Sorgunun tüm sonuçlarını ve (yapıldıysa) dönüştürüldükten sonraki halini sade JSON formatında gösterir </p>\\\r\n\t\t<p>Sonuçları Çizdir: Sonuçları grafiksel olarak görüntülemek için sonuç dörücüyü kullanarak değerleri dizi haline getirin.</p>\\\r\n\t\t<p>Arama Sonuçları Tablosu: Eğer sorgunuz bir arama ise, sonuçları bir tabloda görüntüleyebilirsiniz.</p>\\\r\n\t\t\"\r\n});\r\n\r\ni18n.setKeys({\r\n\t\"QueryFilter.DateRangeHelp\" : \"\\\r\n\t\t<p>Tarih alanları ana dile yakın kelimeler kullanarak iki tarih aralığında sorgu yapılabilmesini sağlar.</p>\\\r\n\t\t<p>Aşağıdaki tanımlar kullanılabilir:</p>\\\r\n\t\t<ul>\\\r\n\t\t\t<li><b>Anahtar Kelimeler</b><br>\\\r\n\t\t\t\t<code>now<br> today<br> tomorrow<br> yesterday<br> last / this / next + week / month / year</code><br>\\\r\n\t\t\t\tkelimeleri eşleşen tarihleri verir. Örneğin <code>last year</code> geçen yıl tarihli bütün verileri döndürür.</li>\\\r\n\t\t\t<li><b>Aralıklar</b><br>\\\r\n\t\t\t\t<code>1000 secs<br> 5mins<br> 1day<br> 2days<br> 80d<br> 9 months<br> 2yrs</code> (boşluklar isteğe bağlıdır, ayni kelime için farklı yazım şekilleri kullanılabilir)<br>\\\r\n\t\t\t\tŞu anki tarihi (<code>now</code>) baz alarak geçmiş veya ileriki bir tarih aralığındaki kayıtları verir.</li>\\\r\n\t\t\t<li><b>Tarih ve Kısmi Tarihler</b><br>\\\r\n\t\t\t\t<code>2011<br> 2011-01<br> 2011-01-18<br> 2011-01-18 12<br> 2011-01-18 12:32<br> 2011-01-18 12:32:45</code><br>\\\r\n\t\t\t\tbu formatlar spesifik bir tarihi tanımlarlar. <code>2011</code> tüm 2011 yılını ararken, <code>2011-01-18 12:32:45</code> şeklinde bir sorgu sadece o saniyedeki sonuçları verir.</li>\\\r\n\t\t\t<li><b>Zaman ve Kısmi Zamanlar</b><br>\\\r\n\t\t\t\t<code>12<br> 12:32<br> 12:32:45</code><br>\\\r\n\t\t\t\tbu formatlar gün içerisinde spesifik bir zamanı tanımlarlar. Örneğin <code>12:32</code> sadece bu saat ve dakikadaki kayıtları verir.</li>\\\r\n\t\t\t<li><b>Tarih Aralıkları</b><br>\\\r\n\t\t\t\t<code>2010 -&gt; 2011<br> last week -&gt; next week<br> 2011-05 -&gt;<br> &lt; now</code><br>\\\r\n\t\t\t\tTarih aralıkları yukarda belirtilen herhangi bir formatı &lt; or -&gt;  ile ayırarak yapılabilir. Eğer aralığın bir tarafı eksikse, sorgu ucu açıkmış gibi davranır.</li>\\\r\n\t\t\t<li><b>Ofsetli Tarih Aralığı</b><br>\\\r\n\t\t\t\t<code>2010 -> 1yr<br> 3mins < now</code>\\\r\n\t\t\t\tVerilen yöndeki tarih aralığına bakar.</li>\\\r\n\t\t\t<li><b>Çakılı Aralıklar</b><br>\\\r\n\t\t\t\t<code>2010-05-13 05:13 <> 10m<br> now <> 1yr<br> lastweek <> 1month</code><br>\\\r\n\t\t\t\tYukarıdakiyle ayni fakat belirtilen tarihten her iki yöne de bakılır.</li>\\\r\n\t\t</ul>\\\r\n\t\"\r\n});\r\n"
  },
  {
    "path": "_site/lang/zh-TW_strings.js",
    "content": "i18n.setKeys({\n\t\"General.Elasticsearch\": \"Elasticsearch\",\n\t\"General.LoadingAggs\": \"讀取聚合查詢...\",\n\t\"General.Searching\": \"搜尋中...\",\n\t\"General.Search\": \"搜尋\",\n\t\"General.Help\": \"幫助\",\n\t\"General.HelpGlyph\": \"?\",\n\t\"General.CloseGlyph\": \"X\",\n\t\"General.RefreshResults\": \"更新\",\n\t\"General.ManualRefresh\": \"手動更新\",\n\t\"General.RefreshQuickly\": \"快速更新\",\n\t\"General.Refresh5seconds\": \"每5秒更新\",\n\t\"General.Refresh1minute\": \"每1分鐘更新\",\n\t\"AliasForm.AliasName\": \"别名\",\n\t\"AliasForm.NewAliasForIndex\": \"為 {0} 建立新别名\",\n\t\"AliasForm.DeleteAliasMessage\": \"輸入 ''{0}''  删除 {1}. 此操作無法恢復\",\n\t\"AnyRequest.DisplayOptions\" : \"顯示選項\",\n\t\"AnyRequest.AsGraph\" : \"圖形視圖\",\n\t\"AnyRequest.AsJson\" : \"原始 JSON\",\n\t\"AnyRequest.AsTable\" : \"表格視圖\",\n\t\"AnyRequest.History\" : \"歷史記錄\",\n\t\"AnyRequest.RepeatRequest\" : \"重複請求\",\n\t\"AnyRequest.RepeatRequestSelect\" : \"重複周期 \",\n\t\"AnyRequest.Transformer\" : \"結果轉換器\",\n\t\"AnyRequest.Pretty\": \"易讀\",\n\t\"AnyRequest.Query\" : \"查詢\",\n\t\"AnyRequest.Request\": \"送出\",\n\t\"AnyRequest.Requesting\": \"請求中...\",\n\t\"AnyRequest.ValidateJSON\": \"驗證 JSON\",\n\t\"Browser.Title\": \"資料瀏覽\",\n\t\"Browser.ResultSourcePanelTitle\": \"原始資料\",\n\t\"Command.DELETE\": \"删除\",\n\t\"Command.SHUTDOWN\": \"關閉\",\n\t\"Command.DeleteAliasMessage\": \"删除别名？\",\n\t\"ClusterOverView.IndexName\": \"索引名稱\",\n\t\"ClusterOverview.NumShards\": \"分片數\",\n\t\"ClusterOverview.NumReplicas\": \"副本數\",\n\t\"ClusterOverview.NewIndex\": \"新建索引\",\n\t\"IndexActionsMenu.Title\": \"動作\",\n\t\"IndexActionsMenu.NewAlias\": \"新建别名...\",\n\t\"IndexActionsMenu.Refresh\": \"更新\",\n\t\"IndexActionsMenu.Flush\": \"Flush更新\",\n\t\"IndexActionsMenu.Optimize\": \"最佳化...\",\n\t\"IndexActionsMenu.ForceMerge\": \"強制合併...\",\n\t\"IndexActionsMenu.Snapshot\": \"网关快照\",\n\t\"IndexActionsMenu.Analyser\": \"測試分析器\",\n\t\"IndexActionsMenu.Open\": \"開啟\",\n\t\"IndexActionsMenu.Close\": \"關閉\",\n\t\"IndexActionsMenu.Delete\": \"删除...\",\n\t\"IndexInfoMenu.Title\": \"訊息\",\n\t\"IndexInfoMenu.Status\": \"索引狀態\",\n\t\"IndexInfoMenu.Metadata\": \"索引訊息\",\n\t\"IndexCommand.TextToAnalyze\": \"文本分析\",\n\t\"IndexCommand.ShutdownMessage\": \"輸入 ''{0}'' 以關閉 {1} 節點. 關閉的節點無法從此界面重新啟動\",\n\t\"IndexOverview.PageTitle\": \"索引總覽\",\n\t\"IndexSelector.NameWithDocs\": \"{0} ({1} 個文件)\",\n\t\"IndexSelector.SearchIndexForDocs\": \"搜尋 {0} 的文件，查詢條件:\",\n\t\"FilterBrowser.OutputType\": \"返回格式: {0}\",\n\t\"FilterBrowser.OutputSize\": \"顯示數量: {0}\",\n\t\"Header.ClusterHealth\": \"叢集健康值: {0} ({1} of {2})\",\n\t\"Header.ClusterNotConnected\": \"叢集健康值: 未連接\",\n\t\"Header.Connect\": \"連接\",\n\t\"Nav.AnyRequest\": \"複合查詢\",\n\t\"Nav.Browser\": \"資料瀏覽\",\n\t\"Nav.ClusterHealth\": \"叢集健康值\",\n\t\"Nav.ClusterState\": \"群集狀態\",\n\t\"Nav.ClusterNodes\": \"叢集節點\",\n\t\"Nav.Info\": \"訊息\",\n\t\"Nav.NodeStats\": \"節點狀態\",\n\t\"Nav.Overview\": \"總覽\",\n\t\"Nav.Indices\": \"索引\",\n\t\"Nav.Plugins\": \"套件\",\n\t\"Nav.Status\": \"狀態\",\n\t\"Nav.Templates\": \"樣版\",\n\t\"Nav.StructuredQuery\": \"基本查詢\",\n\t\"NodeActionsMenu.Title\": \"動作\",\n\t\"NodeActionsMenu.Shutdown\": \"關閉節點...\",\n\t\"NodeInfoMenu.Title\": \"訊息\",\n\t\"NodeInfoMenu.ClusterNodeInfo\": \"叢集節點訊息\",\n\t\"NodeInfoMenu.NodeStats\": \"節點狀態\",\n\t\"NodeType.Client\": \"節點客户端\",\n\t\"NodeType.Coord\": \"協調器\",\n\t\"NodeType.Master\": \"主節點\",\n\t\"NodeType.Tribe\": \"分支節點\",\n\t\"NodeType.Worker\": \"工作節點\",\n\t\"NodeType.Unassigned\": \"未分配\",\n\t\"OptimizeForm.OptimizeIndex\": \"最佳化 {0}\",\n\t\"OptimizeForm.MaxSegments\": \"最大索引段數\",\n\t\"OptimizeForm.ExpungeDeletes\": \"只删除被標記為删除的\",\n\t\"OptimizeForm.FlushAfter\": \"最佳化後更新\",\n\t\"OptimizeForm.WaitForMerge\": \"等待合併\",\n\t\"ForceMergeForm.ForceMergeIndex\": \"強制合併 {0}\",\n\t\"ForceMergeForm.MaxSegments\": \"最大索引段數\",\n\t\"ForceMergeForm.ExpungeDeletes\": \"只删除被標記為删除的\",\n\t\"ForceMergeForm.FlushAfter\": \"強制合併後更新\",\n\t\"Overview.PageTitle\" : \"叢集總覽\",\n\t\"Output.JSON\": \"JSON\",\n\t\"Output.Table\": \"Table\",\n\t\"Output.CSV\": \"CSV\",\n\t\"Output.ShowSource\": \"顯示查詢語句\",\n\t\"Preference.SortCluster\": \"叢集排序\",\n\t\"Sort.ByName\": \"按名稱\",\n\t\"Sort.ByAddress\": \"按地址\",\n\t\"Sort.ByType\": \"按類型\",\n\t\"TableResults.Summary\": \"查詢 {1} 個分片中用的 {0} 個. {2} 命中. 耗時 {3} 秒\",\n\t\"QueryFilter.AllIndices\": \"所有索引\",\n\t\"QueryFilter.AnyValue\": \"任意\",\n\t\"QueryFilter-Header-Indices\": \"索引\",\n\t\"QueryFilter-Header-Types\": \"類型\",\n\t\"QueryFilter-Header-Fields\": \"欄位\",\n\t\"QueryFilter.DateRangeHint.from\": \"從 : {0}\",\n\t\"QueryFilter.DateRangeHint.to\": \"  到 : {0}\",\n\t\"Query.FailAndUndo\": \"查詢失敗. 撤銷最近的更改\",\n\t\"StructuredQuery.ShowRawJson\": \"顯示原始 JSON\"\n});\n\ni18n.setKeys({\n\t\"AnyRequest.TransformerHelp\" : \"\\\n\t\t<p>結果轉換器用於返回結果原始 JSON 的後續處理, 將結果轉換為更有用的格式.</p>\\\n\t\t<p>轉換器應當包含 JavaScript 函數內容. 函數的返回值將傳遞给 JSON 分析器</p>\\\n\t\t<p>Example:<br>\\\n\t\t  <code>return root.hits.hits[0];</code><br>\\\n\t\t  遍歷結果並只顯示第一個元素<br>\\\n\t\t  <code>return Object.keys(root.nodes).reduce(function(tot, node) { return tot + root.nodes[node].os.mem.used_in_bytes; }, 0);</code><br>\\\n\t\t  將返回整個叢集使用的總記憶體<br></p>\\\n\t\t<p>以下函數可以方便的處理陣列與物件<br>\\\n\t\t<ul>\\\n\t\t\t<li><i>Object.keys</i>(object) := array</li>\\\n\t\t\t<li>array.<i>forEach</i>(function(prop, index))</li>\\\n\t\t\t<li>array.<i>map</i>(function(prop, index)) := array</li>\\\n\t\t\t<li>array.<i>reduce</i>(function(accumulator, prop, index), initial_value) := final_value</li>\\\n\t\t</ul>\\\n\t\t<p>當啟用重複請求時, prev 參數將會傳遞给轉換器函數. 這將用於比較並累加圖形</p>\\\n\t\t<p>Example:<br>\\\n\t\t<code>var la = [ root.nodes[Object.keys(root.nodes)[0]].os.load_average[0] ]; return prev ? la.concat(prev) : la;</code><br>\\\n\t\t將返回第一個叢集節點最近一分鐘内的平均負載\\\n\t\t將會把結果送入圖表以產生一個負載曲線圖\\\n\t\t\"\n});\n\ni18n.setKeys({\n\t\"AnyRequest.DisplayOptionsHelp\" : \"\\\n\t\t<p>原始 JSON: 將完整的查詢結果轉換為原始 JSON 格式 </p>\\\n\t\t<p>圖形視圖: 將查詢結果圖形化, 將查詢結果轉換為陣列值的形式</p>\\\n\t\t<p>表格視圖: 如果查詢是一個搜尋, 可以將搜尋結果以表格形式顯示.</p>\\\n\t\t\"\n});\n\ni18n.setKeys({\n\t\"QueryFilter.DateRangeHelp\" : \"\\\n\t\t<p>Date 欄位接受日期範圍的形式查詢.</p>\\\n\t\t<p>以下格式被支援:</p>\\\n\t\t<ul>\\\n\t\t\t<li><b>關鍵詞 / 關鍵短語</b><br>\\\n\t\t\t\t<code>now<br> today<br> tomorrow<br> yesterday<br> last / this / next + week / month / year</code><br>\\\n\t\t\t\t搜尋關鍵字匹配的日期. <code>last year</code> 將搜尋過去全年.</li>\\\n\t\t\t<li><b>範圍</b><br>\\\n\t\t\t\t<code>1000 secs<br> 5mins<br> 1day<br> 2days<br> 80d<br> 9 months<br> 2yrs</code> (空格可選, 同等於多個範圍修飾詞)<br>\\\n\t\t\t\t建立一個指定時間範圍的搜尋, 將圍繞<code>现在</code> 並延伸至過去與未來時間段.</li>\\\n\t\t\t<li><b>DateTime 與 DateTime局部</b><br>\\\n\t\t\t\t<code>2011<br> 2011-01<br> 2011-01-18<br> 2011-01-18 12<br> 2011-01-18 12:32<br> 2011-01-18 12:32:45</code><br>\\\n\t\t\t\t指定一個特定的日期範圍. <code>2011</code>會搜尋整個 2011年, 而 <code>2011-01-18 12:32:45</code> 將只搜尋1秒範圍内</li>\\\n\t\t\t<li><b>Time 與 Time局部</b><br>\\\n\t\t\t\t<code>12<br> 12:32<br> 12:32:45</code><br>\\\n\t\t\t\t這些格式只搜尋當天的特定時間. <code>12:32</code> 將搜尋當天的那一分鐘</li>\\\n\t\t\t<li><b>日期範圍</b><br>\\\n\t\t\t\t<code>2010 -&gt; 2011<br> last week -&gt; next week<br> 2011-05 -&gt;<br> &lt; now</code><br>\\\n\t\t\t\t日期範圍是將兩個日期格式串 (日期關鍵字 / DateTime / Time) 用  &lt; 或 -&gt; (效果相同) 分隔. 如果缺少任意一端，那麼在這個方向上時間將沒有限制.</li>\\\n\t\t\t<li><b>偏移日期範圍</b><br>\\\n\t\t\t\t<code>2010 -> 1yr<br> 3mins < now</code>\\\n\t\t\t\t搜尋包括指定方向上偏移的日期.</li>\\\n\t\t\t<li><b>錨定範圍</b><br>\\\n\t\t\t\t<code>2010-05-13 05:13 <> 10m<br> now <> 1yr<br> lastweek <> 1month</code><br>\\\n\t\t\t\t類似於上面的便宜日期，在兩個方向上將錨定的日期延長</li>\\\n\t\t</ul>\\\n\t\"\n});\n"
  },
  {
    "path": "_site/lang/zh_strings.js",
    "content": "i18n.setKeys({\n\t\"General.Elasticsearch\": \"Elasticsearch\",\n\t\"General.LoadingAggs\": \"加载聚合查询...\",\n\t\"General.Searching\": \"搜索中...\",\n\t\"General.Search\": \"搜索\",\n\t\"General.Help\": \"帮助\",\n\t\"General.HelpGlyph\": \"?\",\n\t\"General.CloseGlyph\": \"X\",\n\t\"General.RefreshResults\": \"刷新\",\n\t\"General.ManualRefresh\": \"手动刷新\",\n\t\"General.RefreshQuickly\": \"快速刷新\",\n\t\"General.Refresh5seconds\": \"每5秒刷新\",\n\t\"General.Refresh1minute\": \"每1分钟刷新\",\n\t\"AliasForm.AliasName\": \"别名\",\n\t\"AliasForm.NewAliasForIndex\": \"为 {0} 创建新别名\",\n\t\"AliasForm.DeleteAliasMessage\": \"输入 ''{0}''  删除 {1}. 此操作无法恢复\",\n\t\"AnyRequest.DisplayOptions\" : \"显示选项\",\n\t\"AnyRequest.AsGraph\" : \"图形视图\",\n\t\"AnyRequest.AsJson\" : \"原始 JSON\",\n\t\"AnyRequest.AsTable\" : \"表格视图\",\n\t\"AnyRequest.History\" : \"历史记录\",\n\t\"AnyRequest.RepeatRequest\" : \"重复请求\",\n\t\"AnyRequest.RepeatRequestSelect\" : \"重复周期 \",\n\t\"AnyRequest.Transformer\" : \"结果转换器\",\n\t\"AnyRequest.Pretty\": \"易读\",\n\t\"AnyRequest.Query\" : \"查询\",\n\t\"AnyRequest.Request\": \"提交请求\",\n\t\"AnyRequest.Requesting\": \"请求中...\",\n\t\"AnyRequest.ValidateJSON\": \"验证 JSON\",\n\t\"Browser.Title\": \"数据浏览\",\n\t\"Browser.ResultSourcePanelTitle\": \"原始数据\",\n\t\"Command.DELETE\": \"删除\",\n\t\"Command.SHUTDOWN\": \"关闭\",\n\t\"Command.DeleteAliasMessage\": \"删除别名?\",\n\t\"ClusterOverView.IndexName\": \"索引名称\",\n\t\"ClusterOverview.NumShards\": \"分片数\",\n\t\"ClusterOverview.NumReplicas\": \"副本数\",\n\t\"ClusterOverview.NewIndex\": \"新建索引\",\n\t\"IndexActionsMenu.Title\": \"动作\",\n\t\"IndexActionsMenu.NewAlias\": \"新建别名...\",\n\t\"IndexActionsMenu.Refresh\": \"刷新\",\n\t\"IndexActionsMenu.Flush\": \"Flush刷新\",\n\t\"IndexActionsMenu.Optimize\": \"优化...\",\n\t\"IndexActionsMenu.ForceMerge\": \"ForceMerge...\",\n\t\"IndexActionsMenu.Snapshot\": \"网关快照\",\n\t\"IndexActionsMenu.Analyser\": \"测试分析器\",\n\t\"IndexActionsMenu.Open\": \"开启\",\n\t\"IndexActionsMenu.Close\": \"关闭\",\n\t\"IndexActionsMenu.Delete\": \"删除...\",\n\t\"IndexInfoMenu.Title\": \"信息\",\n\t\"IndexInfoMenu.Status\": \"索引状态\",\n\t\"IndexInfoMenu.Metadata\": \"索引信息\",\n\t\"IndexCommand.TextToAnalyze\": \"文本分析\",\n\t\"IndexCommand.ShutdownMessage\": \"输入 ''{0}'' 以关闭 {1} 节点. 关闭的节点无法从此界面重新启动\",\n\t\"IndexOverview.PageTitle\": \"索引概览\",\n\t\"IndexSelector.NameWithDocs\": \"{0} ({1} 个文档)\",\n\t\"IndexSelector.SearchIndexForDocs\": \"搜索 {0} 的文档， 查询条件:\",\n\t\"FilterBrowser.OutputType\": \"返回格式: {0}\",\n\t\"FilterBrowser.OutputSize\": \"显示数量: {0}\",\n\t\"Header.ClusterHealth\": \"集群健康值: {0} ({1} of {2})\",\n\t\"Header.ClusterNotConnected\": \"集群健康值: 未连接\",\n\t\"Header.Connect\": \"连接\",\n\t\"Nav.AnyRequest\": \"复合查询\",\n\t\"Nav.Browser\": \"数据浏览\",\n\t\"Nav.ClusterHealth\": \"集群健康值\",\n\t\"Nav.ClusterState\": \"群集状态\",\n\t\"Nav.ClusterNodes\": \"集群节点\",\n\t\"Nav.Info\": \"信息\",\n\t\"Nav.NodeStats\": \"节点状态\",\n\t\"Nav.Overview\": \"概览\",\n\t\"Nav.Indices\": \"索引\",\n\t\"Nav.Plugins\": \"插件\",\n\t\"Nav.Status\": \"状态\",\n\t\"Nav.Templates\": \"模板\",\n\t\"Nav.StructuredQuery\": \"基本查询\",\n\t\"NodeActionsMenu.Title\": \"动作\",\n\t\"NodeActionsMenu.Shutdown\": \"关停...\",\n\t\"NodeInfoMenu.Title\": \"信息\",\n\t\"NodeInfoMenu.ClusterNodeInfo\": \"集群节点信息\",\n\t\"NodeInfoMenu.NodeStats\": \"节点状态\",\n\t\"NodeType.Client\": \"节点客户端\",\n\t\"NodeType.Coord\": \"协调器\",\n\t\"NodeType.Master\": \"主节点\",\n\t\"NodeType.Tribe\": \"分支结点\",\n\t\"NodeType.Worker\": \"工作节点\",\n\t\"NodeType.Unassigned\": \"未分配\",\n\t\"OptimizeForm.OptimizeIndex\": \"优化 {0}\",\n\t\"OptimizeForm.MaxSegments\": \"最大索引段数\",\n\t\"OptimizeForm.ExpungeDeletes\": \"只删除被标记为删除的\",\n\t\"OptimizeForm.FlushAfter\": \"优化后刷新\",\n\t\"OptimizeForm.WaitForMerge\": \"等待合并\",\n\t\"ForceMergeForm.ForceMergeIndex\": \"ForceMerge {0}\",\n\t\"ForceMergeForm.MaxSegments\": \"最大索引段数\",\n\t\"ForceMergeForm.ExpungeDeletes\": \"只删除被标记为删除的\",\n\t\"ForceMergeForm.FlushAfter\": \"ForceMerge后刷新\",\n\t\"Overview.PageTitle\" : \"集群概览\",\n\t\"Output.JSON\": \"JSON\",\n\t\"Output.Table\": \"Table\",\n\t\"Output.CSV\": \"CSV\",\n\t\"Output.ShowSource\": \"显示查询语句\",\n\t\"Preference.SortCluster\": \"集群排序\",\n\t\"Sort.ByName\": \"按名称\",\n\t\"Sort.ByAddress\": \"按地址\",\n\t\"Sort.ByType\": \"按类型\",\n\t\"TableResults.Summary\": \"查询 {1} 个分片中用的 {0} 个. {2} 命中. 耗时 {3} 秒\",\n\t\"QueryFilter.AllIndices\": \"所有索引\",\n\t\"QueryFilter.AnyValue\": \"任意\",\n\t\"QueryFilter-Header-Indices\": \"索引\",\n\t\"QueryFilter-Header-Types\": \"类型\",\n\t\"QueryFilter-Header-Fields\": \"字段\",\n\t\"QueryFilter.DateRangeHint.from\": \"从 : {0}\",\n\t\"QueryFilter.DateRangeHint.to\": \"  到 : {0}\",\n\t\"Query.FailAndUndo\": \"查询失败. 撤消最近的更改\",\n\t\"StructuredQuery.ShowRawJson\": \"显示原始 JSON\"\n});\n\ni18n.setKeys({\n\t\"AnyRequest.TransformerHelp\" : \"\\\n\t\t<p>结果转换器用于返回结果原始JSON的后续处理, 将结果转换为更有用的格式.</p>\\\n\t\t<p>转换器应当包含javascript函数体. 函数的返回值将传递给json分析器</p>\\\n\t\t<p>Example:<br>\\\n\t\t  <code>return root.hits.hits[0];</code><br>\\\n\t\t  遍历结果并只显示第一个元素<br>\\\n\t\t  <code>return Object.keys(root.nodes).reduce(function(tot, node) { return tot + root.nodes[node].os.mem.used_in_bytes; }, 0);</code><br>\\\n\t\t  将返回整个集群使用的总内存<br></p>\\\n\t\t<p>以下函数可以方便的处理数组与对象<br>\\\n\t\t<ul>\\\n\t\t\t<li><i>Object.keys</i>(object) := array</li>\\\n\t\t\t<li>array.<i>forEach</i>(function(prop, index))</li>\\\n\t\t\t<li>array.<i>map</i>(function(prop, index)) := array</li>\\\n\t\t\t<li>array.<i>reduce</i>(function(accumulator, prop, index), initial_value) := final_value</li>\\\n\t\t</ul>\\\n\t\t<p>当启用重复请求时, prev 参数将会传递给转换器函数. 这将用于比较并累加图形</p>\\\n\t\t<p>Example:<br>\\\n\t\t<code>var la = [ root.nodes[Object.keys(root.nodes)[0]].os.load_average[0] ]; return prev ? la.concat(prev) : la;</code><br>\\\n\t\t将返回第一个集群节点最近一分钟内的平均负载\\\n\t\t将会把结果送人图表以产生一个负载曲线图\\\n\t\t\"\n});\n\ni18n.setKeys({\n\t\"AnyRequest.DisplayOptionsHelp\" : \"\\\n\t\t<p>原始 Json: 将完整的查询结果转换为原始JSON格式 </p>\\\n\t\t<p>图形视图: 将查询结果图形化, 将查询结果转换为数组值的形式</p>\\\n\t\t<p>表格视图: 如果查询是一个搜索, 可以将搜索结果以表格形式显示.</p>\\\n\t\t\"\n});\n\ni18n.setKeys({\n\t\"QueryFilter.DateRangeHelp\" : \"\\\n\t\t<p>Date 字段接受日期范围的形式查询.</p>\\\n\t\t<p>一下格式被支持:</p>\\\n\t\t<ul>\\\n\t\t\t<li><b>关键词 / 关键短语</b><br>\\\n\t\t\t\t<code>now<br> today<br> tomorrow<br> yesterday<br> last / this / next + week / month / year</code><br>\\\n\t\t\t\t搜索关键字匹配的日期. <code>last year</code> 将搜索过去全年.</li>\\\n\t\t\t<li><b>范围</b><br>\\\n\t\t\t\t<code>1000 secs<br> 5mins<br> 1day<br> 2days<br> 80d<br> 9 months<br> 2yrs</code> (空格可选, 同等于多个范围修饰词)<br>\\\n\t\t\t\t创建一个指定时间范围的搜索, 将围绕<code>现在</code> 并延伸至过去与未来时间段.</li>\\\n\t\t\t<li><b>DateTime 与 DateTime局部</b><br>\\\n\t\t\t\t<code>2011<br> 2011-01<br> 2011-01-18<br> 2011-01-18 12<br> 2011-01-18 12:32<br> 2011-01-18 12:32:45</code><br>\\\n\t\t\t\t指定一个特定的日期范围. <code>2011</code>会搜索整个 2011年, 而 <code>2011-01-18 12:32:45</code> 将只搜索1秒范围内</li>\\\n\t\t\t<li><b>Time 与 Time局部</b><br>\\\n\t\t\t\t<code>12<br> 12:32<br> 12:32:45</code><br>\\\n\t\t\t\t这些格式只搜索当天的特定时间. <code>12:32</code> 将搜索当天的那一分钟</li>\\\n\t\t\t<li><b>日期范围</b><br>\\\n\t\t\t\t<code>2010 -&gt; 2011<br> last week -&gt; next week<br> 2011-05 -&gt;<br> &lt; now</code><br>\\\n\t\t\t\t日期范围是将两个日期格式串 (日期关键字 / DateTime / Time) 用  &lt; 或 -&gt; (效果相同) 分隔. 如果缺少任意一端，那么在这个方向上时间将没有限制.</li>\\\n\t\t\t<li><b>偏移日期范围</b><br>\\\n\t\t\t\t<code>2010 -> 1yr<br> 3mins < now</code>\\\n\t\t\t\t搜索包括指定方向上偏移的日期.</li>\\\n\t\t\t<li><b>锚定范围</b><br>\\\n\t\t\t\t<code>2010-05-13 05:13 <> 10m<br> now <> 1yr<br> lastweek <> 1month</code><br>\\\n\t\t\t\t类似于上面的便宜日期，在两个方向上将锚定的日期延长</li>\\\n\t\t</ul>\\\n\t\"\n});\n"
  },
  {
    "path": "_site/manifest.json",
    "content": "{  \n    \"manifest_version\": 2,\n    \"name\": \"elasticsearch-head\",  \n    \"version\": \"1.0.8\",\n    \"background\": { \n      \"scripts\": [\"background.js\"],\n      \"persistent\": false\n    },\n    \"icons\": {\n      \"16\": \"base/favicon.png\"\n    },\n    \"content_security_policy\": \"script-src 'self' 'sha256-Rpn+rjJuXCjZBPOPhhVloRXuzAUBRnAas+6gKVDohs0=' 'unsafe-eval'; object-src 'self';\",\n    \"description\": \"Chrome Extension containing the excellent ElasticSearch Head application.\",  \n    \"browser_action\": {  \n      \"default_icon\": \"base/favicon.png\" ,\n      \"default_title\": \"es-head\"\n    },\n    \"content_scripts\":[{\n        \"all_frames\": false,\n        \"matches\":[\"*://*/\"],\n        \"js\":[\"background.js\"],\n        \"run_at\": \"document_end\"\n    }]\n  } \n  "
  },
  {
    "path": "_site/vendor.css",
    "content": "/*!\n *  Font Awesome 4.0.3 by @davegandy - http://fontawesome.io - @fontawesome\n *  License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)\n */\n/* FONT PATH\n * -------------------------- */\n@font-face {\n  font-family: 'FontAwesome';\n  src: url('fonts/fontawesome-webfont.eot?v=4.0.3');\n  src: url('fonts/fontawesome-webfont.eot?#iefix&v=4.0.3') format('embedded-opentype'), url('fonts/fontawesome-webfont.woff?v=4.0.3') format('woff'), url('fonts/fontawesome-webfont.ttf?v=4.0.3') format('truetype'), url('fonts/fontawesome-webfont.svg?v=4.0.3#fontawesomeregular') format('svg');\n  font-weight: normal;\n  font-style: normal;\n}\n.fa {\n  display: inline-block;\n  font-family: FontAwesome;\n  font-style: normal;\n  font-weight: normal;\n  line-height: 1;\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n/* makes the font 33% larger relative to the icon container */\n.fa-lg {\n  font-size: 1.3333333333333333em;\n  line-height: 0.75em;\n  vertical-align: -15%;\n}\n.fa-2x {\n  font-size: 2em;\n}\n.fa-3x {\n  font-size: 3em;\n}\n.fa-4x {\n  font-size: 4em;\n}\n.fa-5x {\n  font-size: 5em;\n}\n.fa-fw {\n  width: 1.2857142857142858em;\n  text-align: center;\n}\n.fa-ul {\n  padding-left: 0;\n  margin-left: 2.142857142857143em;\n  list-style-type: none;\n}\n.fa-ul > li {\n  position: relative;\n}\n.fa-li {\n  position: absolute;\n  left: -2.142857142857143em;\n  width: 2.142857142857143em;\n  top: 0.14285714285714285em;\n  text-align: center;\n}\n.fa-li.fa-lg {\n  left: -1.8571428571428572em;\n}\n.fa-border {\n  padding: .2em .25em .15em;\n  border: solid 0.08em #eeeeee;\n  border-radius: .1em;\n}\n.pull-right {\n  float: right;\n}\n.pull-left {\n  float: left;\n}\n.fa.pull-left {\n  margin-right: .3em;\n}\n.fa.pull-right {\n  margin-left: .3em;\n}\n.fa-spin {\n  -webkit-animation: spin 2s infinite linear;\n  -moz-animation: spin 2s infinite linear;\n  -o-animation: spin 2s infinite linear;\n  animation: spin 2s infinite linear;\n}\n@-moz-keyframes spin {\n  0% {\n    -moz-transform: rotate(0deg);\n  }\n  100% {\n    -moz-transform: rotate(359deg);\n  }\n}\n@-webkit-keyframes spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n  }\n  100% {\n    -webkit-transform: rotate(359deg);\n  }\n}\n@-o-keyframes spin {\n  0% {\n    -o-transform: rotate(0deg);\n  }\n  100% {\n    -o-transform: rotate(359deg);\n  }\n}\n@-ms-keyframes spin {\n  0% {\n    -ms-transform: rotate(0deg);\n  }\n  100% {\n    -ms-transform: rotate(359deg);\n  }\n}\n@keyframes spin {\n  0% {\n    transform: rotate(0deg);\n  }\n  100% {\n    transform: rotate(359deg);\n  }\n}\n.fa-rotate-90 {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1);\n  -webkit-transform: rotate(90deg);\n  -moz-transform: rotate(90deg);\n  -ms-transform: rotate(90deg);\n  -o-transform: rotate(90deg);\n  transform: rotate(90deg);\n}\n.fa-rotate-180 {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2);\n  -webkit-transform: rotate(180deg);\n  -moz-transform: rotate(180deg);\n  -ms-transform: rotate(180deg);\n  -o-transform: rotate(180deg);\n  transform: rotate(180deg);\n}\n.fa-rotate-270 {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);\n  -webkit-transform: rotate(270deg);\n  -moz-transform: rotate(270deg);\n  -ms-transform: rotate(270deg);\n  -o-transform: rotate(270deg);\n  transform: rotate(270deg);\n}\n.fa-flip-horizontal {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);\n  -webkit-transform: scale(-1, 1);\n  -moz-transform: scale(-1, 1);\n  -ms-transform: scale(-1, 1);\n  -o-transform: scale(-1, 1);\n  transform: scale(-1, 1);\n}\n.fa-flip-vertical {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);\n  -webkit-transform: scale(1, -1);\n  -moz-transform: scale(1, -1);\n  -ms-transform: scale(1, -1);\n  -o-transform: scale(1, -1);\n  transform: scale(1, -1);\n}\n.fa-stack {\n  position: relative;\n  display: inline-block;\n  width: 2em;\n  height: 2em;\n  line-height: 2em;\n  vertical-align: middle;\n}\n.fa-stack-1x,\n.fa-stack-2x {\n  position: absolute;\n  left: 0;\n  width: 100%;\n  text-align: center;\n}\n.fa-stack-1x {\n  line-height: inherit;\n}\n.fa-stack-2x {\n  font-size: 2em;\n}\n.fa-inverse {\n  color: #ffffff;\n}\n/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen\n   readers do not read off random characters that represent icons */\n.fa-glass:before {\n  content: \"\\f000\";\n}\n.fa-music:before {\n  content: \"\\f001\";\n}\n.fa-search:before {\n  content: \"\\f002\";\n}\n.fa-envelope-o:before {\n  content: \"\\f003\";\n}\n.fa-heart:before {\n  content: \"\\f004\";\n}\n.fa-star:before {\n  content: \"\\f005\";\n}\n.fa-star-o:before {\n  content: \"\\f006\";\n}\n.fa-user:before {\n  content: \"\\f007\";\n}\n.fa-film:before {\n  content: \"\\f008\";\n}\n.fa-th-large:before {\n  content: \"\\f009\";\n}\n.fa-th:before {\n  content: \"\\f00a\";\n}\n.fa-th-list:before {\n  content: \"\\f00b\";\n}\n.fa-check:before {\n  content: \"\\f00c\";\n}\n.fa-times:before {\n  content: \"\\f00d\";\n}\n.fa-search-plus:before {\n  content: \"\\f00e\";\n}\n.fa-search-minus:before {\n  content: \"\\f010\";\n}\n.fa-power-off:before {\n  content: \"\\f011\";\n}\n.fa-signal:before {\n  content: \"\\f012\";\n}\n.fa-gear:before,\n.fa-cog:before {\n  content: \"\\f013\";\n}\n.fa-trash-o:before {\n  content: \"\\f014\";\n}\n.fa-home:before {\n  content: \"\\f015\";\n}\n.fa-file-o:before {\n  content: \"\\f016\";\n}\n.fa-clock-o:before {\n  content: \"\\f017\";\n}\n.fa-road:before {\n  content: \"\\f018\";\n}\n.fa-download:before {\n  content: \"\\f019\";\n}\n.fa-arrow-circle-o-down:before {\n  content: \"\\f01a\";\n}\n.fa-arrow-circle-o-up:before {\n  content: \"\\f01b\";\n}\n.fa-inbox:before {\n  content: \"\\f01c\";\n}\n.fa-play-circle-o:before {\n  content: \"\\f01d\";\n}\n.fa-rotate-right:before,\n.fa-repeat:before {\n  content: \"\\f01e\";\n}\n.fa-refresh:before {\n  content: \"\\f021\";\n}\n.fa-list-alt:before {\n  content: \"\\f022\";\n}\n.fa-lock:before {\n  content: \"\\f023\";\n}\n.fa-flag:before {\n  content: \"\\f024\";\n}\n.fa-headphones:before {\n  content: \"\\f025\";\n}\n.fa-volume-off:before {\n  content: \"\\f026\";\n}\n.fa-volume-down:before {\n  content: \"\\f027\";\n}\n.fa-volume-up:before {\n  content: \"\\f028\";\n}\n.fa-qrcode:before {\n  content: \"\\f029\";\n}\n.fa-barcode:before {\n  content: \"\\f02a\";\n}\n.fa-tag:before {\n  content: \"\\f02b\";\n}\n.fa-tags:before {\n  content: \"\\f02c\";\n}\n.fa-book:before {\n  content: \"\\f02d\";\n}\n.fa-bookmark:before {\n  content: \"\\f02e\";\n}\n.fa-print:before {\n  content: \"\\f02f\";\n}\n.fa-camera:before {\n  content: \"\\f030\";\n}\n.fa-font:before {\n  content: \"\\f031\";\n}\n.fa-bold:before {\n  content: \"\\f032\";\n}\n.fa-italic:before {\n  content: \"\\f033\";\n}\n.fa-text-height:before {\n  content: \"\\f034\";\n}\n.fa-text-width:before {\n  content: \"\\f035\";\n}\n.fa-align-left:before {\n  content: \"\\f036\";\n}\n.fa-align-center:before {\n  content: \"\\f037\";\n}\n.fa-align-right:before {\n  content: \"\\f038\";\n}\n.fa-align-justify:before {\n  content: \"\\f039\";\n}\n.fa-list:before {\n  content: \"\\f03a\";\n}\n.fa-dedent:before,\n.fa-outdent:before {\n  content: \"\\f03b\";\n}\n.fa-indent:before {\n  content: \"\\f03c\";\n}\n.fa-video-camera:before {\n  content: \"\\f03d\";\n}\n.fa-picture-o:before {\n  content: \"\\f03e\";\n}\n.fa-pencil:before {\n  content: \"\\f040\";\n}\n.fa-map-marker:before {\n  content: \"\\f041\";\n}\n.fa-adjust:before {\n  content: \"\\f042\";\n}\n.fa-tint:before {\n  content: \"\\f043\";\n}\n.fa-edit:before,\n.fa-pencil-square-o:before {\n  content: \"\\f044\";\n}\n.fa-share-square-o:before {\n  content: \"\\f045\";\n}\n.fa-check-square-o:before {\n  content: \"\\f046\";\n}\n.fa-arrows:before {\n  content: \"\\f047\";\n}\n.fa-step-backward:before {\n  content: \"\\f048\";\n}\n.fa-fast-backward:before {\n  content: \"\\f049\";\n}\n.fa-backward:before {\n  content: \"\\f04a\";\n}\n.fa-play:before {\n  content: \"\\f04b\";\n}\n.fa-pause:before {\n  content: \"\\f04c\";\n}\n.fa-stop:before {\n  content: \"\\f04d\";\n}\n.fa-forward:before {\n  content: \"\\f04e\";\n}\n.fa-fast-forward:before {\n  content: \"\\f050\";\n}\n.fa-step-forward:before {\n  content: \"\\f051\";\n}\n.fa-eject:before {\n  content: \"\\f052\";\n}\n.fa-chevron-left:before {\n  content: \"\\f053\";\n}\n.fa-chevron-right:before {\n  content: \"\\f054\";\n}\n.fa-plus-circle:before {\n  content: \"\\f055\";\n}\n.fa-minus-circle:before {\n  content: \"\\f056\";\n}\n.fa-times-circle:before {\n  content: \"\\f057\";\n}\n.fa-check-circle:before {\n  content: \"\\f058\";\n}\n.fa-question-circle:before {\n  content: \"\\f059\";\n}\n.fa-info-circle:before {\n  content: \"\\f05a\";\n}\n.fa-crosshairs:before {\n  content: \"\\f05b\";\n}\n.fa-times-circle-o:before {\n  content: \"\\f05c\";\n}\n.fa-check-circle-o:before {\n  content: \"\\f05d\";\n}\n.fa-ban:before {\n  content: \"\\f05e\";\n}\n.fa-arrow-left:before {\n  content: \"\\f060\";\n}\n.fa-arrow-right:before {\n  content: \"\\f061\";\n}\n.fa-arrow-up:before {\n  content: \"\\f062\";\n}\n.fa-arrow-down:before {\n  content: \"\\f063\";\n}\n.fa-mail-forward:before,\n.fa-share:before {\n  content: \"\\f064\";\n}\n.fa-expand:before {\n  content: \"\\f065\";\n}\n.fa-compress:before {\n  content: \"\\f066\";\n}\n.fa-plus:before {\n  content: \"\\f067\";\n}\n.fa-minus:before {\n  content: \"\\f068\";\n}\n.fa-asterisk:before {\n  content: \"\\f069\";\n}\n.fa-exclamation-circle:before {\n  content: \"\\f06a\";\n}\n.fa-gift:before {\n  content: \"\\f06b\";\n}\n.fa-leaf:before {\n  content: \"\\f06c\";\n}\n.fa-fire:before {\n  content: \"\\f06d\";\n}\n.fa-eye:before {\n  content: \"\\f06e\";\n}\n.fa-eye-slash:before {\n  content: \"\\f070\";\n}\n.fa-warning:before,\n.fa-exclamation-triangle:before {\n  content: \"\\f071\";\n}\n.fa-plane:before {\n  content: \"\\f072\";\n}\n.fa-calendar:before {\n  content: \"\\f073\";\n}\n.fa-random:before {\n  content: \"\\f074\";\n}\n.fa-comment:before {\n  content: \"\\f075\";\n}\n.fa-magnet:before {\n  content: \"\\f076\";\n}\n.fa-chevron-up:before {\n  content: \"\\f077\";\n}\n.fa-chevron-down:before {\n  content: \"\\f078\";\n}\n.fa-retweet:before {\n  content: \"\\f079\";\n}\n.fa-shopping-cart:before {\n  content: \"\\f07a\";\n}\n.fa-folder:before {\n  content: \"\\f07b\";\n}\n.fa-folder-open:before {\n  content: \"\\f07c\";\n}\n.fa-arrows-v:before {\n  content: \"\\f07d\";\n}\n.fa-arrows-h:before {\n  content: \"\\f07e\";\n}\n.fa-bar-chart-o:before {\n  content: \"\\f080\";\n}\n.fa-twitter-square:before {\n  content: \"\\f081\";\n}\n.fa-facebook-square:before {\n  content: \"\\f082\";\n}\n.fa-camera-retro:before {\n  content: \"\\f083\";\n}\n.fa-key:before {\n  content: \"\\f084\";\n}\n.fa-gears:before,\n.fa-cogs:before {\n  content: \"\\f085\";\n}\n.fa-comments:before {\n  content: \"\\f086\";\n}\n.fa-thumbs-o-up:before {\n  content: \"\\f087\";\n}\n.fa-thumbs-o-down:before {\n  content: \"\\f088\";\n}\n.fa-star-half:before {\n  content: \"\\f089\";\n}\n.fa-heart-o:before {\n  content: \"\\f08a\";\n}\n.fa-sign-out:before {\n  content: \"\\f08b\";\n}\n.fa-linkedin-square:before {\n  content: \"\\f08c\";\n}\n.fa-thumb-tack:before {\n  content: \"\\f08d\";\n}\n.fa-external-link:before {\n  content: \"\\f08e\";\n}\n.fa-sign-in:before {\n  content: \"\\f090\";\n}\n.fa-trophy:before {\n  content: \"\\f091\";\n}\n.fa-github-square:before {\n  content: \"\\f092\";\n}\n.fa-upload:before {\n  content: \"\\f093\";\n}\n.fa-lemon-o:before {\n  content: \"\\f094\";\n}\n.fa-phone:before {\n  content: \"\\f095\";\n}\n.fa-square-o:before {\n  content: \"\\f096\";\n}\n.fa-bookmark-o:before {\n  content: \"\\f097\";\n}\n.fa-phone-square:before {\n  content: \"\\f098\";\n}\n.fa-twitter:before {\n  content: \"\\f099\";\n}\n.fa-facebook:before {\n  content: \"\\f09a\";\n}\n.fa-github:before {\n  content: \"\\f09b\";\n}\n.fa-unlock:before {\n  content: \"\\f09c\";\n}\n.fa-credit-card:before {\n  content: \"\\f09d\";\n}\n.fa-rss:before {\n  content: \"\\f09e\";\n}\n.fa-hdd-o:before {\n  content: \"\\f0a0\";\n}\n.fa-bullhorn:before {\n  content: \"\\f0a1\";\n}\n.fa-bell:before {\n  content: \"\\f0f3\";\n}\n.fa-certificate:before {\n  content: \"\\f0a3\";\n}\n.fa-hand-o-right:before {\n  content: \"\\f0a4\";\n}\n.fa-hand-o-left:before {\n  content: \"\\f0a5\";\n}\n.fa-hand-o-up:before {\n  content: \"\\f0a6\";\n}\n.fa-hand-o-down:before {\n  content: \"\\f0a7\";\n}\n.fa-arrow-circle-left:before {\n  content: \"\\f0a8\";\n}\n.fa-arrow-circle-right:before {\n  content: \"\\f0a9\";\n}\n.fa-arrow-circle-up:before {\n  content: \"\\f0aa\";\n}\n.fa-arrow-circle-down:before {\n  content: \"\\f0ab\";\n}\n.fa-globe:before {\n  content: \"\\f0ac\";\n}\n.fa-wrench:before {\n  content: \"\\f0ad\";\n}\n.fa-tasks:before {\n  content: \"\\f0ae\";\n}\n.fa-filter:before {\n  content: \"\\f0b0\";\n}\n.fa-briefcase:before {\n  content: \"\\f0b1\";\n}\n.fa-arrows-alt:before {\n  content: \"\\f0b2\";\n}\n.fa-group:before,\n.fa-users:before {\n  content: \"\\f0c0\";\n}\n.fa-chain:before,\n.fa-link:before {\n  content: \"\\f0c1\";\n}\n.fa-cloud:before {\n  content: \"\\f0c2\";\n}\n.fa-flask:before {\n  content: \"\\f0c3\";\n}\n.fa-cut:before,\n.fa-scissors:before {\n  content: \"\\f0c4\";\n}\n.fa-copy:before,\n.fa-files-o:before {\n  content: \"\\f0c5\";\n}\n.fa-paperclip:before {\n  content: \"\\f0c6\";\n}\n.fa-save:before,\n.fa-floppy-o:before {\n  content: \"\\f0c7\";\n}\n.fa-square:before {\n  content: \"\\f0c8\";\n}\n.fa-bars:before {\n  content: \"\\f0c9\";\n}\n.fa-list-ul:before {\n  content: \"\\f0ca\";\n}\n.fa-list-ol:before {\n  content: \"\\f0cb\";\n}\n.fa-strikethrough:before {\n  content: \"\\f0cc\";\n}\n.fa-underline:before {\n  content: \"\\f0cd\";\n}\n.fa-table:before {\n  content: \"\\f0ce\";\n}\n.fa-magic:before {\n  content: \"\\f0d0\";\n}\n.fa-truck:before {\n  content: \"\\f0d1\";\n}\n.fa-pinterest:before {\n  content: \"\\f0d2\";\n}\n.fa-pinterest-square:before {\n  content: \"\\f0d3\";\n}\n.fa-google-plus-square:before {\n  content: \"\\f0d4\";\n}\n.fa-google-plus:before {\n  content: \"\\f0d5\";\n}\n.fa-money:before {\n  content: \"\\f0d6\";\n}\n.fa-caret-down:before {\n  content: \"\\f0d7\";\n}\n.fa-caret-up:before {\n  content: \"\\f0d8\";\n}\n.fa-caret-left:before {\n  content: \"\\f0d9\";\n}\n.fa-caret-right:before {\n  content: \"\\f0da\";\n}\n.fa-columns:before {\n  content: \"\\f0db\";\n}\n.fa-unsorted:before,\n.fa-sort:before {\n  content: \"\\f0dc\";\n}\n.fa-sort-down:before,\n.fa-sort-asc:before {\n  content: \"\\f0dd\";\n}\n.fa-sort-up:before,\n.fa-sort-desc:before {\n  content: \"\\f0de\";\n}\n.fa-envelope:before {\n  content: \"\\f0e0\";\n}\n.fa-linkedin:before {\n  content: \"\\f0e1\";\n}\n.fa-rotate-left:before,\n.fa-undo:before {\n  content: \"\\f0e2\";\n}\n.fa-legal:before,\n.fa-gavel:before {\n  content: \"\\f0e3\";\n}\n.fa-dashboard:before,\n.fa-tachometer:before {\n  content: \"\\f0e4\";\n}\n.fa-comment-o:before {\n  content: \"\\f0e5\";\n}\n.fa-comments-o:before {\n  content: \"\\f0e6\";\n}\n.fa-flash:before,\n.fa-bolt:before {\n  content: \"\\f0e7\";\n}\n.fa-sitemap:before {\n  content: \"\\f0e8\";\n}\n.fa-umbrella:before {\n  content: \"\\f0e9\";\n}\n.fa-paste:before,\n.fa-clipboard:before {\n  content: \"\\f0ea\";\n}\n.fa-lightbulb-o:before {\n  content: \"\\f0eb\";\n}\n.fa-exchange:before {\n  content: \"\\f0ec\";\n}\n.fa-cloud-download:before {\n  content: \"\\f0ed\";\n}\n.fa-cloud-upload:before {\n  content: \"\\f0ee\";\n}\n.fa-user-md:before {\n  content: \"\\f0f0\";\n}\n.fa-stethoscope:before {\n  content: \"\\f0f1\";\n}\n.fa-suitcase:before {\n  content: \"\\f0f2\";\n}\n.fa-bell-o:before {\n  content: \"\\f0a2\";\n}\n.fa-coffee:before {\n  content: \"\\f0f4\";\n}\n.fa-cutlery:before {\n  content: \"\\f0f5\";\n}\n.fa-file-text-o:before {\n  content: \"\\f0f6\";\n}\n.fa-building-o:before {\n  content: \"\\f0f7\";\n}\n.fa-hospital-o:before {\n  content: \"\\f0f8\";\n}\n.fa-ambulance:before {\n  content: \"\\f0f9\";\n}\n.fa-medkit:before {\n  content: \"\\f0fa\";\n}\n.fa-fighter-jet:before {\n  content: \"\\f0fb\";\n}\n.fa-beer:before {\n  content: \"\\f0fc\";\n}\n.fa-h-square:before {\n  content: \"\\f0fd\";\n}\n.fa-plus-square:before {\n  content: \"\\f0fe\";\n}\n.fa-angle-double-left:before {\n  content: \"\\f100\";\n}\n.fa-angle-double-right:before {\n  content: \"\\f101\";\n}\n.fa-angle-double-up:before {\n  content: \"\\f102\";\n}\n.fa-angle-double-down:before {\n  content: \"\\f103\";\n}\n.fa-angle-left:before {\n  content: \"\\f104\";\n}\n.fa-angle-right:before {\n  content: \"\\f105\";\n}\n.fa-angle-up:before {\n  content: \"\\f106\";\n}\n.fa-angle-down:before {\n  content: \"\\f107\";\n}\n.fa-desktop:before {\n  content: \"\\f108\";\n}\n.fa-laptop:before {\n  content: \"\\f109\";\n}\n.fa-tablet:before {\n  content: \"\\f10a\";\n}\n.fa-mobile-phone:before,\n.fa-mobile:before {\n  content: \"\\f10b\";\n}\n.fa-circle-o:before {\n  content: \"\\f10c\";\n}\n.fa-quote-left:before {\n  content: \"\\f10d\";\n}\n.fa-quote-right:before {\n  content: \"\\f10e\";\n}\n.fa-spinner:before {\n  content: \"\\f110\";\n}\n.fa-circle:before {\n  content: \"\\f111\";\n}\n.fa-mail-reply:before,\n.fa-reply:before {\n  content: \"\\f112\";\n}\n.fa-github-alt:before {\n  content: \"\\f113\";\n}\n.fa-folder-o:before {\n  content: \"\\f114\";\n}\n.fa-folder-open-o:before {\n  content: \"\\f115\";\n}\n.fa-smile-o:before {\n  content: \"\\f118\";\n}\n.fa-frown-o:before {\n  content: \"\\f119\";\n}\n.fa-meh-o:before {\n  content: \"\\f11a\";\n}\n.fa-gamepad:before {\n  content: \"\\f11b\";\n}\n.fa-keyboard-o:before {\n  content: \"\\f11c\";\n}\n.fa-flag-o:before {\n  content: \"\\f11d\";\n}\n.fa-flag-checkered:before {\n  content: \"\\f11e\";\n}\n.fa-terminal:before {\n  content: \"\\f120\";\n}\n.fa-code:before {\n  content: \"\\f121\";\n}\n.fa-reply-all:before {\n  content: \"\\f122\";\n}\n.fa-mail-reply-all:before {\n  content: \"\\f122\";\n}\n.fa-star-half-empty:before,\n.fa-star-half-full:before,\n.fa-star-half-o:before {\n  content: \"\\f123\";\n}\n.fa-location-arrow:before {\n  content: \"\\f124\";\n}\n.fa-crop:before {\n  content: \"\\f125\";\n}\n.fa-code-fork:before {\n  content: \"\\f126\";\n}\n.fa-unlink:before,\n.fa-chain-broken:before {\n  content: \"\\f127\";\n}\n.fa-question:before {\n  content: \"\\f128\";\n}\n.fa-info:before {\n  content: \"\\f129\";\n}\n.fa-exclamation:before {\n  content: \"\\f12a\";\n}\n.fa-superscript:before {\n  content: \"\\f12b\";\n}\n.fa-subscript:before {\n  content: \"\\f12c\";\n}\n.fa-eraser:before {\n  content: \"\\f12d\";\n}\n.fa-puzzle-piece:before {\n  content: \"\\f12e\";\n}\n.fa-microphone:before {\n  content: \"\\f130\";\n}\n.fa-microphone-slash:before {\n  content: \"\\f131\";\n}\n.fa-shield:before {\n  content: \"\\f132\";\n}\n.fa-calendar-o:before {\n  content: \"\\f133\";\n}\n.fa-fire-extinguisher:before {\n  content: \"\\f134\";\n}\n.fa-rocket:before {\n  content: \"\\f135\";\n}\n.fa-maxcdn:before {\n  content: \"\\f136\";\n}\n.fa-chevron-circle-left:before {\n  content: \"\\f137\";\n}\n.fa-chevron-circle-right:before {\n  content: \"\\f138\";\n}\n.fa-chevron-circle-up:before {\n  content: \"\\f139\";\n}\n.fa-chevron-circle-down:before {\n  content: \"\\f13a\";\n}\n.fa-html5:before {\n  content: \"\\f13b\";\n}\n.fa-css3:before {\n  content: \"\\f13c\";\n}\n.fa-anchor:before {\n  content: \"\\f13d\";\n}\n.fa-unlock-alt:before {\n  content: \"\\f13e\";\n}\n.fa-bullseye:before {\n  content: \"\\f140\";\n}\n.fa-ellipsis-h:before {\n  content: \"\\f141\";\n}\n.fa-ellipsis-v:before {\n  content: \"\\f142\";\n}\n.fa-rss-square:before {\n  content: \"\\f143\";\n}\n.fa-play-circle:before {\n  content: \"\\f144\";\n}\n.fa-ticket:before {\n  content: \"\\f145\";\n}\n.fa-minus-square:before {\n  content: \"\\f146\";\n}\n.fa-minus-square-o:before {\n  content: \"\\f147\";\n}\n.fa-level-up:before {\n  content: \"\\f148\";\n}\n.fa-level-down:before {\n  content: \"\\f149\";\n}\n.fa-check-square:before {\n  content: \"\\f14a\";\n}\n.fa-pencil-square:before {\n  content: \"\\f14b\";\n}\n.fa-external-link-square:before {\n  content: \"\\f14c\";\n}\n.fa-share-square:before {\n  content: \"\\f14d\";\n}\n.fa-compass:before {\n  content: \"\\f14e\";\n}\n.fa-toggle-down:before,\n.fa-caret-square-o-down:before {\n  content: \"\\f150\";\n}\n.fa-toggle-up:before,\n.fa-caret-square-o-up:before {\n  content: \"\\f151\";\n}\n.fa-toggle-right:before,\n.fa-caret-square-o-right:before {\n  content: \"\\f152\";\n}\n.fa-euro:before,\n.fa-eur:before {\n  content: \"\\f153\";\n}\n.fa-gbp:before {\n  content: \"\\f154\";\n}\n.fa-dollar:before,\n.fa-usd:before {\n  content: \"\\f155\";\n}\n.fa-rupee:before,\n.fa-inr:before {\n  content: \"\\f156\";\n}\n.fa-cny:before,\n.fa-rmb:before,\n.fa-yen:before,\n.fa-jpy:before {\n  content: \"\\f157\";\n}\n.fa-ruble:before,\n.fa-rouble:before,\n.fa-rub:before {\n  content: \"\\f158\";\n}\n.fa-won:before,\n.fa-krw:before {\n  content: \"\\f159\";\n}\n.fa-bitcoin:before,\n.fa-btc:before {\n  content: \"\\f15a\";\n}\n.fa-file:before {\n  content: \"\\f15b\";\n}\n.fa-file-text:before {\n  content: \"\\f15c\";\n}\n.fa-sort-alpha-asc:before {\n  content: \"\\f15d\";\n}\n.fa-sort-alpha-desc:before {\n  content: \"\\f15e\";\n}\n.fa-sort-amount-asc:before {\n  content: \"\\f160\";\n}\n.fa-sort-amount-desc:before {\n  content: \"\\f161\";\n}\n.fa-sort-numeric-asc:before {\n  content: \"\\f162\";\n}\n.fa-sort-numeric-desc:before {\n  content: \"\\f163\";\n}\n.fa-thumbs-up:before {\n  content: \"\\f164\";\n}\n.fa-thumbs-down:before {\n  content: \"\\f165\";\n}\n.fa-youtube-square:before {\n  content: \"\\f166\";\n}\n.fa-youtube:before {\n  content: \"\\f167\";\n}\n.fa-xing:before {\n  content: \"\\f168\";\n}\n.fa-xing-square:before {\n  content: \"\\f169\";\n}\n.fa-youtube-play:before {\n  content: \"\\f16a\";\n}\n.fa-dropbox:before {\n  content: \"\\f16b\";\n}\n.fa-stack-overflow:before {\n  content: \"\\f16c\";\n}\n.fa-instagram:before {\n  content: \"\\f16d\";\n}\n.fa-flickr:before {\n  content: \"\\f16e\";\n}\n.fa-adn:before {\n  content: \"\\f170\";\n}\n.fa-bitbucket:before {\n  content: \"\\f171\";\n}\n.fa-bitbucket-square:before {\n  content: \"\\f172\";\n}\n.fa-tumblr:before {\n  content: \"\\f173\";\n}\n.fa-tumblr-square:before {\n  content: \"\\f174\";\n}\n.fa-long-arrow-down:before {\n  content: \"\\f175\";\n}\n.fa-long-arrow-up:before {\n  content: \"\\f176\";\n}\n.fa-long-arrow-left:before {\n  content: \"\\f177\";\n}\n.fa-long-arrow-right:before {\n  content: \"\\f178\";\n}\n.fa-apple:before {\n  content: \"\\f179\";\n}\n.fa-windows:before {\n  content: \"\\f17a\";\n}\n.fa-android:before {\n  content: \"\\f17b\";\n}\n.fa-linux:before {\n  content: \"\\f17c\";\n}\n.fa-dribbble:before {\n  content: \"\\f17d\";\n}\n.fa-skype:before {\n  content: \"\\f17e\";\n}\n.fa-foursquare:before {\n  content: \"\\f180\";\n}\n.fa-trello:before {\n  content: \"\\f181\";\n}\n.fa-female:before {\n  content: \"\\f182\";\n}\n.fa-male:before {\n  content: \"\\f183\";\n}\n.fa-gittip:before {\n  content: \"\\f184\";\n}\n.fa-sun-o:before {\n  content: \"\\f185\";\n}\n.fa-moon-o:before {\n  content: \"\\f186\";\n}\n.fa-archive:before {\n  content: \"\\f187\";\n}\n.fa-bug:before {\n  content: \"\\f188\";\n}\n.fa-vk:before {\n  content: \"\\f189\";\n}\n.fa-weibo:before {\n  content: \"\\f18a\";\n}\n.fa-renren:before {\n  content: \"\\f18b\";\n}\n.fa-pagelines:before {\n  content: \"\\f18c\";\n}\n.fa-stack-exchange:before {\n  content: \"\\f18d\";\n}\n.fa-arrow-circle-o-right:before {\n  content: \"\\f18e\";\n}\n.fa-arrow-circle-o-left:before {\n  content: \"\\f190\";\n}\n.fa-toggle-left:before,\n.fa-caret-square-o-left:before {\n  content: \"\\f191\";\n}\n.fa-dot-circle-o:before {\n  content: \"\\f192\";\n}\n.fa-wheelchair:before {\n  content: \"\\f193\";\n}\n.fa-vimeo-square:before {\n  content: \"\\f194\";\n}\n.fa-turkish-lira:before,\n.fa-try:before {\n  content: \"\\f195\";\n}\n.fa-plus-square-o:before {\n  content: \"\\f196\";\n}\n"
  },
  {
    "path": "_site/vendor.js",
    "content": "/*!\n * jQuery JavaScript Library v1.6.1\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: Thu May 12 15:04:36 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// (both of which we optimize for)\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// 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.1\",\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\t// Not own constructor property must be Object\n\t\tif ( obj.constructor &&\n\t\t\t!hasOwn.call(obj, \"constructor\") &&\n\t\t\t!hasOwn.call(obj.constructor.prototype, \"isPrototypeOf\") ) {\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\t// (xml & tmp used internally)\n\tparseXML: function( data , xml , tmp ) {\n\n\t\tif ( window.DOMParser ) { // Standard\n\t\t\ttmp = new DOMParser();\n\t\t\txml = tmp.parseFromString( data , \"text/xml\" );\n\t\t} else { // IE\n\t\t\txml = new ActiveXObject( \"Microsoft.XMLDOM\" );\n\t\t\txml.async = \"false\";\n\t\t\txml.loadXML( data );\n\t\t}\n\n\t\ttmp = xml.documentElement;\n\n\t\tif ( ! tmp || ! tmp.nodeName || tmp.nodeName === \"parsererror\" ) {\n\t\t\tjQuery.error( \"Invalid XML: \" + data );\n\t\t}\n\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\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\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 be optionally by executed if its 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\n// Expose jQuery to the global object\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 ]( 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\tbodyStyle,\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\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 click() {\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\tdiv.detachEvent( \"onclick\", click );\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\t// We use our own, invisible, body\n\tbody = document.createElement( \"body\" );\n\tbodyStyle = {\n\t\tvisibility: \"hidden\",\n\t\twidth: 0,\n\t\theight: 0,\n\t\tborder: 0,\n\t\tmargin: 0,\n\t\t// Set background to avoid IE crashes when removing (#9028)\n\t\tbackground: \"none\"\n\t};\n\tfor ( i in bodyStyle ) {\n\t\tbody.style[ i ] = bodyStyle[ i ];\n\t}\n\tbody.appendChild( div );\n\tdocumentElement.insertBefore( body, documentElement.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\tbody.innerHTML = \"\";\n\tdocumentElement.removeChild( body );\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\treturn support;\n})();\n\n// Keep track of boxModel\njQuery.boxModel = jQuery.support.boxModel;\n\n\n\n\nvar rbrace = /^(?:\\{.*\\}|\\[.*\\])$/,\n\trmultiDash = /([a-z])([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 internalKey = jQuery.expando, getByName = typeof name === \"string\", thisCache,\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 ][ 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\treturn getByName ? thisCache[ jQuery.camelCase( name ) ] : thisCache;\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 internalKey = jQuery.expando, isNode = 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\t\t\tvar thisCache = pvt ? cache[ id ][ internalKey ] : cache[ id ];\n\n\t\t\tif ( thisCache ) {\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\tif ( jQuery.support.deleteExpando || cache != window ) {\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\t\tvar name = \"data-\" + key.replace( rmultiDash, \"$1-$2\" ).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\trinvalidChar = /\\:/,\n\tformHook, 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\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function(i) {\n\t\t\t\tvar self = jQuery(this);\n\t\t\t\tself.addClass( value.call(this, i, self.attr(\"class\") || \"\") );\n\t\t\t});\n\t\t}\n\n\t\tif ( value && typeof value === \"string\" ) {\n\t\t\tvar classNames = (value || \"\").split( rspace );\n\n\t\t\tfor ( var i = 0, l = this.length; i < l; i++ ) {\n\t\t\t\tvar elem = this[i];\n\n\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\tif ( !elem.className ) {\n\t\t\t\t\t\telem.className = value;\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tvar className = \" \" + elem.className + \" \",\n\t\t\t\t\t\t\tsetClass = elem.className;\n\n\t\t\t\t\t\tfor ( var c = 0, cl = classNames.length; c < cl; c++ ) {\n\t\t\t\t\t\t\tif ( className.indexOf( \" \" + classNames[c] + \" \" ) < 0 ) {\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\tif ( jQuery.isFunction(value) ) {\n\t\t\treturn this.each(function(i) {\n\t\t\t\tvar self = jQuery(this);\n\t\t\t\tself.removeClass( value.call(this, i, self.attr(\"class\")) );\n\t\t\t});\n\t\t}\n\n\t\tif ( (value && typeof value === \"string\") || value === undefined ) {\n\t\t\tvar classNames = (value || \"\").split( rspace );\n\n\t\t\tfor ( var i = 0, l = this.length; i < l; i++ ) {\n\t\t\t\tvar elem = 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\tvar className = (\" \" + elem.className + \" \").replace(rclass, \" \");\n\t\t\t\t\t\tfor ( var 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\tvar self = jQuery(this);\n\t\t\t\tself.toggleClass( value.call(this, i, self.attr(\"class\"), 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].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\treturn (elem.value || \"\").replace(rreturn, \"\");\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\tname = notxml && jQuery.attrFix[ name ] || name;\n\n\t\thooks = jQuery.attrHooks[ name ];\n\n\t\tif ( !hooks ) {\n\t\t\t// Use boolHook for boolean attributes\n\t\t\tif ( rboolean.test( name ) &&\n\t\t\t\t(typeof value === \"boolean\" || value === undefined || value.toLowerCase() === name.toLowerCase()) ) {\n\n\t\t\t\thooks = boolHook;\n\n\t\t\t// Use formHook for forms and if the name contains certain characters\n\t\t\t} else if ( formHook && (jQuery.nodeName( elem, \"form\" ) || rinvalidChar.test( name )) ) {\n\t\t\t\thooks = formHook;\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 ) {\n\t\t\treturn hooks.get( elem, name );\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\t\t\n\t\t\tif ( jQuery.support.getSetAttribute ) {\n\t\t\t\t// Use removeAttribute in browsers that support it\n\t\t\t\telem.removeAttribute( name );\n\t\t\t} else {\n\t\t\t\tjQuery.attr( elem, name, \"\" );\n\t\t\t\telem.removeAttributeNode( elem.getAttributeNode( name ) );\n\t\t\t}\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\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\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\t// Try to normalize/fix the name\n\t\tname = notxml && jQuery.propFix[ name ] || name;\n\t\t\n\t\thooks = jQuery.propHooks[ name ];\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 )) !== undefined ) {\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});\n\n// Hook for boolean attributes\nboolHook = {\n\tget: function( elem, name ) {\n\t\t// Align boolean attributes with corresponding properties\n\t\treturn elem[ jQuery.propFix[ name ] || name ] ?\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 ] = value;\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// Use the value property for back compat\n// Use the formHook for button elements in IE6/7 (#1954)\njQuery.attrHooks.value = {\n\tget: function( elem, name ) {\n\t\tif ( formHook && jQuery.nodeName( elem, \"button\" ) ) {\n\t\t\treturn formHook.get( elem, name );\n\t\t}\n\t\treturn elem.value;\n\t},\n\tset: function( elem, value, name ) {\n\t\tif ( formHook && jQuery.nodeName( elem, \"button\" ) ) {\n\t\t\treturn formHook.set( elem, value, name );\n\t\t}\n\t\t// Does not return so that setAttribute is also used\n\t\telem.value = value;\n\t}\n};\n\n// IE6/7 do not support getting/setting some attributes with get/setAttribute\nif ( !jQuery.support.getSetAttribute ) {\n\n\t// propFix is more comprehensive and contains all fixes\n\tjQuery.attrFix = jQuery.propFix;\n\t\n\t// Use this for any attribute on a form in IE6/7\n\tformHook = jQuery.attrHooks.name = 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// Check form objects in IE (multiple bugs related)\n\t\t\t// Only use nodeValue if the attribute node exists on the form\n\t\t\tvar ret = elem.getAttributeNode( name );\n\t\t\tif ( ret ) {\n\t\t\t\tret.nodeValue = value;\n\t\t\t\treturn value;\n\t\t\t}\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}\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 hasOwn = Object.prototype.hasOwnProperty,\n\trnamespaces = /\\.(.*)$/,\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 ? 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 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\t// Check if mouse(over|out) are still within the same parent element\n\tvar parent = event.relatedTarget;\n\n\t// set the correct event type\n\tevent.type = event.data;\n\n\t// Firefox sometimes assigns relatedTarget a XUL element\n\t// which we cannot access the parentNode property of\n\ttry {\n\n\t\t// Chrome does something similar, the parentNode property\n\t\t// can be accessed but is null.\n\t\tif ( parent && parent !== document && !parent.parentNode ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Traverse up the tree\n\t\twhile ( parent && parent !== this ) {\n\t\t\tparent = parent.parentNode;\n\t\t}\n\n\t\tif ( parent !== this ) {\n\t\t\t// handle event if we actually just moused on to a non sub-element\n\t\t\tjQuery.event.handle.apply( this, arguments );\n\t\t}\n\n\t// assuming we've left the element since we most likely mousedover a xul element\n\t} catch(e) { }\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\tvar elem = e.target,\n\t\t\t\t\t\ttype = 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 = 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 = elem.type, val = 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\t\tif ( !elem || typeof elem === \"string\" ) {\n\t\t\treturn jQuery.inArray( this[0],\n\t\t\t\t// If it receives a string, the selector is used\n\t\t\t\t// If it receives nothing, the siblings are used\n\t\t\t\telem ? jQuery( elem ) : this.parent().children() );\n\t\t}\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,\n\t\tdoc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);\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 ( elem.getElementsByTagName ) {\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\tcloneFixAttributes( srcElements[i], destElements[i] );\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\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\trdashAlpha = /-([a-z])/ig,\n\t// fixed for IE9, see #8346\n\trupper = /([A-Z]|^ms)/g,\n\trnumpx = /^-?\\d+(?:px)?$/i,\n\trnum = /^-?\\d/,\n\trrelNum = /^[+\\-]=/,\n\trrelNumFilter = /[^+\\-\\.\\de]+/g,\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\n\tfcamelCase = function( all, letter ) {\n\t\treturn letter.toUpperCase();\n\t};\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\"zIndex\": true,\n\t\t\"fontWeight\": true,\n\t\t\"opacity\": true,\n\t\t\"zoom\": true,\n\t\t\"lineHeight\": true,\n\t\t\"widows\": true,\n\t\t\"orphans\": 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// Make sure that NaN and null values aren't set. See: #7116\n\t\t\tif ( type === \"number\" && isNaN( value ) || value == null ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// convert relative number strings (+= or -=) to relative numbers. #7345\n\t\t\tif ( type === \"string\" && rrelNum.test( value ) ) {\n\t\t\t\tvalue = +value.replace( rrelNumFilter, \"\" ) + parseFloat( jQuery.css( elem, name ) );\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\tcamelCase: function( string ) {\n\t\treturn string.replace( rdashAlpha, fcamelCase );\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\tval = getWH( elem, name, extra );\n\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\tif ( val <= 0 ) {\n\t\t\t\t\tval = curCSS( elem, name, name );\n\n\t\t\t\t\tif ( val === \"0px\" && currentStyle ) {\n\t\t\t\t\t\tval = currentStyle( elem, name, name );\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( val != null ) {\n\t\t\t\t\t\t// Should return \"auto\" instead of 0, use 0 for\n\t\t\t\t\t\t// temporary backwards-compat\n\t\t\t\t\t\treturn val === \"\" || val === \"auto\" ? \"0px\" : val;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( val < 0 || val == null ) {\n\t\t\t\t\tval = elem.style[ name ];\n\n\t\t\t\t\t// Should return \"auto\" instead of 0, use 0 for\n\t\t\t\t\t// temporary backwards-compat\n\t\t\t\t\treturn val === \"\" || val === \"auto\" ? \"0px\" : val;\n\t\t\t\t}\n\n\t\t\t\treturn typeof val === \"string\" ? val : val + \"px\";\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\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// Set the alpha filter to set the opacity\n\t\t\tvar opacity = jQuery.isNaN( value ) ?\n\t\t\t\t\"\" :\n\t\t\t\t\"alpha(opacity=\" + value * 100 + \")\",\n\t\t\t\tfilter = currentStyle && currentStyle.filter || style.filter || \"\";\n\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\tvar which = name === \"width\" ? cssWidth : cssHeight,\n\t\tval = name === \"width\" ? elem.offsetWidth : elem.offsetHeight;\n\n\tif ( extra === \"border\" ) {\n\t\treturn val;\n\t}\n\n\tjQuery.each( which, function() {\n\t\tif ( !extra ) {\n\t\t\tval -= parseFloat(jQuery.css( elem, \"padding\" + this )) || 0;\n\t\t}\n\n\t\tif ( extra === \"margin\" ) {\n\t\t\tval += parseFloat(jQuery.css( elem, \"margin\" + this )) || 0;\n\n\t\t} else {\n\t\t\tval -= parseFloat(jQuery.css( elem, \"border\" + this + \"Width\" )) || 0;\n\t\t}\n\t});\n\n\treturn val;\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|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|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\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\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// Only one parameter, we extend ajaxSettings\n\t\t\tsettings = target;\n\t\t\ttarget = jQuery.extend( true, jQuery.ajaxSettings, settings );\n\t\t} else {\n\t\t\t// target was provided, we extend into it\n\t\t\tjQuery.extend( true, target, jQuery.ajaxSettings, settings );\n\t\t}\n\t\t// Flatten fields we don't want deep extended\n\t\tfor( var field in { context: 1, url: 1 } ) {\n\t\t\tif ( field in settings ) {\n\t\t\t\ttarget[ field ] = settings[ field ];\n\t\t\t} else if( field in jQuery.ajaxSettings ) {\n\t\t\t\ttarget[ field ] = jQuery.ajaxSettings[ field ];\n\t\t\t}\n\t\t}\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\"*\": \"*/*\"\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\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, statusText, 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 ? 4 : 0;\n\n\t\t\tvar isSuccess,\n\t\t\t\tsuccess,\n\t\t\t\terror,\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 = 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}\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 ] !== \"*\" ? \", */*; 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 ( status < 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\trequestAnimationFrame = window.webkitRequestAnimationFrame ||\n\t    window.mozRequestAnimationFrame ||\n\t    window.oRequestAnimationFrame;\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 ( 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\n\t\t\tif ( jQuery.isFunction( opt.old ) ) {\n\t\t\t\topt.old.call( 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\t\t\traf;\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\t// Use requestAnimationFrame instead of setInterval if available\n\t\t\tif ( requestAnimationFrame ) {\n\t\t\t\ttimerId = 1;\n\t\t\t\traf = function() {\n\t\t\t\t\t// When timerId gets set to null at any point, this stops\n\t\t\t\t\tif ( timerId ) {\n\t\t\t\t\t\trequestAnimationFrame( raf );\n\t\t\t\t\t\tfx.tick();\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\trequestAnimationFrame( raf );\n\t\t\t} else {\n\t\t\t\ttimerId = setInterval( fx.tick, fx.interval );\n\t\t\t}\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 elem = 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\tdocument.body.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( \"<!doctype><html><body></body></html>\" );\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\tdocument.body.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 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\treturn this[0] ?\n\t\t\tparseFloat( jQuery.css( this[0], type, \"padding\" ) ) :\n\t\t\tnull;\n\t};\n\n\t// outerHeight and outerWidth\n\tjQuery.fn[\"outer\" + name] = function( margin ) {\n\t\treturn this[0] ?\n\t\t\tparseFloat( jQuery.css( this[0], 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\treturn elem.document.compatMode === \"CSS1Compat\" && docElemProp ||\n\t\t\t\telem.document.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\nwindow.jQuery = window.$ = jQuery;\n})(window);\n(function() {\n\n\tvar joey = this.joey = function joey(elementDef, parentNode) {\n\t\treturn createNode( elementDef, parentNode, parentNode ? parentNode.ownerDocument : this.document );\n\t};\n\n\tvar shortcuts = joey.shortcuts = {\n\t\t\"text\" : \"textContent\",\n\t\t\"cls\" : \"className\"\n\t};\n\n\tvar plugins = joey.plugins = [\n\t\tfunction( obj, context ) {\n\t\t\tif( typeof obj === 'string' ) {\n\t\t\t\treturn context.createTextNode( obj );\n\t\t\t}\n\t\t},\n\t\tfunction( obj, context ) {\n\t\t\tif( \"tag\" in obj ) {\n\t\t\t\tvar el = context.createElement( obj.tag );\n\t\t\t\tfor( var attr in obj ) {\n\t\t\t\t\taddAttr( el, attr, obj[ attr ], context );\n\t\t\t\t}\n\t\t\t\treturn el;\n\t\t\t}\n\t\t}\n\t];\n\n\tfunction addAttr( el, attr, value, context ) {\n\t\tattr = shortcuts[attr] || attr;\n\t\tif( attr === 'children' ) {\n\t\t\tfor( var i = 0; i < value.length; i++) {\n\t\t\t\tcreateNode( value[i], el, context );\n\t\t\t}\n\t\t} else if( attr === 'style' || attr === 'dataset' ) {\n\t\t\tfor( var prop in value ) {\n\t\t\t\tel[ attr ][ prop ] = value[ prop ];\n\t\t\t}\n\t\t} else if( attr.indexOf(\"on\") === 0 ) {\n\t\t\tel.addEventListener( attr.substr(2), value, false );\n\t\t} else if( value !== undefined ) {\n\t\t\tel[ attr ] = value;\n\t\t}\n\t}\n\n\tfunction createNode( obj, parent, context ) {\n\t\tvar el;\n\t\tif( obj != null ) {\n\t\t\tplugins.some( function( plug ) {\n\t\t\t\treturn ( el = plug( obj, context ) );\n\t\t\t});\n\t\t\tparent && parent.appendChild( el );\n\t\t\treturn el;\n\t\t}\n\t}\n\n}());\n\n(function($, document) {\n\n\tvar create = $.create = (function() {\n\n\t\tfunction addAttrs( el, obj, context ) {\n\t\t\tfor( var attr in obj ){\n\t\t\t\tswitch( attr ) {\n\t\t\t\tcase 'tag' :\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'html' :\n\t\t\t\t\tel.innerHTML = obj[ attr ];\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'css' :\n\t\t\t\t\tfor( var style in obj.css ) {\n\t\t\t\t\t\t$.attr( el.style, style, obj.css[ style ] );\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'text' : case 'child' : case 'children' :\n\t\t\t\t\tcreateNode( obj[attr], el, context );\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'cls' :\n\t\t\t\t\tel.className = obj[attr];\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'data' :\n\t\t\t\t\tfor( var data in obj.data ) {\n\t\t\t\t\t\t$.data( el, data, obj.data[data] );\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tdefault :\n\t\t\t\t\tif( attr.indexOf(\"on\") === 0 && $.isFunction(obj[attr]) ) {\n\t\t\t\t\t\t$.event.add( el, attr.substr(2).replace(/^[A-Z]/, function(a) { return a.toLowerCase(); }), obj[attr] );\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$.attr( el, attr, obj[attr] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfunction createNode(obj, parent, context) {\n\t\t\tif(obj && ($.isArray(obj) || obj instanceof $)) {\n\t\t\t\tfor(var ret = [], i = 0; i < obj.length; i++) {\n\t\t\t\t\tvar newNode = createNode(obj[i], parent, context);\n\t\t\t\t\tif(newNode) {\n\t\t\t\t\t\tret.push(newNode);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t\tvar el;\n\t\t\tif(typeof(obj) === 'string') {\n\t\t\t\tel = context.createTextNode( obj );\n\t\t\t} else if(!obj) {\n\t\t\t\treturn undefined;\n\t\t\t} else if(obj.nodeType === 1) {\n\t\t\t\tel = obj;\n\t\t\t} else if( obj instanceof app.ui.AbstractWidget ) {\n\t\t\t\tel = obj.el[0];\n\t\t\t} else {\n\t\t\t\tel = context.createElement( obj.tag || 'DIV' );\n\t\t\t\taddAttrs(el, obj, context);\n\t\t\t}\n\t\t\tif(parent){ parent.appendChild(el); }\n\t\t\treturn el;\n\t\t}\n\n\t\treturn function(elementDef, parentNode) {\n\t\t\treturn createNode(elementDef, parentNode, (parentNode && parentNode.ownerDocument) || document);\n\t\t};\n\t\t\n\t})();\n\t\n\n\t// inject create into jquery internals so object definitions are treated as first class constructors (overrides non-public methods)\n\tvar clean = $.clean,\n\t\tinit = $.fn.init;\n\n\t$.clean = function( elems, context, fragment, scripts ) {\n\t\tfor(var i = 0; i < elems.length; i++) {\n\t\t\tif( elems[i].tag || elems[i] instanceof app.ui.AbstractWidget ) {\n\t\t\t\telems[i] = create( elems[i], null, context );\n\t\t\t}\n\t\t}\n\t\treturn clean( elems, context, fragment, scripts );\n\t};\n\n\t$.fn.init = function( selector, context, rootjQuery ) {\n\t\tif ( selector && ( selector.tag || selector instanceof app.ui.AbstractWidget )) {\n\t\t\tselector = create( selector, null, context );\n\t\t}\n\t\treturn init.call( this, selector, context, rootjQuery );\n\t};\n\n\t$.fn.init.prototype = $.fn;\n\n})(jQuery, window.document);\n\n\n/*!\n * Raphael 1.5.2 - JavaScript Vector Library\n *\n * Copyright (c) 2010 Dmitry Baranovskiy (http://raphaeljs.com)\n * Licensed under the MIT (http://raphaeljs.com/license.html) license.\n * from fork at git@github.com:mobz/g.raphael.git\n */\n(function () {\n    function R() {\n        if (R.is(arguments[0], array)) {\n            var a = arguments[0],\n                cnv = create[apply](R, a.splice(0, 3 + R.is(a[0], nu))),\n                res = cnv.set();\n            for (var i = 0, ii = a[length]; i < ii; i++) {\n                var j = a[i] || {};\n                elements[has](j.type) && res[push](cnv[j.type]().attr(j));\n            }\n            return res;\n        }\n        return create[apply](R, arguments);\n    }\n    R.version = \"1.5.2\";\n    var separator = /[, ]+/,\n        elements = {circle: 1, rect: 1, path: 1, ellipse: 1, text: 1, image: 1},\n        formatrg = /\\{(\\d+)\\}/g,\n        proto = \"prototype\",\n        has = \"hasOwnProperty\",\n        doc = document,\n        win = window,\n        oldRaphael = {\n            was: Object[proto][has].call(win, \"Raphael\"),\n            is: win.Raphael\n        },\n        Paper = function () {\n            this.customAttributes = {};\n        },\n        paperproto,\n        appendChild = \"appendChild\",\n        apply = \"apply\",\n        concat = \"concat\",\n        supportsTouch = \"createTouch\" in doc,\n        E = \"\",\n        S = \" \",\n        Str = String,\n        split = \"split\",\n        events = \"click dblclick mousedown mousemove mouseout mouseover mouseup touchstart touchmove touchend orientationchange touchcancel gesturestart gesturechange gestureend\"[split](S),\n        touchMap = {\n            mousedown: \"touchstart\",\n            mousemove: \"touchmove\",\n            mouseup: \"touchend\"\n        },\n        join = \"join\",\n        length = \"length\",\n        lowerCase = Str[proto].toLowerCase,\n        math = Math,\n        mmax = math.max,\n        mmin = math.min,\n        abs = math.abs,\n        pow = math.pow,\n        PI = math.PI,\n        nu = \"number\",\n        string = \"string\",\n        array = \"array\",\n        toString = \"toString\",\n        fillString = \"fill\",\n        objectToString = Object[proto][toString],\n        paper = {},\n        push = \"push\",\n        ISURL = /^url\\(['\"]?([^\\)]+?)['\"]?\\)$/i,\n        colourRegExp = /^\\s*((#[a-f\\d]{6})|(#[a-f\\d]{3})|rgba?\\(\\s*([\\d\\.]+%?\\s*,\\s*[\\d\\.]+%?\\s*,\\s*[\\d\\.]+(?:%?\\s*,\\s*[\\d\\.]+)?)%?\\s*\\)|hsba?\\(\\s*([\\d\\.]+(?:deg|\\xb0|%)?\\s*,\\s*[\\d\\.]+%?\\s*,\\s*[\\d\\.]+(?:%?\\s*,\\s*[\\d\\.]+)?)%?\\s*\\)|hsla?\\(\\s*([\\d\\.]+(?:deg|\\xb0|%)?\\s*,\\s*[\\d\\.]+%?\\s*,\\s*[\\d\\.]+(?:%?\\s*,\\s*[\\d\\.]+)?)%?\\s*\\))\\s*$/i,\n        isnan = {\"NaN\": 1, \"Infinity\": 1, \"-Infinity\": 1},\n        bezierrg = /^(?:cubic-)?bezier\\(([^,]+),([^,]+),([^,]+),([^\\)]+)\\)/,\n        round = math.round,\n        setAttribute = \"setAttribute\",\n        toFloat = parseFloat,\n        toInt = parseInt,\n        ms = \" progid:DXImageTransform.Microsoft\",\n        upperCase = Str[proto].toUpperCase,\n        availableAttrs = {blur: 0, \"clip-rect\": \"0 0 1e9 1e9\", cursor: \"default\", cx: 0, cy: 0, fill: \"#fff\", \"fill-opacity\": 1, font: '10px \"Arial\"', \"font-family\": '\"Arial\"', \"font-size\": \"10\", \"font-style\": \"normal\", \"font-weight\": 400, gradient: 0, height: 0, href: \"http://raphaeljs.com/\", opacity: 1, path: \"M0,0\", r: 0, rotation: 0, rx: 0, ry: 0, scale: \"1 1\", src: \"\", stroke: \"#000\", \"stroke-dasharray\": \"\", \"stroke-linecap\": \"butt\", \"stroke-linejoin\": \"butt\", \"stroke-miterlimit\": 0, \"stroke-opacity\": 1, \"stroke-width\": 1, target: \"_blank\", \"text-anchor\": \"middle\", title: \"Raphael\", translation: \"0 0\", width: 0, x: 0, y: 0},\n        availableAnimAttrs = {along: \"along\", blur: nu, \"clip-rect\": \"csv\", cx: nu, cy: nu, fill: \"colour\", \"fill-opacity\": nu, \"font-size\": nu, height: nu, opacity: nu, path: \"path\", r: nu, rotation: \"csv\", rx: nu, ry: nu, scale: \"csv\", stroke: \"colour\", \"stroke-opacity\": nu, \"stroke-width\": nu, translation: \"csv\", width: nu, x: nu, y: nu},\n        rp = \"replace\",\n        animKeyFrames= /^(from|to|\\d+%?)$/,\n        commaSpaces = /\\s*,\\s*/,\n        hsrg = {hs: 1, rg: 1},\n        p2s = /,?([achlmqrstvxz]),?/gi,\n        pathCommand = /([achlmqstvz])[\\s,]*((-?\\d*\\.?\\d*(?:e[-+]?\\d+)?\\s*,?\\s*)+)/ig,\n        pathValues = /(-?\\d*\\.?\\d*(?:e[-+]?\\d+)?)\\s*,?\\s*/ig,\n        radial_gradient = /^r(?:\\(([^,]+?)\\s*,\\s*([^\\)]+?)\\))?/,\n        sortByKey = function (a, b) {\n            return a.key - b.key;\n        };\n\n    R.type = (win.SVGAngle || doc.implementation.hasFeature(\"http://www.w3.org/TR/SVG11/feature#BasicStructure\", \"1.1\") ? \"SVG\" : \"VML\");\n    if (R.type == \"VML\") {\n        var d = doc.createElement(\"div\"),\n            b;\n        d.innerHTML = '<v:shape adj=\"1\"/>';\n        b = d.firstChild;\n        b.style.behavior = \"url(#default#VML)\";\n        if (!(b && typeof b.adj == \"object\")) {\n            return R.type = null;\n        }\n        d = null;\n    }\n    R.svg = !(R.vml = R.type == \"VML\");\n    Paper[proto] = R[proto];\n    paperproto = Paper[proto];\n    R._id = 0;\n    R._oid = 0;\n    R.fn = {};\n    R.is = function (o, type) {\n        type = lowerCase.call(type);\n        if (type == \"finite\") {\n            return !isnan[has](+o);\n        }\n        return  (type == \"null\" && o === null) ||\n                (type == typeof o) ||\n                (type == \"object\" && o === Object(o)) ||\n                (type == \"array\" && Array.isArray && Array.isArray(o)) ||\n                objectToString.call(o).slice(8, -1).toLowerCase() == type;\n    };\n    R.angle = function (x1, y1, x2, y2, x3, y3) {\n        if (x3 == null) {\n            var x = x1 - x2,\n                y = y1 - y2;\n            if (!x && !y) {\n                return 0;\n            }\n            return ((x < 0) * 180 + math.atan(-y / -x) * 180 / PI + 360) % 360;\n        } else {\n            return R.angle(x1, y1, x3, y3) - R.angle(x2, y2, x3, y3);\n        }\n    };\n    R.rad = function (deg) {\n        return deg % 360 * PI / 180;\n    };\n    R.deg = function (rad) {\n        return rad * 180 / PI % 360;\n    };\n    R.snapTo = function (values, value, tolerance) {\n        tolerance = R.is(tolerance, \"finite\") ? tolerance : 10;\n        if (R.is(values, array)) {\n            var i = values.length;\n            while (i--) if (abs(values[i] - value) <= tolerance) {\n                return values[i];\n            }\n        } else {\n            values = +values;\n            var rem = value % values;\n            if (rem < tolerance) {\n                return value - rem;\n            }\n            if (rem > values - tolerance) {\n                return value - rem + values;\n            }\n        }\n        return value;\n    };\n    function createUUID() {\n        // http://www.ietf.org/rfc/rfc4122.txt\n        var s = [],\n            i = 0;\n        for (; i < 32; i++) {\n            s[i] = (~~(math.random() * 16))[toString](16);\n        }\n        s[12] = 4;  // bits 12-15 of the time_hi_and_version field to 0010\n        s[16] = ((s[16] & 3) | 8)[toString](16);  // bits 6-7 of the clock_seq_hi_and_reserved to 01\n        return \"r-\" + s[join](\"\");\n    }\n\n    R.setWindow = function (newwin) {\n        win = newwin;\n        doc = win.document;\n    };\n    // colour utilities\n    var toHex = function (color) {\n        if (R.vml) {\n            // http://dean.edwards.name/weblog/2009/10/convert-any-colour-value-to-hex-in-msie/\n            var trim = /^\\s+|\\s+$/g;\n            var bod;\n            try {\n                var docum = new ActiveXObject(\"htmlfile\");\n                docum.write(\"<body>\");\n                docum.close();\n                bod = docum.body;\n            } catch(e) {\n                bod = createPopup().document.body;\n            }\n            var range = bod.createTextRange();\n            toHex = cacher(function (color) {\n                try {\n                    bod.style.color = Str(color)[rp](trim, E);\n                    var value = range.queryCommandValue(\"ForeColor\");\n                    value = ((value & 255) << 16) | (value & 65280) | ((value & 16711680) >>> 16);\n                    return \"#\" + (\"000000\" + value[toString](16)).slice(-6);\n                } catch(e) {\n                    return \"none\";\n                }\n            });\n        } else {\n            var i = doc.createElement(\"i\");\n            i.title = \"Rapha\\xebl Colour Picker\";\n            i.style.display = \"none\";\n            doc.body[appendChild](i);\n            toHex = cacher(function (color) {\n                i.style.color = color;\n                return doc.defaultView.getComputedStyle(i, E).getPropertyValue(\"color\");\n            });\n        }\n        return toHex(color);\n    },\n    hsbtoString = function () {\n        return \"hsb(\" + [this.h, this.s, this.b] + \")\";\n    },\n    hsltoString = function () {\n        return \"hsl(\" + [this.h, this.s, this.l] + \")\";\n    },\n    rgbtoString = function () {\n        return this.hex;\n    };\n    R.hsb2rgb = function (h, s, b, o) {\n        if (R.is(h, \"object\") && \"h\" in h && \"s\" in h && \"b\" in h) {\n            b = h.b;\n            s = h.s;\n            h = h.h;\n            o = h.o;\n        }\n        return R.hsl2rgb(h, s, b / 2, o);\n    };\n    R.hsl2rgb = function (h, s, l, o) {\n        if (R.is(h, \"object\") && \"h\" in h && \"s\" in h && \"l\" in h) {\n            l = h.l;\n            s = h.s;\n            h = h.h;\n        }\n        if (h > 1 || s > 1 || l > 1) {\n            h /= 360;\n            s /= 100;\n            l /= 100;\n        }\n        var rgb = {},\n            channels = [\"r\", \"g\", \"b\"],\n            t2, t1, t3, r, g, b;\n        if (!s) {\n            rgb = {\n                r: l,\n                g: l,\n                b: l\n            };\n        } else {\n            if (l < .5) {\n                t2 = l * (1 + s);\n            } else {\n                t2 = l + s - l * s;\n            }\n            t1 = 2 * l - t2;\n            for (var i = 0; i < 3; i++) {\n                t3 = h + 1 / 3 * -(i - 1);\n                t3 < 0 && t3++;\n                t3 > 1 && t3--;\n                if (t3 * 6 < 1) {\n                    rgb[channels[i]] = t1 + (t2 - t1) * 6 * t3;\n                } else if (t3 * 2 < 1) {\n                    rgb[channels[i]] = t2;\n                } else if (t3 * 3 < 2) {\n                    rgb[channels[i]] = t1 + (t2 - t1) * (2 / 3 - t3) * 6;\n                } else {\n                    rgb[channels[i]] = t1;\n                }\n            }\n        }\n        rgb.r *= 255;\n        rgb.g *= 255;\n        rgb.b *= 255;\n        rgb.hex = \"#\" + (16777216 | rgb.b | (rgb.g << 8) | (rgb.r << 16)).toString(16).slice(1);\n        R.is(o, \"finite\") && (rgb.opacity = o);\n        rgb.toString = rgbtoString;\n        return rgb;\n    };\n    R.rgb2hsb = function (red, green, blue) {\n        if (green == null && R.is(red, \"object\") && \"r\" in red && \"g\" in red && \"b\" in red) {\n            blue = red.b;\n            green = red.g;\n            red = red.r;\n        }\n        if (green == null && R.is(red, string)) {\n            var clr = R.getRGB(red);\n            red = clr.r;\n            green = clr.g;\n            blue = clr.b;\n        }\n        if (red > 1 || green > 1 || blue > 1) {\n            red /= 255;\n            green /= 255;\n            blue /= 255;\n        }\n        var max = mmax(red, green, blue),\n            min = mmin(red, green, blue),\n            hue,\n            saturation,\n            brightness = max;\n        if (min == max) {\n            return {h: 0, s: 0, b: max, toString: hsbtoString};\n        } else {\n            var delta = (max - min);\n            saturation = delta / max;\n            if (red == max) {\n                hue = (green - blue) / delta;\n            } else if (green == max) {\n                hue = 2 + ((blue - red) / delta);\n            } else {\n                hue = 4 + ((red - green) / delta);\n            }\n            hue /= 6;\n            hue < 0 && hue++;\n            hue > 1 && hue--;\n        }\n        return {h: hue, s: saturation, b: brightness, toString: hsbtoString};\n    };\n    R.rgb2hsl = function (red, green, blue) {\n        if (green == null && R.is(red, \"object\") && \"r\" in red && \"g\" in red && \"b\" in red) {\n            blue = red.b;\n            green = red.g;\n            red = red.r;\n        }\n        if (green == null && R.is(red, string)) {\n            var clr = R.getRGB(red);\n            red = clr.r;\n            green = clr.g;\n            blue = clr.b;\n        }\n        if (red > 1 || green > 1 || blue > 1) {\n            red /= 255;\n            green /= 255;\n            blue /= 255;\n        }\n        var max = mmax(red, green, blue),\n            min = mmin(red, green, blue),\n            h,\n            s,\n            l = (max + min) / 2,\n            hsl;\n        if (min == max) {\n            hsl =  {h: 0, s: 0, l: l};\n        } else {\n            var delta = max - min;\n            s = l < .5 ? delta / (max + min) : delta / (2 - max - min);\n            if (red == max) {\n                h = (green - blue) / delta;\n            } else if (green == max) {\n                h = 2 + (blue - red) / delta;\n            } else {\n                h = 4 + (red - green) / delta;\n            }\n            h /= 6;\n            h < 0 && h++;\n            h > 1 && h--;\n            hsl = {h: h, s: s, l: l};\n        }\n        hsl.toString = hsltoString;\n        return hsl;\n    };\n    R._path2string = function () {\n        return this.join(\",\")[rp](p2s, \"$1\");\n    };\n    function cacher(f, scope, postprocessor) {\n        function newf() {\n            var arg = Array[proto].slice.call(arguments, 0),\n                args = arg[join](\"\\u25ba\"),\n                cache = newf.cache = newf.cache || {},\n                count = newf.count = newf.count || [];\n            if (cache[has](args)) {\n                return postprocessor ? postprocessor(cache[args]) : cache[args];\n            }\n            count[length] >= 1e3 && delete cache[count.shift()];\n            count[push](args);\n            cache[args] = f[apply](scope, arg);\n            return postprocessor ? postprocessor(cache[args]) : cache[args];\n        }\n        return newf;\n    }\n \n    R.getRGB = cacher(function (colour) {\n        if (!colour || !!((colour = Str(colour)).indexOf(\"-\") + 1)) {\n            return {r: -1, g: -1, b: -1, hex: \"none\", error: 1};\n        }\n        if (colour == \"none\") {\n            return {r: -1, g: -1, b: -1, hex: \"none\"};\n        }\n        !(hsrg[has](colour.toLowerCase().substring(0, 2)) || colour.charAt() == \"#\") && (colour = toHex(colour));\n        var res,\n            red,\n            green,\n            blue,\n            opacity,\n            t,\n            values,\n            rgb = colour.match(colourRegExp);\n        if (rgb) {\n            if (rgb[2]) {\n                blue = toInt(rgb[2].substring(5), 16);\n                green = toInt(rgb[2].substring(3, 5), 16);\n                red = toInt(rgb[2].substring(1, 3), 16);\n            }\n            if (rgb[3]) {\n                blue = toInt((t = rgb[3].charAt(3)) + t, 16);\n                green = toInt((t = rgb[3].charAt(2)) + t, 16);\n                red = toInt((t = rgb[3].charAt(1)) + t, 16);\n            }\n            if (rgb[4]) {\n                values = rgb[4][split](commaSpaces);\n                red = toFloat(values[0]);\n                values[0].slice(-1) == \"%\" && (red *= 2.55);\n                green = toFloat(values[1]);\n                values[1].slice(-1) == \"%\" && (green *= 2.55);\n                blue = toFloat(values[2]);\n                values[2].slice(-1) == \"%\" && (blue *= 2.55);\n                rgb[1].toLowerCase().slice(0, 4) == \"rgba\" && (opacity = toFloat(values[3]));\n                values[3] && values[3].slice(-1) == \"%\" && (opacity /= 100);\n            }\n            if (rgb[5]) {\n                values = rgb[5][split](commaSpaces);\n                red = toFloat(values[0]);\n                values[0].slice(-1) == \"%\" && (red *= 2.55);\n                green = toFloat(values[1]);\n                values[1].slice(-1) == \"%\" && (green *= 2.55);\n                blue = toFloat(values[2]);\n                values[2].slice(-1) == \"%\" && (blue *= 2.55);\n                (values[0].slice(-3) == \"deg\" || values[0].slice(-1) == \"\\xb0\") && (red /= 360);\n                rgb[1].toLowerCase().slice(0, 4) == \"hsba\" && (opacity = toFloat(values[3]));\n                values[3] && values[3].slice(-1) == \"%\" && (opacity /= 100);\n                return R.hsb2rgb(red, green, blue, opacity);\n            }\n            if (rgb[6]) {\n                values = rgb[6][split](commaSpaces);\n                red = toFloat(values[0]);\n                values[0].slice(-1) == \"%\" && (red *= 2.55);\n                green = toFloat(values[1]);\n                values[1].slice(-1) == \"%\" && (green *= 2.55);\n                blue = toFloat(values[2]);\n                values[2].slice(-1) == \"%\" && (blue *= 2.55);\n                (values[0].slice(-3) == \"deg\" || values[0].slice(-1) == \"\\xb0\") && (red /= 360);\n                rgb[1].toLowerCase().slice(0, 4) == \"hsla\" && (opacity = toFloat(values[3]));\n                values[3] && values[3].slice(-1) == \"%\" && (opacity /= 100);\n                return R.hsl2rgb(red, green, blue, opacity);\n            }\n            rgb = {r: red, g: green, b: blue};\n            rgb.hex = \"#\" + (16777216 | blue | (green << 8) | (red << 16)).toString(16).slice(1);\n            R.is(opacity, \"finite\") && (rgb.opacity = opacity);\n            return rgb;\n        }\n        return {r: -1, g: -1, b: -1, hex: \"none\", error: 1};\n    }, R);\n    R.getColor = function (value) {\n        var start = this.getColor.start = this.getColor.start || {h: 0, s: 1, b: value || .75},\n            rgb = this.hsb2rgb(start.h, start.s, start.b);\n        start.h += .075;\n        if (start.h > 1) {\n            start.h = 0;\n            start.s -= .2;\n            start.s <= 0 && (this.getColor.start = {h: 0, s: 1, b: start.b});\n        }\n        return rgb.hex;\n    };\n    R.getColor.reset = function () {\n        delete this.start;\n    };\n    // path utilities\n    R.parsePathString = cacher(function (pathString) {\n        if (!pathString) {\n            return null;\n        }\n        var paramCounts = {a: 7, c: 6, h: 1, l: 2, m: 2, q: 4, s: 4, t: 2, v: 1, z: 0},\n            data = [];\n        if (R.is(pathString, array) && R.is(pathString[0], array)) { // rough assumption\n            data = pathClone(pathString);\n        }\n        if (!data[length]) {\n            Str(pathString)[rp](pathCommand, function (a, b, c) {\n                var params = [],\n                    name = lowerCase.call(b);\n                c[rp](pathValues, function (a, b) {\n                    b && params[push](+b);\n                });\n                if (name == \"m\" && params[length] > 2) {\n                    data[push]([b][concat](params.splice(0, 2)));\n                    name = \"l\";\n                    b = b == \"m\" ? \"l\" : \"L\";\n                }\n                while (params[length] >= paramCounts[name]) {\n                    data[push]([b][concat](params.splice(0, paramCounts[name])));\n                    if (!paramCounts[name]) {\n                        break;\n                    }\n                }\n            });\n        }\n        data[toString] = R._path2string;\n        return data;\n    });\n    R.findDotsAtSegment = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) {\n        var t1 = 1 - t,\n            x = pow(t1, 3) * p1x + pow(t1, 2) * 3 * t * c1x + t1 * 3 * t * t * c2x + pow(t, 3) * p2x,\n            y = pow(t1, 3) * p1y + pow(t1, 2) * 3 * t * c1y + t1 * 3 * t * t * c2y + pow(t, 3) * p2y,\n            mx = p1x + 2 * t * (c1x - p1x) + t * t * (c2x - 2 * c1x + p1x),\n            my = p1y + 2 * t * (c1y - p1y) + t * t * (c2y - 2 * c1y + p1y),\n            nx = c1x + 2 * t * (c2x - c1x) + t * t * (p2x - 2 * c2x + c1x),\n            ny = c1y + 2 * t * (c2y - c1y) + t * t * (p2y - 2 * c2y + c1y),\n            ax = (1 - t) * p1x + t * c1x,\n            ay = (1 - t) * p1y + t * c1y,\n            cx = (1 - t) * c2x + t * p2x,\n            cy = (1 - t) * c2y + t * p2y,\n            alpha = (90 - math.atan((mx - nx) / (my - ny)) * 180 / PI);\n        (mx > nx || my < ny) && (alpha += 180);\n        return {x: x, y: y, m: {x: mx, y: my}, n: {x: nx, y: ny}, start: {x: ax, y: ay}, end: {x: cx, y: cy}, alpha: alpha};\n    };\n    var pathDimensions = cacher(function (path) {\n        if (!path) {\n            return {x: 0, y: 0, width: 0, height: 0};\n        }\n        path = path2curve(path);\n        var x = 0, \n            y = 0,\n            X = [],\n            Y = [],\n            p;\n        for (var i = 0, ii = path[length]; i < ii; i++) {\n            p = path[i];\n            if (p[0] == \"M\") {\n                x = p[1];\n                y = p[2];\n                X[push](x);\n                Y[push](y);\n            } else {\n                var dim = curveDim(x, y, p[1], p[2], p[3], p[4], p[5], p[6]);\n                X = X[concat](dim.min.x, dim.max.x);\n                Y = Y[concat](dim.min.y, dim.max.y);\n                x = p[5];\n                y = p[6];\n            }\n        }\n        var xmin = mmin[apply](0, X),\n            ymin = mmin[apply](0, Y);\n        return {\n            x: xmin,\n            y: ymin,\n            width: mmax[apply](0, X) - xmin,\n            height: mmax[apply](0, Y) - ymin\n        };\n    }),\n        pathClone = function (pathArray) {\n            var res = [];\n            if (!R.is(pathArray, array) || !R.is(pathArray && pathArray[0], array)) { // rough assumption\n                pathArray = R.parsePathString(pathArray);\n            }\n            for (var i = 0, ii = pathArray[length]; i < ii; i++) {\n                res[i] = [];\n                for (var j = 0, jj = pathArray[i][length]; j < jj; j++) {\n                    res[i][j] = pathArray[i][j];\n                }\n            }\n            res[toString] = R._path2string;\n            return res;\n        },\n        pathToRelative = cacher(function (pathArray) {\n            if (!R.is(pathArray, array) || !R.is(pathArray && pathArray[0], array)) { // rough assumption\n                pathArray = R.parsePathString(pathArray);\n            }\n            var res = [],\n                x = 0,\n                y = 0,\n                mx = 0,\n                my = 0,\n                start = 0;\n            if (pathArray[0][0] == \"M\") {\n                x = pathArray[0][1];\n                y = pathArray[0][2];\n                mx = x;\n                my = y;\n                start++;\n                res[push]([\"M\", x, y]);\n            }\n            for (var i = start, ii = pathArray[length]; i < ii; i++) {\n                var r = res[i] = [],\n                    pa = pathArray[i];\n                if (pa[0] != lowerCase.call(pa[0])) {\n                    r[0] = lowerCase.call(pa[0]);\n                    switch (r[0]) {\n                        case \"a\":\n                            r[1] = pa[1];\n                            r[2] = pa[2];\n                            r[3] = pa[3];\n                            r[4] = pa[4];\n                            r[5] = pa[5];\n                            r[6] = +(pa[6] - x).toFixed(3);\n                            r[7] = +(pa[7] - y).toFixed(3);\n                            break;\n                        case \"v\":\n                            r[1] = +(pa[1] - y).toFixed(3);\n                            break;\n                        case \"m\":\n                            mx = pa[1];\n                            my = pa[2];\n                        default:\n                            for (var j = 1, jj = pa[length]; j < jj; j++) {\n                                r[j] = +(pa[j] - ((j % 2) ? x : y)).toFixed(3);\n                            }\n                    }\n                } else {\n                    r = res[i] = [];\n                    if (pa[0] == \"m\") {\n                        mx = pa[1] + x;\n                        my = pa[2] + y;\n                    }\n                    for (var k = 0, kk = pa[length]; k < kk; k++) {\n                        res[i][k] = pa[k];\n                    }\n                }\n                var len = res[i][length];\n                switch (res[i][0]) {\n                    case \"z\":\n                        x = mx;\n                        y = my;\n                        break;\n                    case \"h\":\n                        x += +res[i][len - 1];\n                        break;\n                    case \"v\":\n                        y += +res[i][len - 1];\n                        break;\n                    default:\n                        x += +res[i][len - 2];\n                        y += +res[i][len - 1];\n                }\n            }\n            res[toString] = R._path2string;\n            return res;\n        }, 0, pathClone),\n        pathToAbsolute = cacher(function (pathArray) {\n            if (!R.is(pathArray, array) || !R.is(pathArray && pathArray[0], array)) { // rough assumption\n                pathArray = R.parsePathString(pathArray);\n            }\n            var res = [],\n                x = 0,\n                y = 0,\n                mx = 0,\n                my = 0,\n                start = 0;\n            if (pathArray[0][0] == \"M\") {\n                x = +pathArray[0][1];\n                y = +pathArray[0][2];\n                mx = x;\n                my = y;\n                start++;\n                res[0] = [\"M\", x, y];\n            }\n            for (var i = start, ii = pathArray[length]; i < ii; i++) {\n                var r = res[i] = [],\n                    pa = pathArray[i];\n                if (pa[0] != upperCase.call(pa[0])) {\n                    r[0] = upperCase.call(pa[0]);\n                    switch (r[0]) {\n                        case \"A\":\n                            r[1] = pa[1];\n                            r[2] = pa[2];\n                            r[3] = pa[3];\n                            r[4] = pa[4];\n                            r[5] = pa[5];\n                            r[6] = +(pa[6] + x);\n                            r[7] = +(pa[7] + y);\n                            break;\n                        case \"V\":\n                            r[1] = +pa[1] + y;\n                            break;\n                        case \"H\":\n                            r[1] = +pa[1] + x;\n                            break;\n                        case \"M\":\n                            mx = +pa[1] + x;\n                            my = +pa[2] + y;\n                        default:\n                            for (var j = 1, jj = pa[length]; j < jj; j++) {\n                                r[j] = +pa[j] + ((j % 2) ? x : y);\n                            }\n                    }\n                } else {\n                    for (var k = 0, kk = pa[length]; k < kk; k++) {\n                        res[i][k] = pa[k];\n                    }\n                }\n                switch (r[0]) {\n                    case \"Z\":\n                        x = mx;\n                        y = my;\n                        break;\n                    case \"H\":\n                        x = r[1];\n                        break;\n                    case \"V\":\n                        y = r[1];\n                        break;\n                    case \"M\":\n                        mx = res[i][res[i][length] - 2];\n                        my = res[i][res[i][length] - 1];\n                    default:\n                        x = res[i][res[i][length] - 2];\n                        y = res[i][res[i][length] - 1];\n                }\n            }\n            res[toString] = R._path2string;\n            return res;\n        }, null, pathClone),\n        l2c = function (x1, y1, x2, y2) {\n            return [x1, y1, x2, y2, x2, y2];\n        },\n        q2c = function (x1, y1, ax, ay, x2, y2) {\n            var _13 = 1 / 3,\n                _23 = 2 / 3;\n            return [\n                    _13 * x1 + _23 * ax,\n                    _13 * y1 + _23 * ay,\n                    _13 * x2 + _23 * ax,\n                    _13 * y2 + _23 * ay,\n                    x2,\n                    y2\n                ];\n        },\n        a2c = function (x1, y1, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2, recursive) {\n            // for more information of where this math came from visit:\n            // http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes\n            var _120 = PI * 120 / 180,\n                rad = PI / 180 * (+angle || 0),\n                res = [],\n                xy,\n                rotate = cacher(function (x, y, rad) {\n                    var X = x * math.cos(rad) - y * math.sin(rad),\n                        Y = x * math.sin(rad) + y * math.cos(rad);\n                    return {x: X, y: Y};\n                });\n            if (!recursive) {\n                xy = rotate(x1, y1, -rad);\n                x1 = xy.x;\n                y1 = xy.y;\n                xy = rotate(x2, y2, -rad);\n                x2 = xy.x;\n                y2 = xy.y;\n                var cos = math.cos(PI / 180 * angle),\n                    sin = math.sin(PI / 180 * angle),\n                    x = (x1 - x2) / 2,\n                    y = (y1 - y2) / 2;\n                var h = (x * x) / (rx * rx) + (y * y) / (ry * ry);\n                if (h > 1) {\n                    h = math.sqrt(h);\n                    rx = h * rx;\n                    ry = h * ry;\n                }\n                var rx2 = rx * rx,\n                    ry2 = ry * ry,\n                    k = (large_arc_flag == sweep_flag ? -1 : 1) *\n                        math.sqrt(abs((rx2 * ry2 - rx2 * y * y - ry2 * x * x) / (rx2 * y * y + ry2 * x * x))),\n                    cx = k * rx * y / ry + (x1 + x2) / 2,\n                    cy = k * -ry * x / rx + (y1 + y2) / 2,\n                    f1 = math.asin(((y1 - cy) / ry).toFixed(9)),\n                    f2 = math.asin(((y2 - cy) / ry).toFixed(9));\n\n                f1 = x1 < cx ? PI - f1 : f1;\n                f2 = x2 < cx ? PI - f2 : f2;\n                f1 < 0 && (f1 = PI * 2 + f1);\n                f2 < 0 && (f2 = PI * 2 + f2);\n                if (sweep_flag && f1 > f2) {\n                    f1 = f1 - PI * 2;\n                }\n                if (!sweep_flag && f2 > f1) {\n                    f2 = f2 - PI * 2;\n                }\n            } else {\n                f1 = recursive[0];\n                f2 = recursive[1];\n                cx = recursive[2];\n                cy = recursive[3];\n            }\n            var df = f2 - f1;\n            if (abs(df) > _120) {\n                var f2old = f2,\n                    x2old = x2,\n                    y2old = y2;\n                f2 = f1 + _120 * (sweep_flag && f2 > f1 ? 1 : -1);\n                x2 = cx + rx * math.cos(f2);\n                y2 = cy + ry * math.sin(f2);\n                res = a2c(x2, y2, rx, ry, angle, 0, sweep_flag, x2old, y2old, [f2, f2old, cx, cy]);\n            }\n            df = f2 - f1;\n            var c1 = math.cos(f1),\n                s1 = math.sin(f1),\n                c2 = math.cos(f2),\n                s2 = math.sin(f2),\n                t = math.tan(df / 4),\n                hx = 4 / 3 * rx * t,\n                hy = 4 / 3 * ry * t,\n                m1 = [x1, y1],\n                m2 = [x1 + hx * s1, y1 - hy * c1],\n                m3 = [x2 + hx * s2, y2 - hy * c2],\n                m4 = [x2, y2];\n            m2[0] = 2 * m1[0] - m2[0];\n            m2[1] = 2 * m1[1] - m2[1];\n            if (recursive) {\n                return [m2, m3, m4][concat](res);\n            } else {\n                res = [m2, m3, m4][concat](res)[join]()[split](\",\");\n                var newres = [];\n                for (var i = 0, ii = res[length]; i < ii; i++) {\n                    newres[i] = i % 2 ? rotate(res[i - 1], res[i], rad).y : rotate(res[i], res[i + 1], rad).x;\n                }\n                return newres;\n            }\n        },\n        findDotAtSegment = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) {\n            var t1 = 1 - t;\n            return {\n                x: pow(t1, 3) * p1x + pow(t1, 2) * 3 * t * c1x + t1 * 3 * t * t * c2x + pow(t, 3) * p2x,\n                y: pow(t1, 3) * p1y + pow(t1, 2) * 3 * t * c1y + t1 * 3 * t * t * c2y + pow(t, 3) * p2y\n            };\n        },\n        curveDim = cacher(function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y) {\n            var a = (c2x - 2 * c1x + p1x) - (p2x - 2 * c2x + c1x),\n                b = 2 * (c1x - p1x) - 2 * (c2x - c1x),\n                c = p1x - c1x,\n                t1 = (-b + math.sqrt(b * b - 4 * a * c)) / 2 / a,\n                t2 = (-b - math.sqrt(b * b - 4 * a * c)) / 2 / a,\n                y = [p1y, p2y],\n                x = [p1x, p2x],\n                dot;\n            abs(t1) > \"1e12\" && (t1 = .5);\n            abs(t2) > \"1e12\" && (t2 = .5);\n            if (t1 > 0 && t1 < 1) {\n                dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t1);\n                x[push](dot.x);\n                y[push](dot.y);\n            }\n            if (t2 > 0 && t2 < 1) {\n                dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t2);\n                x[push](dot.x);\n                y[push](dot.y);\n            }\n            a = (c2y - 2 * c1y + p1y) - (p2y - 2 * c2y + c1y);\n            b = 2 * (c1y - p1y) - 2 * (c2y - c1y);\n            c = p1y - c1y;\n            t1 = (-b + math.sqrt(b * b - 4 * a * c)) / 2 / a;\n            t2 = (-b - math.sqrt(b * b - 4 * a * c)) / 2 / a;\n            abs(t1) > \"1e12\" && (t1 = .5);\n            abs(t2) > \"1e12\" && (t2 = .5);\n            if (t1 > 0 && t1 < 1) {\n                dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t1);\n                x[push](dot.x);\n                y[push](dot.y);\n            }\n            if (t2 > 0 && t2 < 1) {\n                dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t2);\n                x[push](dot.x);\n                y[push](dot.y);\n            }\n            return {\n                min: {x: mmin[apply](0, x), y: mmin[apply](0, y)},\n                max: {x: mmax[apply](0, x), y: mmax[apply](0, y)}\n            };\n        }),\n        path2curve = cacher(function (path, path2) {\n            var p = pathToAbsolute(path),\n                p2 = path2 && pathToAbsolute(path2),\n                attrs = {x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null},\n                attrs2 = {x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null},\n                processPath = function (path, d) {\n                    var nx, ny;\n                    if (!path) {\n                        return [\"C\", d.x, d.y, d.x, d.y, d.x, d.y];\n                    }\n                    !(path[0] in {T:1, Q:1}) && (d.qx = d.qy = null);\n                    switch (path[0]) {\n                        case \"M\":\n                            d.X = path[1];\n                            d.Y = path[2];\n                            break;\n                        case \"A\":\n                            path = [\"C\"][concat](a2c[apply](0, [d.x, d.y][concat](path.slice(1))));\n                            break;\n                        case \"S\":\n                            nx = d.x + (d.x - (d.bx || d.x));\n                            ny = d.y + (d.y - (d.by || d.y));\n                            path = [\"C\", nx, ny][concat](path.slice(1));\n                            break;\n                        case \"T\":\n                            d.qx = d.x + (d.x - (d.qx || d.x));\n                            d.qy = d.y + (d.y - (d.qy || d.y));\n                            path = [\"C\"][concat](q2c(d.x, d.y, d.qx, d.qy, path[1], path[2]));\n                            break;\n                        case \"Q\":\n                            d.qx = path[1];\n                            d.qy = path[2];\n                            path = [\"C\"][concat](q2c(d.x, d.y, path[1], path[2], path[3], path[4]));\n                            break;\n                        case \"L\":\n                            path = [\"C\"][concat](l2c(d.x, d.y, path[1], path[2]));\n                            break;\n                        case \"H\":\n                            path = [\"C\"][concat](l2c(d.x, d.y, path[1], d.y));\n                            break;\n                        case \"V\":\n                            path = [\"C\"][concat](l2c(d.x, d.y, d.x, path[1]));\n                            break;\n                        case \"Z\":\n                            path = [\"C\"][concat](l2c(d.x, d.y, d.X, d.Y));\n                            break;\n                    }\n                    return path;\n                },\n                fixArc = function (pp, i) {\n                    if (pp[i][length] > 7) {\n                        pp[i].shift();\n                        var pi = pp[i];\n                        while (pi[length]) {\n                            pp.splice(i++, 0, [\"C\"][concat](pi.splice(0, 6)));\n                        }\n                        pp.splice(i, 1);\n                        ii = mmax(p[length], p2 && p2[length] || 0);\n                    }\n                },\n                fixM = function (path1, path2, a1, a2, i) {\n                    if (path1 && path2 && path1[i][0] == \"M\" && path2[i][0] != \"M\") {\n                        path2.splice(i, 0, [\"M\", a2.x, a2.y]);\n                        a1.bx = 0;\n                        a1.by = 0;\n                        a1.x = path1[i][1];\n                        a1.y = path1[i][2];\n                        ii = mmax(p[length], p2 && p2[length] || 0);\n                    }\n                };\n            for (var i = 0, ii = mmax(p[length], p2 && p2[length] || 0); i < ii; i++) {\n                p[i] = processPath(p[i], attrs);\n                fixArc(p, i);\n                p2 && (p2[i] = processPath(p2[i], attrs2));\n                p2 && fixArc(p2, i);\n                fixM(p, p2, attrs, attrs2, i);\n                fixM(p2, p, attrs2, attrs, i);\n                var seg = p[i],\n                    seg2 = p2 && p2[i],\n                    seglen = seg[length],\n                    seg2len = p2 && seg2[length];\n                attrs.x = seg[seglen - 2];\n                attrs.y = seg[seglen - 1];\n                attrs.bx = toFloat(seg[seglen - 4]) || attrs.x;\n                attrs.by = toFloat(seg[seglen - 3]) || attrs.y;\n                attrs2.bx = p2 && (toFloat(seg2[seg2len - 4]) || attrs2.x);\n                attrs2.by = p2 && (toFloat(seg2[seg2len - 3]) || attrs2.y);\n                attrs2.x = p2 && seg2[seg2len - 2];\n                attrs2.y = p2 && seg2[seg2len - 1];\n            }\n            return p2 ? [p, p2] : p;\n        }, null, pathClone),\n        parseDots = cacher(function (gradient) {\n            var dots = [];\n            for (var i = 0, ii = gradient[length]; i < ii; i++) {\n                var dot = {},\n                    par = gradient[i].match(/^([^:]*):?([\\d\\.]*)/);\n                dot.color = R.getRGB(par[1]);\n                if (dot.color.error) {\n                    return null;\n                }\n                dot.color = dot.color.hex;\n                par[2] && (dot.offset = par[2] + \"%\");\n                dots[push](dot);\n            }\n            for (i = 1, ii = dots[length] - 1; i < ii; i++) {\n                if (!dots[i].offset) {\n                    var start = toFloat(dots[i - 1].offset || 0),\n                        end = 0;\n                    for (var j = i + 1; j < ii; j++) {\n                        if (dots[j].offset) {\n                            end = dots[j].offset;\n                            break;\n                        }\n                    }\n                    if (!end) {\n                        end = 100;\n                        j = ii;\n                    }\n                    end = toFloat(end);\n                    var d = (end - start) / (j - i + 1);\n                    for (; i < j; i++) {\n                        start += d;\n                        dots[i].offset = start + \"%\";\n                    }\n                }\n            }\n            return dots;\n        }),\n        getContainer = function (x, y, w, h) {\n            var container;\n            if (R.is(x, string) || R.is(x, \"object\")) {\n                container = R.is(x, string) ? doc.getElementById(x) : x;\n                if (container.tagName) {\n                    if (y == null) {\n                        return {\n                            container: container,\n                            width: container.style.pixelWidth || container.offsetWidth,\n                            height: container.style.pixelHeight || container.offsetHeight\n                        };\n                    } else {\n                        return {container: container, width: y, height: w};\n                    }\n                }\n            } else {\n                return {container: 1, x: x, y: y, width: w, height: h};\n            }\n        },\n        plugins = function (con, add) {\n            var that = this;\n            for (var prop in add) {\n                if (add[has](prop) && !(prop in con)) {\n                    switch (typeof add[prop]) {\n                        case \"function\":\n                            (function (f) {\n                                con[prop] = con === that ? f : function () { return f[apply](that, arguments); };\n                            })(add[prop]);\n                        break;\n                        case \"object\":\n                            con[prop] = con[prop] || {};\n                            plugins.call(this, con[prop], add[prop]);\n                        break;\n                        default:\n                            con[prop] = add[prop];\n                        break;\n                    }\n                }\n            }\n        },\n        tear = function (el, paper) {\n            el == paper.top && (paper.top = el.prev);\n            el == paper.bottom && (paper.bottom = el.next);\n            el.next && (el.next.prev = el.prev);\n            el.prev && (el.prev.next = el.next);\n        },\n        tofront = function (el, paper) {\n            if (paper.top === el) {\n                return;\n            }\n            tear(el, paper);\n            el.next = null;\n            el.prev = paper.top;\n            paper.top.next = el;\n            paper.top = el;\n        },\n        toback = function (el, paper) {\n            if (paper.bottom === el) {\n                return;\n            }\n            tear(el, paper);\n            el.next = paper.bottom;\n            el.prev = null;\n            paper.bottom.prev = el;\n            paper.bottom = el;\n        },\n        insertafter = function (el, el2, paper) {\n            tear(el, paper);\n            el2 == paper.top && (paper.top = el);\n            el2.next && (el2.next.prev = el);\n            el.next = el2.next;\n            el.prev = el2;\n            el2.next = el;\n        },\n        insertbefore = function (el, el2, paper) {\n            tear(el, paper);\n            el2 == paper.bottom && (paper.bottom = el);\n            el2.prev && (el2.prev.next = el);\n            el.prev = el2.prev;\n            el2.prev = el;\n            el.next = el2;\n        },\n        removed = function (methodname) {\n            return function () {\n                throw new Error(\"Rapha\\xebl: you are calling to method \\u201c\" + methodname + \"\\u201d of removed object\");\n            };\n        };\n    R.pathToRelative = pathToRelative;\n    // SVG\n    if (R.svg) {\n        paperproto.svgns = \"http://www.w3.org/2000/svg\";\n        paperproto.xlink = \"http://www.w3.org/1999/xlink\";\n        round = function (num) {\n            return +num + (~~num === num) * .5;\n        };\n        var $ = function (el, attr) {\n            if (attr) {\n                for (var key in attr) {\n                    if (attr[has](key)) {\n                        el[setAttribute](key, Str(attr[key]));\n                    }\n                }\n            } else {\n                el = doc.createElementNS(paperproto.svgns, el);\n                el.style.webkitTapHighlightColor = \"rgba(0,0,0,0)\";\n                return el;\n            }\n        };\n        R[toString] = function () {\n            return  \"Your browser supports SVG.\\nYou are running Rapha\\xebl \" + this.version;\n        };\n        var thePath = function (pathString, SVG) {\n            var el = $(\"path\");\n            SVG.canvas && SVG.canvas[appendChild](el);\n            var p = new Element(el, SVG);\n            p.type = \"path\";\n            setFillAndStroke(p, {fill: \"none\", stroke: \"#000\", path: pathString});\n            return p;\n        };\n        var addGradientFill = function (o, gradient, SVG) {\n            var type = \"linear\",\n                fx = .5, fy = .5,\n                s = o.style;\n            gradient = Str(gradient)[rp](radial_gradient, function (all, _fx, _fy) {\n                type = \"radial\";\n                if (_fx && _fy) {\n                    fx = toFloat(_fx);\n                    fy = toFloat(_fy);\n                    var dir = ((fy > .5) * 2 - 1);\n                    pow(fx - .5, 2) + pow(fy - .5, 2) > .25 &&\n                        (fy = math.sqrt(.25 - pow(fx - .5, 2)) * dir + .5) &&\n                        fy != .5 &&\n                        (fy = fy.toFixed(5) - 1e-5 * dir);\n                }\n                return E;\n            });\n            gradient = gradient[split](/\\s*\\-\\s*/);\n            if (type == \"linear\") {\n                var angle = gradient.shift();\n                angle = -toFloat(angle);\n                if (isNaN(angle)) {\n                    return null;\n                }\n                var vector = [0, 0, math.cos(angle * PI / 180), math.sin(angle * PI / 180)],\n                    max = 1 / (mmax(abs(vector[2]), abs(vector[3])) || 1);\n                vector[2] *= max;\n                vector[3] *= max;\n                if (vector[2] < 0) {\n                    vector[0] = -vector[2];\n                    vector[2] = 0;\n                }\n                if (vector[3] < 0) {\n                    vector[1] = -vector[3];\n                    vector[3] = 0;\n                }\n            }\n            var dots = parseDots(gradient);\n            if (!dots) {\n                return null;\n            }\n            var id = o.getAttribute(fillString);\n            id = id.match(/^url\\(#(.*)\\)$/);\n            id && SVG.defs.removeChild(doc.getElementById(id[1]));\n\n            var el = $(type + \"Gradient\");\n            el.id = createUUID();\n            $(el, type == \"radial\" ? {fx: fx, fy: fy} : {x1: vector[0], y1: vector[1], x2: vector[2], y2: vector[3]});\n            SVG.defs[appendChild](el);\n            for (var i = 0, ii = dots[length]; i < ii; i++) {\n                var stop = $(\"stop\");\n                $(stop, {\n                    offset: dots[i].offset ? dots[i].offset : !i ? \"0%\" : \"100%\",\n                    \"stop-color\": dots[i].color || \"#fff\"\n                });\n                el[appendChild](stop);\n            }\n            $(o, {\n                fill: \"url(#\" + el.id + \")\",\n                opacity: 1,\n                \"fill-opacity\": 1\n            });\n            s.fill = E;\n            s.opacity = 1;\n            s.fillOpacity = 1;\n            return 1;\n        };\n        var updatePosition = function (o) {\n            var bbox = o.getBBox();\n            $(o.pattern, {patternTransform: R.format(\"translate({0},{1})\", bbox.x, bbox.y)});\n        };\n        var setFillAndStroke = function (o, params) {\n            var dasharray = {\n                    \"\": [0],\n                    \"none\": [0],\n                    \"-\": [3, 1],\n                    \".\": [1, 1],\n                    \"-.\": [3, 1, 1, 1],\n                    \"-..\": [3, 1, 1, 1, 1, 1],\n                    \". \": [1, 3],\n                    \"- \": [4, 3],\n                    \"--\": [8, 3],\n                    \"- .\": [4, 3, 1, 3],\n                    \"--.\": [8, 3, 1, 3],\n                    \"--..\": [8, 3, 1, 3, 1, 3]\n                },\n                node = o.node,\n                attrs = o.attrs,\n                rot = o.rotate(),\n                addDashes = function (o, value) {\n                    value = dasharray[lowerCase.call(value)];\n                    if (value) {\n                        var width = o.attrs[\"stroke-width\"] || \"1\",\n                            butt = {round: width, square: width, butt: 0}[o.attrs[\"stroke-linecap\"] || params[\"stroke-linecap\"]] || 0,\n                            dashes = [];\n                        var i = value[length];\n                        while (i--) {\n                            dashes[i] = value[i] * width + ((i % 2) ? 1 : -1) * butt;\n                        }\n                        $(node, {\"stroke-dasharray\": dashes[join](\",\")});\n                    }\n                };\n            params[has](\"rotation\") && (rot = params.rotation);\n            var rotxy = Str(rot)[split](separator);\n            if (!(rotxy.length - 1)) {\n                rotxy = null;\n            } else {\n                rotxy[1] = +rotxy[1];\n                rotxy[2] = +rotxy[2];\n            }\n            toFloat(rot) && o.rotate(0, true);\n            for (var att in params) {\n                if (params[has](att)) {\n                    if (!availableAttrs[has](att)) {\n                        continue;\n                    }\n                    var value = params[att];\n                    attrs[att] = value;\n                    switch (att) {\n                        case \"blur\":\n                            o.blur(value);\n                            break;\n                        case \"rotation\":\n                            o.rotate(value, true);\n                            break;\n                        case \"href\":\n                        case \"title\":\n                        case \"target\":\n                            var pn = node.parentNode;\n                            if (lowerCase.call(pn.tagName) != \"a\") {\n                                var hl = $(\"a\");\n                                pn.insertBefore(hl, node);\n                                hl[appendChild](node);\n                                pn = hl;\n                            }\n                            if (att == \"target\" && value == \"blank\") {\n                                pn.setAttributeNS(o.paper.xlink, \"show\", \"new\");\n                            } else {\n                                pn.setAttributeNS(o.paper.xlink, att, value);\n                            }\n                            break;\n                        case \"cursor\":\n                            node.style.cursor = value;\n                            break;\n                        case \"clip-rect\":\n                            var rect = Str(value)[split](separator);\n                            if (rect[length] == 4) {\n                                o.clip && o.clip.parentNode.parentNode.removeChild(o.clip.parentNode);\n                                var el = $(\"clipPath\"),\n                                    rc = $(\"rect\");\n                                el.id = createUUID();\n                                $(rc, {\n                                    x: rect[0],\n                                    y: rect[1],\n                                    width: rect[2],\n                                    height: rect[3]\n                                });\n                                el[appendChild](rc);\n                                o.paper.defs[appendChild](el);\n                                $(node, {\"clip-path\": \"url(#\" + el.id + \")\"});\n                                o.clip = rc;\n                            }\n                            if (!value) {\n                                var clip = doc.getElementById(node.getAttribute(\"clip-path\")[rp](/(^url\\(#|\\)$)/g, E));\n                                clip && clip.parentNode.removeChild(clip);\n                                $(node, {\"clip-path\": E});\n                                delete o.clip;\n                            }\n                        break;\n                        case \"path\":\n                            if (o.type == \"path\") {\n                                $(node, {d: value ? attrs.path = pathToAbsolute(value) : \"M0,0\"});\n                            }\n                            break;\n                        case \"width\":\n                            node[setAttribute](att, value);\n                            if (attrs.fx) {\n                                att = \"x\";\n                                value = attrs.x;\n                            } else {\n                                break;\n                            }\n                        case \"x\":\n                            if (attrs.fx) {\n                                value = -attrs.x - (attrs.width || 0);\n                            }\n                        case \"rx\":\n                            if (att == \"rx\" && o.type == \"rect\") {\n                                break;\n                            }\n                        case \"cx\":\n                            rotxy && (att == \"x\" || att == \"cx\") && (rotxy[1] += value - attrs[att]);\n                            node[setAttribute](att, value);\n                            o.pattern && updatePosition(o);\n                            break;\n                        case \"height\":\n                            node[setAttribute](att, value);\n                            if (attrs.fy) {\n                                att = \"y\";\n                                value = attrs.y;\n                            } else {\n                                break;\n                            }\n                        case \"y\":\n                            if (attrs.fy) {\n                                value = -attrs.y - (attrs.height || 0);\n                            }\n                        case \"ry\":\n                            if (att == \"ry\" && o.type == \"rect\") {\n                                break;\n                            }\n                        case \"cy\":\n                            rotxy && (att == \"y\" || att == \"cy\") && (rotxy[2] += value - attrs[att]);\n                            node[setAttribute](att, value);\n                            o.pattern && updatePosition(o);\n                            break;\n                        case \"r\":\n                            if (o.type == \"rect\") {\n                                $(node, {rx: value, ry: value});\n                            } else {\n                                node[setAttribute](att, value);\n                            }\n                            break;\n                        case \"src\":\n                            if (o.type == \"image\") {\n                                node.setAttributeNS(o.paper.xlink, \"href\", value);\n                            }\n                            break;\n                        case \"stroke-width\":\n                            node.style.strokeWidth = value;\n                            // Need following line for Firefox\n                            node[setAttribute](att, value);\n                            if (attrs[\"stroke-dasharray\"]) {\n                                addDashes(o, attrs[\"stroke-dasharray\"]);\n                            }\n                            break;\n                        case \"stroke-dasharray\":\n                            addDashes(o, value);\n                            break;\n                        case \"translation\":\n                            var xy = Str(value)[split](separator);\n                            xy[0] = +xy[0] || 0;\n                            xy[1] = +xy[1] || 0;\n                            if (rotxy) {\n                                rotxy[1] += xy[0];\n                                rotxy[2] += xy[1];\n                            }\n                            translate.call(o, xy[0], xy[1]);\n                            break;\n                        case \"scale\":\n                            xy = Str(value)[split](separator);\n                            o.scale(+xy[0] || 1, +xy[1] || +xy[0] || 1, isNaN(toFloat(xy[2])) ? null : +xy[2], isNaN(toFloat(xy[3])) ? null : +xy[3]);\n                            break;\n                        case fillString:\n                            var isURL = Str(value).match(ISURL);\n                            if (isURL) {\n                                el = $(\"pattern\");\n                                var ig = $(\"image\");\n                                el.id = createUUID();\n                                $(el, {x: 0, y: 0, patternUnits: \"userSpaceOnUse\", height: 1, width: 1});\n                                $(ig, {x: 0, y: 0});\n                                ig.setAttributeNS(o.paper.xlink, \"href\", isURL[1]);\n                                el[appendChild](ig);\n \n                                var img = doc.createElement(\"img\");\n                                img.style.cssText = \"position:absolute;left:-9999em;top-9999em\";\n                                img.onload = function () {\n                                    $(el, {width: this.offsetWidth, height: this.offsetHeight});\n                                    $(ig, {width: this.offsetWidth, height: this.offsetHeight});\n                                    doc.body.removeChild(this);\n                                    o.paper.safari();\n                                };\n                                doc.body[appendChild](img);\n                                img.src = isURL[1];\n                                o.paper.defs[appendChild](el);\n                                node.style.fill = \"url(#\" + el.id + \")\";\n                                $(node, {fill: \"url(#\" + el.id + \")\"});\n                                o.pattern = el;\n                                o.pattern && updatePosition(o);\n                                break;\n                            }\n                            var clr = R.getRGB(value);\n                            if (!clr.error) {\n                                delete params.gradient;\n                                delete attrs.gradient;\n                                !R.is(attrs.opacity, \"undefined\") &&\n                                    R.is(params.opacity, \"undefined\") &&\n                                    $(node, {opacity: attrs.opacity});\n                                !R.is(attrs[\"fill-opacity\"], \"undefined\") &&\n                                    R.is(params[\"fill-opacity\"], \"undefined\") &&\n                                    $(node, {\"fill-opacity\": attrs[\"fill-opacity\"]});\n                            } else if ((({circle: 1, ellipse: 1})[has](o.type) || Str(value).charAt() != \"r\") && addGradientFill(node, value, o.paper)) {\n                                attrs.gradient = value;\n                                attrs.fill = \"none\";\n                                break;\n                            }\n                            clr[has](\"opacity\") && $(node, {\"fill-opacity\": clr.opacity > 1 ? clr.opacity / 100 : clr.opacity});\n                        case \"stroke\":\n                            clr = R.getRGB(value);\n                            node[setAttribute](att, clr.hex);\n                            att == \"stroke\" && clr[has](\"opacity\") && $(node, {\"stroke-opacity\": clr.opacity > 1 ? clr.opacity / 100 : clr.opacity});\n                            break;\n                        case \"gradient\":\n                            (({circle: 1, ellipse: 1})[has](o.type) || Str(value).charAt() != \"r\") && addGradientFill(node, value, o.paper);\n                            break;\n                        case \"opacity\":\n                            if (attrs.gradient && !attrs[has](\"stroke-opacity\")) {\n                                $(node, {\"stroke-opacity\": value > 1 ? value / 100 : value});\n                            }\n                            // fall\n                        case \"fill-opacity\":\n                            if (attrs.gradient) {\n                                var gradient = doc.getElementById(node.getAttribute(fillString)[rp](/^url\\(#|\\)$/g, E));\n                                if (gradient) {\n                                    var stops = gradient.getElementsByTagName(\"stop\");\n                                    stops[stops[length] - 1][setAttribute](\"stop-opacity\", value);\n                                }\n                                break;\n                            }\n                        default:\n                            att == \"font-size\" && (value = toInt(value, 10) + \"px\");\n                            var cssrule = att[rp](/(\\-.)/g, function (w) {\n                                return upperCase.call(w.substring(1));\n                            });\n                            node.style[cssrule] = value;\n                            // Need following line for Firefox\n                            node[setAttribute](att, value);\n                            break;\n                    }\n                }\n            }\n            \n            tuneText(o, params);\n            if (rotxy) {\n                o.rotate(rotxy.join(S));\n            } else {\n                toFloat(rot) && o.rotate(rot, true);\n            }\n        };\n        var leading = 1.2,\n        tuneText = function (el, params) {\n            if (el.type != \"text\" || !(params[has](\"text\") || params[has](\"font\") || params[has](\"font-size\") || params[has](\"x\") || params[has](\"y\"))) {\n                return;\n            }\n            var a = el.attrs,\n                node = el.node,\n                fontSize = node.firstChild ? toInt(doc.defaultView.getComputedStyle(node.firstChild, E).getPropertyValue(\"font-size\"), 10) : 10;\n \n            if (params[has](\"text\")) {\n                a.text = params.text;\n                while (node.firstChild) {\n                    node.removeChild(node.firstChild);\n                }\n                var texts = Str(params.text)[split](\"\\n\");\n                for (var i = 0, ii = texts[length]; i < ii; i++) if (texts[i]) {\n                    var tspan = $(\"tspan\");\n                    i && $(tspan, {dy: fontSize * leading, x: a.x});\n                    tspan[appendChild](doc.createTextNode(texts[i]));\n                    node[appendChild](tspan);\n                }\n            } else {\n                texts = node.getElementsByTagName(\"tspan\");\n                for (i = 0, ii = texts[length]; i < ii; i++) {\n                    i && $(texts[i], {dy: fontSize * leading, x: a.x});\n                }\n            }\n            $(node, {y: a.y});\n            var bb = el.getBBox(),\n                dif = a.y - (bb.y + bb.height / 2);\n            dif && R.is(dif, \"finite\") && $(node, {y: a.y + dif});\n        },\n        Element = function (node, svg) {\n            var X = 0,\n                Y = 0;\n            this[0] = node;\n            this.id = R._oid++;\n            this.node = node;\n            node.raphael = this;\n            this.paper = svg;\n            this.attrs = this.attrs || {};\n            this.transformations = []; // rotate, translate, scale\n            this._ = {\n                tx: 0,\n                ty: 0,\n                rt: {deg: 0, cx: 0, cy: 0},\n                sx: 1,\n                sy: 1\n            };\n            !svg.bottom && (svg.bottom = this);\n            this.prev = svg.top;\n            svg.top && (svg.top.next = this);\n            svg.top = this;\n            this.next = null;\n        };\n        var elproto = Element[proto];\n        Element[proto].rotate = function (deg, cx, cy) {\n            if (this.removed) {\n                return this;\n            }\n            if (deg == null) {\n                if (this._.rt.cx) {\n                    return [this._.rt.deg, this._.rt.cx, this._.rt.cy][join](S);\n                }\n                return this._.rt.deg;\n            }\n            var bbox = this.getBBox();\n            deg = Str(deg)[split](separator);\n            if (deg[length] - 1) {\n                cx = toFloat(deg[1]);\n                cy = toFloat(deg[2]);\n            }\n            deg = toFloat(deg[0]);\n            if (cx != null && cx !== false) {\n                this._.rt.deg = deg;\n            } else {\n                this._.rt.deg += deg;\n            }\n            (cy == null) && (cx = null);\n            this._.rt.cx = cx;\n            this._.rt.cy = cy;\n            cx = cx == null ? bbox.x + bbox.width / 2 : cx;\n            cy = cy == null ? bbox.y + bbox.height / 2 : cy;\n            if (this._.rt.deg) {\n                this.transformations[0] = R.format(\"rotate({0} {1} {2})\", this._.rt.deg, cx, cy);\n                this.clip && $(this.clip, {transform: R.format(\"rotate({0} {1} {2})\", -this._.rt.deg, cx, cy)});\n            } else {\n                this.transformations[0] = E;\n                this.clip && $(this.clip, {transform: E});\n            }\n            $(this.node, {transform: this.transformations[join](S)});\n            return this;\n        };\n        Element[proto].hide = function () {\n            !this.removed && (this.node.style.display = \"none\");\n            return this;\n        };\n        Element[proto].show = function () {\n            !this.removed && (this.node.style.display = \"\");\n            return this;\n        };\n        Element[proto].remove = function () {\n            if (this.removed) {\n                return;\n            }\n            tear(this, this.paper);\n            this.node.parentNode.removeChild(this.node);\n            for (var i in this) {\n                delete this[i];\n            }\n            this.removed = true;\n        };\n        Element[proto].getBBox = function () {\n            if (this.removed) {\n                return this;\n            }\n            if (this.type == \"path\") {\n                return pathDimensions(this.attrs.path);\n            }\n            if (this.node.style.display == \"none\") {\n                this.show();\n                var hide = true;\n            }\n            var bbox = {};\n            try {\n                bbox = this.node.getBBox();\n            } catch(e) {\n                // Firefox 3.0.x plays badly here\n            } finally {\n                bbox = bbox || {};\n            }\n            if (this.type == \"text\") {\n                bbox = {x: bbox.x, y: Infinity, width: 0, height: 0};\n                for (var i = 0, ii = this.node.getNumberOfChars(); i < ii; i++) {\n                    var bb = this.node.getExtentOfChar(i);\n                    (bb.y < bbox.y) && (bbox.y = bb.y);\n                    (bb.y + bb.height - bbox.y > bbox.height) && (bbox.height = bb.y + bb.height - bbox.y);\n                    (bb.x + bb.width - bbox.x > bbox.width) && (bbox.width = bb.x + bb.width - bbox.x);\n                }\n            }\n            hide && this.hide();\n            return bbox;\n        };\n        Element[proto].attr = function (name, value) {\n            if (this.removed) {\n                return this;\n            }\n            if (name == null) {\n                var res = {};\n                for (var i in this.attrs) if (this.attrs[has](i)) {\n                    res[i] = this.attrs[i];\n                }\n                this._.rt.deg && (res.rotation = this.rotate());\n                (this._.sx != 1 || this._.sy != 1) && (res.scale = this.scale());\n                res.gradient && res.fill == \"none\" && (res.fill = res.gradient) && delete res.gradient;\n                return res;\n            }\n            if (value == null && R.is(name, string)) {\n                if (name == \"translation\") {\n                    return translate.call(this);\n                }\n                if (name == \"rotation\") {\n                    return this.rotate();\n                }\n                if (name == \"scale\") {\n                    return this.scale();\n                }\n                if (name == fillString && this.attrs.fill == \"none\" && this.attrs.gradient) {\n                    return this.attrs.gradient;\n                }\n                return this.attrs[name];\n            }\n            if (value == null && R.is(name, array)) {\n                var values = {};\n                for (var j = 0, jj = name.length; j < jj; j++) {\n                    values[name[j]] = this.attr(name[j]);\n                }\n                return values;\n            }\n            if (value != null) {\n                var params = {};\n                params[name] = value;\n            } else if (name != null && R.is(name, \"object\")) {\n                params = name;\n            }\n            for (var key in this.paper.customAttributes) if (this.paper.customAttributes[has](key) && params[has](key) && R.is(this.paper.customAttributes[key], \"function\")) {\n                var par = this.paper.customAttributes[key].apply(this, [][concat](params[key]));\n                this.attrs[key] = params[key];\n                for (var subkey in par) if (par[has](subkey)) {\n                    params[subkey] = par[subkey];\n                }\n            }\n            setFillAndStroke(this, params);\n            return this;\n        };\n        Element[proto].toFront = function () {\n            if (this.removed) {\n                return this;\n            }\n            this.node.parentNode[appendChild](this.node);\n            var svg = this.paper;\n            svg.top != this && tofront(this, svg);\n            return this;\n        };\n        Element[proto].toBack = function () {\n            if (this.removed) {\n                return this;\n            }\n            if (this.node.parentNode.firstChild != this.node) {\n                this.node.parentNode.insertBefore(this.node, this.node.parentNode.firstChild);\n                toback(this, this.paper);\n                var svg = this.paper;\n            }\n            return this;\n        };\n        Element[proto].insertAfter = function (element) {\n            if (this.removed) {\n                return this;\n            }\n            var node = element.node || element[element.length - 1].node;\n            if (node.nextSibling) {\n                node.parentNode.insertBefore(this.node, node.nextSibling);\n            } else {\n                node.parentNode[appendChild](this.node);\n            }\n            insertafter(this, element, this.paper);\n            return this;\n        };\n        Element[proto].insertBefore = function (element) {\n            if (this.removed) {\n                return this;\n            }\n            var node = element.node || element[0].node;\n            node.parentNode.insertBefore(this.node, node);\n            insertbefore(this, element, this.paper);\n            return this;\n        };\n        Element[proto].blur = function (size) {\n            // Experimental. No Safari support. Use it on your own risk.\n            var t = this;\n            if (+size !== 0) {\n                var fltr = $(\"filter\"),\n                    blur = $(\"feGaussianBlur\");\n                t.attrs.blur = size;\n                fltr.id = createUUID();\n                $(blur, {stdDeviation: +size || 1.5});\n                fltr.appendChild(blur);\n                t.paper.defs.appendChild(fltr);\n                t._blur = fltr;\n                $(t.node, {filter: \"url(#\" + fltr.id + \")\"});\n            } else {\n                if (t._blur) {\n                    t._blur.parentNode.removeChild(t._blur);\n                    delete t._blur;\n                    delete t.attrs.blur;\n                }\n                t.node.removeAttribute(\"filter\");\n            }\n        };\n        var theCircle = function (svg, x, y, r) {\n            var el = $(\"circle\");\n            svg.canvas && svg.canvas[appendChild](el);\n            var res = new Element(el, svg);\n            res.attrs = {cx: x, cy: y, r: r, fill: \"none\", stroke: \"#000\"};\n            res.type = \"circle\";\n            $(el, res.attrs);\n            return res;\n        },\n        theRect = function (svg, x, y, w, h, r) {\n            var el = $(\"rect\");\n            svg.canvas && svg.canvas[appendChild](el);\n            var res = new Element(el, svg);\n            res.attrs = {x: x, y: y, width: w, height: h, r: r || 0, rx: r || 0, ry: r || 0, fill: \"none\", stroke: \"#000\"};\n            res.type = \"rect\";\n            $(el, res.attrs);\n            return res;\n        },\n        theEllipse = function (svg, x, y, rx, ry) {\n            var el = $(\"ellipse\");\n            svg.canvas && svg.canvas[appendChild](el);\n            var res = new Element(el, svg);\n            res.attrs = {cx: x, cy: y, rx: rx, ry: ry, fill: \"none\", stroke: \"#000\"};\n            res.type = \"ellipse\";\n            $(el, res.attrs);\n            return res;\n        },\n        theImage = function (svg, src, x, y, w, h) {\n            var el = $(\"image\");\n            $(el, {x: x, y: y, width: w, height: h, preserveAspectRatio: \"none\"});\n            el.setAttributeNS(svg.xlink, \"href\", src);\n            svg.canvas && svg.canvas[appendChild](el);\n            var res = new Element(el, svg);\n            res.attrs = {x: x, y: y, width: w, height: h, src: src};\n            res.type = \"image\";\n            return res;\n        },\n        theText = function (svg, x, y, text) {\n            var el = $(\"text\");\n            $(el, {x: x, y: y, \"text-anchor\": \"middle\"});\n            svg.canvas && svg.canvas[appendChild](el);\n            var res = new Element(el, svg);\n            res.attrs = {x: x, y: y, \"text-anchor\": \"middle\", text: text, font: availableAttrs.font, stroke: \"none\", fill: \"#000\"};\n            res.type = \"text\";\n            setFillAndStroke(res, res.attrs);\n            return res;\n        },\n        setSize = function (width, height) {\n            this.width = width || this.width;\n            this.height = height || this.height;\n            this.canvas[setAttribute](\"width\", this.width);\n            this.canvas[setAttribute](\"height\", this.height);\n            return this;\n        },\n        create = function () {\n            var con = getContainer[apply](0, arguments),\n                container = con && con.container,\n                x = con.x,\n                y = con.y,\n                width = con.width,\n                height = con.height;\n            if (!container) {\n                throw new Error(\"SVG container not found.\");\n            }\n            var cnvs = $(\"svg\");\n            x = x || 0;\n            y = y || 0;\n            width = width || 512;\n            height = height || 342;\n            $(cnvs, {\n                xmlns: \"http://www.w3.org/2000/svg\",\n                version: 1.1,\n                width: width,\n                height: height\n            });\n            if (container == 1) {\n                cnvs.style.cssText = \"position:absolute;left:\" + x + \"px;top:\" + y + \"px\";\n                doc.body[appendChild](cnvs);\n            } else {\n                if (container.firstChild) {\n                    container.insertBefore(cnvs, container.firstChild);\n                } else {\n                    container[appendChild](cnvs);\n                }\n            }\n            container = new Paper;\n            container.width = width;\n            container.height = height;\n            container.canvas = cnvs;\n            plugins.call(container, container, R.fn);\n            container.clear();\n            return container;\n        };\n        paperproto.clear = function () {\n            var c = this.canvas;\n            while (c.firstChild) {\n                c.removeChild(c.firstChild);\n            }\n            this.bottom = this.top = null;\n            (this.desc = $(\"desc\"))[appendChild](doc.createTextNode(\"Created with Rapha\\xebl\"));\n            c[appendChild](this.desc);\n            c[appendChild](this.defs = $(\"defs\"));\n        };\n        paperproto.remove = function () {\n            this.canvas.parentNode && this.canvas.parentNode.removeChild(this.canvas);\n            for (var i in this) {\n                this[i] = removed(i);\n            }\n        };\n    }\n\n    // VML\n    if (R.vml) {\n        var map = {M: \"m\", L: \"l\", C: \"c\", Z: \"x\", m: \"t\", l: \"r\", c: \"v\", z: \"x\"},\n            bites = /([clmz]),?([^clmz]*)/gi,\n            blurregexp = / progid:\\S+Blur\\([^\\)]+\\)/g,\n            val = /-?[^,\\s-]+/g,\n            coordsize = 1e3 + S + 1e3,\n            zoom = 10,\n            pathlike = {path: 1, rect: 1},\n            path2vml = function (path) {\n                var total =  /[ahqstv]/ig,\n                    command = pathToAbsolute;\n                Str(path).match(total) && (command = path2curve);\n                total = /[clmz]/g;\n                if (command == pathToAbsolute && !Str(path).match(total)) {\n                    var res = Str(path)[rp](bites, function (all, command, args) {\n                        var vals = [],\n                            isMove = lowerCase.call(command) == \"m\",\n                            res = map[command];\n                        args[rp](val, function (value) {\n                            if (isMove && vals[length] == 2) {\n                                res += vals + map[command == \"m\" ? \"l\" : \"L\"];\n                                vals = [];\n                            }\n                            vals[push](round(value * zoom));\n                        });\n                        return res + vals;\n                    });\n                    return res;\n                }\n                var pa = command(path), p, r;\n                res = [];\n                for (var i = 0, ii = pa[length]; i < ii; i++) {\n                    p = pa[i];\n                    r = lowerCase.call(pa[i][0]);\n                    r == \"z\" && (r = \"x\");\n                    for (var j = 1, jj = p[length]; j < jj; j++) {\n                        r += round(p[j] * zoom) + (j != jj - 1 ? \",\" : E);\n                    }\n                    res[push](r);\n                }\n                return res[join](S);\n            };\n        \n        R[toString] = function () {\n            return  \"Your browser doesn\\u2019t support SVG. Falling down to VML.\\nYou are running Rapha\\xebl \" + this.version;\n        };\n        thePath = function (pathString, vml) {\n            var g = createNode(\"group\");\n            g.style.cssText = \"position:absolute;left:0;top:0;width:\" + vml.width + \"px;height:\" + vml.height + \"px\";\n            g.coordsize = vml.coordsize;\n            g.coordorigin = vml.coordorigin;\n            var el = createNode(\"shape\"), ol = el.style;\n            ol.width = vml.width + \"px\";\n            ol.height = vml.height + \"px\";\n            el.coordsize = coordsize;\n            el.coordorigin = vml.coordorigin;\n            g[appendChild](el);\n            var p = new Element(el, g, vml),\n                attr = {fill: \"none\", stroke: \"#000\"};\n            pathString && (attr.path = pathString);\n            p.type = \"path\";\n            p.path = [];\n            p.Path = E;\n            setFillAndStroke(p, attr);\n            vml.canvas[appendChild](g);\n            return p;\n        };\n        setFillAndStroke = function (o, params) {\n            o.attrs = o.attrs || {};\n            var node = o.node,\n                a = o.attrs,\n                s = node.style,\n                xy,\n                newpath = (params.x != a.x || params.y != a.y || params.width != a.width || params.height != a.height || params.r != a.r) && o.type == \"rect\",\n                res = o;\n\n            for (var par in params) if (params[has](par)) {\n                a[par] = params[par];\n            }\n            if (newpath) {\n                a.path = rectPath(a.x, a.y, a.width, a.height, a.r);\n                o.X = a.x;\n                o.Y = a.y;\n                o.W = a.width;\n                o.H = a.height;\n            }\n            params.href && (node.href = params.href);\n            params.title && (node.title = params.title);\n            params.target && (node.target = params.target);\n            params.cursor && (s.cursor = params.cursor);\n            \"blur\" in params && o.blur(params.blur);\n            if (params.path && o.type == \"path\" || newpath) {\n                node.path = path2vml(a.path);\n            }\n            if (params.rotation != null) {\n                o.rotate(params.rotation, true);\n            }\n            if (params.translation) {\n                xy = Str(params.translation)[split](separator);\n                translate.call(o, xy[0], xy[1]);\n                if (o._.rt.cx != null) {\n                    o._.rt.cx +=+ xy[0];\n                    o._.rt.cy +=+ xy[1];\n                    o.setBox(o.attrs, xy[0], xy[1]);\n                }\n            }\n            if (params.scale) {\n                xy = Str(params.scale)[split](separator);\n                o.scale(+xy[0] || 1, +xy[1] || +xy[0] || 1, +xy[2] || null, +xy[3] || null);\n            }\n            if (\"clip-rect\" in params) {\n                var rect = Str(params[\"clip-rect\"])[split](separator);\n                if (rect[length] == 4) {\n                    rect[2] = +rect[2] + (+rect[0]);\n                    rect[3] = +rect[3] + (+rect[1]);\n                    var div = node.clipRect || doc.createElement(\"div\"),\n                        dstyle = div.style,\n                        group = node.parentNode;\n                    dstyle.clip = R.format(\"rect({1}px {2}px {3}px {0}px)\", rect);\n                    if (!node.clipRect) {\n                        dstyle.position = \"absolute\";\n                        dstyle.top = 0;\n                        dstyle.left = 0;\n                        dstyle.width = o.paper.width + \"px\";\n                        dstyle.height = o.paper.height + \"px\";\n                        group.parentNode.insertBefore(div, group);\n                        div[appendChild](group);\n                        node.clipRect = div;\n                    }\n                }\n                if (!params[\"clip-rect\"]) {\n                    node.clipRect && (node.clipRect.style.clip = E);\n                }\n            }\n            if (o.type == \"image\" && params.src) {\n                node.src = params.src;\n            }\n            if (o.type == \"image\" && params.opacity) {\n                node.filterOpacity = ms + \".Alpha(opacity=\" + (params.opacity * 100) + \")\";\n                s.filter = (node.filterMatrix || E) + (node.filterOpacity || E);\n            }\n            params.font && (s.font = params.font);\n            params[\"font-family\"] && (s.fontFamily = '\"' + params[\"font-family\"][split](\",\")[0][rp](/^['\"]+|['\"]+$/g, E) + '\"');\n            params[\"font-size\"] && (s.fontSize = params[\"font-size\"]);\n            params[\"font-weight\"] && (s.fontWeight = params[\"font-weight\"]);\n            params[\"font-style\"] && (s.fontStyle = params[\"font-style\"]);\n            if (params.opacity != null || \n                params[\"stroke-width\"] != null ||\n                params.fill != null ||\n                params.stroke != null ||\n                params[\"stroke-width\"] != null ||\n                params[\"stroke-opacity\"] != null ||\n                params[\"fill-opacity\"] != null ||\n                params[\"stroke-dasharray\"] != null ||\n                params[\"stroke-miterlimit\"] != null ||\n                params[\"stroke-linejoin\"] != null ||\n                params[\"stroke-linecap\"] != null) {\n                node = o.shape || node;\n                var fill = (node.getElementsByTagName(fillString) && node.getElementsByTagName(fillString)[0]),\n                    newfill = false;\n                !fill && (newfill = fill = createNode(fillString));\n                if (\"fill-opacity\" in params || \"opacity\" in params) {\n                    var opacity = ((+a[\"fill-opacity\"] + 1 || 2) - 1) * ((+a.opacity + 1 || 2) - 1) * ((+R.getRGB(params.fill).o + 1 || 2) - 1);\n                    opacity = mmin(mmax(opacity, 0), 1);\n                    fill.opacity = opacity;\n                }\n                params.fill && (fill.on = true);\n                if (fill.on == null || params.fill == \"none\") {\n                    fill.on = false;\n                }\n                if (fill.on && params.fill) {\n                    var isURL = params.fill.match(ISURL);\n                    if (isURL) {\n                        fill.src = isURL[1];\n                        fill.type = \"tile\";\n                    } else {\n                        fill.color = R.getRGB(params.fill).hex;\n                        fill.src = E;\n                        fill.type = \"solid\";\n                        if (R.getRGB(params.fill).error && (res.type in {circle: 1, ellipse: 1} || Str(params.fill).charAt() != \"r\") && addGradientFill(res, params.fill)) {\n                            a.fill = \"none\";\n                            a.gradient = params.fill;\n                        }\n                    }\n                }\n                newfill && node[appendChild](fill);\n                var stroke = (node.getElementsByTagName(\"stroke\") && node.getElementsByTagName(\"stroke\")[0]),\n                newstroke = false;\n                !stroke && (newstroke = stroke = createNode(\"stroke\"));\n                if ((params.stroke && params.stroke != \"none\") ||\n                    params[\"stroke-width\"] ||\n                    params[\"stroke-opacity\"] != null ||\n                    params[\"stroke-dasharray\"] ||\n                    params[\"stroke-miterlimit\"] ||\n                    params[\"stroke-linejoin\"] ||\n                    params[\"stroke-linecap\"]) {\n                    stroke.on = true;\n                }\n                (params.stroke == \"none\" || stroke.on == null || params.stroke == 0 || params[\"stroke-width\"] == 0) && (stroke.on = false);\n                var strokeColor = R.getRGB(params.stroke);\n                stroke.on && params.stroke && (stroke.color = strokeColor.hex);\n                opacity = ((+a[\"stroke-opacity\"] + 1 || 2) - 1) * ((+a.opacity + 1 || 2) - 1) * ((+strokeColor.o + 1 || 2) - 1);\n                var width = (toFloat(params[\"stroke-width\"]) || 1) * .75;\n                opacity = mmin(mmax(opacity, 0), 1);\n                params[\"stroke-width\"] == null && (width = a[\"stroke-width\"]);\n                params[\"stroke-width\"] && (stroke.weight = width);\n                width && width < 1 && (opacity *= width) && (stroke.weight = 1);\n                stroke.opacity = opacity;\n                \n                params[\"stroke-linejoin\"] && (stroke.joinstyle = params[\"stroke-linejoin\"] || \"miter\");\n                stroke.miterlimit = params[\"stroke-miterlimit\"] || 8;\n                params[\"stroke-linecap\"] && (stroke.endcap = params[\"stroke-linecap\"] == \"butt\" ? \"flat\" : params[\"stroke-linecap\"] == \"square\" ? \"square\" : \"round\");\n                if (params[\"stroke-dasharray\"]) {\n                    var dasharray = {\n                        \"-\": \"shortdash\",\n                        \".\": \"shortdot\",\n                        \"-.\": \"shortdashdot\",\n                        \"-..\": \"shortdashdotdot\",\n                        \". \": \"dot\",\n                        \"- \": \"dash\",\n                        \"--\": \"longdash\",\n                        \"- .\": \"dashdot\",\n                        \"--.\": \"longdashdot\",\n                        \"--..\": \"longdashdotdot\"\n                    };\n                    stroke.dashstyle = dasharray[has](params[\"stroke-dasharray\"]) ? dasharray[params[\"stroke-dasharray\"]] : E;\n                }\n                newstroke && node[appendChild](stroke);\n            }\n            if (res.type == \"text\") {\n                s = res.paper.span.style;\n                a.font && (s.font = a.font);\n                a[\"font-family\"] && (s.fontFamily = a[\"font-family\"]);\n                a[\"font-size\"] && (s.fontSize = a[\"font-size\"]);\n                a[\"font-weight\"] && (s.fontWeight = a[\"font-weight\"]);\n                a[\"font-style\"] && (s.fontStyle = a[\"font-style\"]);\n                res.node.string && (res.paper.span.innerHTML = Str(res.node.string)[rp](/</g, \"&#60;\")[rp](/&/g, \"&#38;\")[rp](/\\n/g, \"<br>\"));\n                res.W = a.w = res.paper.span.offsetWidth;\n                res.H = a.h = res.paper.span.offsetHeight;\n                res.X = a.x;\n                res.Y = a.y + round(res.H / 2);\n \n                // text-anchor emulationm\n                switch (a[\"text-anchor\"]) {\n                    case \"start\":\n                        res.node.style[\"v-text-align\"] = \"left\";\n                        res.bbx = round(res.W / 2);\n                    break;\n                    case \"end\":\n                        res.node.style[\"v-text-align\"] = \"right\";\n                        res.bbx = -round(res.W / 2);\n                    break;\n                    default:\n                        res.node.style[\"v-text-align\"] = \"center\";\n                    break;\n                }\n            }\n        };\n        addGradientFill = function (o, gradient) {\n            o.attrs = o.attrs || {};\n            var attrs = o.attrs,\n                fill,\n                type = \"linear\",\n                fxfy = \".5 .5\";\n            o.attrs.gradient = gradient;\n            gradient = Str(gradient)[rp](radial_gradient, function (all, fx, fy) {\n                type = \"radial\";\n                if (fx && fy) {\n                    fx = toFloat(fx);\n                    fy = toFloat(fy);\n                    pow(fx - .5, 2) + pow(fy - .5, 2) > .25 && (fy = math.sqrt(.25 - pow(fx - .5, 2)) * ((fy > .5) * 2 - 1) + .5);\n                    fxfy = fx + S + fy;\n                }\n                return E;\n            });\n            gradient = gradient[split](/\\s*\\-\\s*/);\n            if (type == \"linear\") {\n                var angle = gradient.shift();\n                angle = -toFloat(angle);\n                if (isNaN(angle)) {\n                    return null;\n                }\n            }\n            var dots = parseDots(gradient);\n            if (!dots) {\n                return null;\n            }\n            o = o.shape || o.node;\n            fill = o.getElementsByTagName(fillString)[0] || createNode(fillString);\n            !fill.parentNode && o.appendChild(fill);\n            if (dots[length]) {\n                fill.on = true;\n                fill.method = \"none\";\n                fill.color = dots[0].color;\n                fill.color2 = dots[dots[length] - 1].color;\n                var clrs = [];\n                for (var i = 0, ii = dots[length]; i < ii; i++) {\n                    dots[i].offset && clrs[push](dots[i].offset + S + dots[i].color);\n                }\n                fill.colors && (fill.colors.value = clrs[length] ? clrs[join]() : \"0% \" + fill.color);\n                if (type == \"radial\") {\n                    fill.type = \"gradientradial\";\n                    fill.focus = \"100%\";\n                    fill.focussize = fxfy;\n                    fill.focusposition = fxfy;\n                } else {\n                    fill.type = \"gradient\";\n                    fill.angle = (270 - angle) % 360;\n                }\n            }\n            return 1;\n        };\n        Element = function (node, group, vml) {\n            var Rotation = 0,\n                RotX = 0,\n                RotY = 0,\n                Scale = 1;\n            this[0] = node;\n            this.id = R._oid++;\n            this.node = node;\n            node.raphael = this;\n            this.X = 0;\n            this.Y = 0;\n            this.attrs = {};\n            this.Group = group;\n            this.paper = vml;\n            this._ = {\n                tx: 0,\n                ty: 0,\n                rt: {deg:0},\n                sx: 1,\n                sy: 1\n            };\n            !vml.bottom && (vml.bottom = this);\n            this.prev = vml.top;\n            vml.top && (vml.top.next = this);\n            vml.top = this;\n            this.next = null;\n        };\n        elproto = Element[proto];\n        elproto.rotate = function (deg, cx, cy) {\n            if (this.removed) {\n                return this;\n            }\n            if (deg == null) {\n                if (this._.rt.cx) {\n                    return [this._.rt.deg, this._.rt.cx, this._.rt.cy][join](S);\n                }\n                return this._.rt.deg;\n            }\n            deg = Str(deg)[split](separator);\n            if (deg[length] - 1) {\n                cx = toFloat(deg[1]);\n                cy = toFloat(deg[2]);\n            }\n            deg = toFloat(deg[0]);\n            if (cx != null) {\n                this._.rt.deg = deg;\n            } else {\n                this._.rt.deg += deg;\n            }\n            cy == null && (cx = null);\n            this._.rt.cx = cx;\n            this._.rt.cy = cy;\n            this.setBox(this.attrs, cx, cy);\n            this.Group.style.rotation = this._.rt.deg;\n            // gradient fix for rotation. TODO\n            // var fill = (this.shape || this.node).getElementsByTagName(fillString);\n            // fill = fill[0] || {};\n            // var b = ((360 - this._.rt.deg) - 270) % 360;\n            // !R.is(fill.angle, \"undefined\") && (fill.angle = b);\n            return this;\n        };\n        elproto.setBox = function (params, cx, cy) {\n            if (this.removed) {\n                return this;\n            }\n            var gs = this.Group.style,\n                os = (this.shape && this.shape.style) || this.node.style;\n            params = params || {};\n            for (var i in params) if (params[has](i)) {\n                this.attrs[i] = params[i];\n            }\n            cx = cx || this._.rt.cx;\n            cy = cy || this._.rt.cy;\n            var attr = this.attrs,\n                x,\n                y,\n                w,\n                h;\n            switch (this.type) {\n                case \"circle\":\n                    x = attr.cx - attr.r;\n                    y = attr.cy - attr.r;\n                    w = h = attr.r * 2;\n                    break;\n                case \"ellipse\":\n                    x = attr.cx - attr.rx;\n                    y = attr.cy - attr.ry;\n                    w = attr.rx * 2;\n                    h = attr.ry * 2;\n                    break;\n                case \"image\":\n                    x = +attr.x;\n                    y = +attr.y;\n                    w = attr.width || 0;\n                    h = attr.height || 0;\n                    break;\n                case \"text\":\n                    this.textpath.v = [\"m\", round(attr.x), \", \", round(attr.y - 2), \"l\", round(attr.x) + 1, \", \", round(attr.y - 2)][join](E);\n                    x = attr.x - round(this.W / 2);\n                    y = attr.y - this.H / 2;\n                    w = this.W;\n                    h = this.H;\n                    break;\n                case \"rect\":\n                case \"path\":\n                    if (!this.attrs.path) {\n                        x = 0;\n                        y = 0;\n                        w = this.paper.width;\n                        h = this.paper.height;\n                    } else {\n                        var dim = pathDimensions(this.attrs.path);\n                        x = dim.x;\n                        y = dim.y;\n                        w = dim.width;\n                        h = dim.height;\n                    }\n                    break;\n                default:\n                    x = 0;\n                    y = 0;\n                    w = this.paper.width;\n                    h = this.paper.height;\n                    break;\n            }\n            cx = (cx == null) ? x + w / 2 : cx;\n            cy = (cy == null) ? y + h / 2 : cy;\n            var left = cx - this.paper.width / 2,\n                top = cy - this.paper.height / 2, t;\n            gs.left != (t = left + \"px\") && (gs.left = t);\n            gs.top != (t = top + \"px\") && (gs.top = t);\n            this.X = pathlike[has](this.type) ? -left : x;\n            this.Y = pathlike[has](this.type) ? -top : y;\n            this.W = w;\n            this.H = h;\n            if (pathlike[has](this.type)) {\n                os.left != (t = -left * zoom + \"px\") && (os.left = t);\n                os.top != (t = -top * zoom + \"px\") && (os.top = t);\n            } else if (this.type == \"text\") {\n                os.left != (t = -left + \"px\") && (os.left = t);\n                os.top != (t = -top + \"px\") && (os.top = t);\n            } else {\n                gs.width != (t = this.paper.width + \"px\") && (gs.width = t);\n                gs.height != (t = this.paper.height + \"px\") && (gs.height = t);\n                os.left != (t = x - left + \"px\") && (os.left = t);\n                os.top != (t = y - top + \"px\") && (os.top = t);\n                os.width != (t = w + \"px\") && (os.width = t);\n                os.height != (t = h + \"px\") && (os.height = t);\n            }\n        };\n        elproto.hide = function () {\n            !this.removed && (this.Group.style.display = \"none\");\n            return this;\n        };\n        elproto.show = function () {\n            !this.removed && (this.Group.style.display = \"block\");\n            return this;\n        };\n        elproto.getBBox = function () {\n            if (this.removed) {\n                return this;\n            }\n            if (pathlike[has](this.type)) {\n                return pathDimensions(this.attrs.path);\n            }\n            return {\n                x: this.X + (this.bbx || 0),\n                y: this.Y,\n                width: this.W,\n                height: this.H\n            };\n        };\n        elproto.remove = function () {\n            if (this.removed) {\n                return;\n            }\n            tear(this, this.paper);\n            this.node.parentNode.removeChild(this.node);\n            this.Group.parentNode.removeChild(this.Group);\n            this.shape && this.shape.parentNode.removeChild(this.shape);\n            for (var i in this) {\n                delete this[i];\n            }\n            this.removed = true;\n        };\n        elproto.attr = function (name, value) {\n            if (this.removed) {\n                return this;\n            }\n            if (name == null) {\n                var res = {};\n                for (var i in this.attrs) if (this.attrs[has](i)) {\n                    res[i] = this.attrs[i];\n                }\n                this._.rt.deg && (res.rotation = this.rotate());\n                (this._.sx != 1 || this._.sy != 1) && (res.scale = this.scale());\n                res.gradient && res.fill == \"none\" && (res.fill = res.gradient) && delete res.gradient;\n                return res;\n            }\n            if (value == null && R.is(name, \"string\")) {\n                if (name == \"translation\") {\n                    return translate.call(this);\n                }\n                if (name == \"rotation\") {\n                    return this.rotate();\n                }\n                if (name == \"scale\") {\n                    return this.scale();\n                }\n                if (name == fillString && this.attrs.fill == \"none\" && this.attrs.gradient) {\n                    return this.attrs.gradient;\n                }\n                return this.attrs[name];\n            }\n            if (this.attrs && value == null && R.is(name, array)) {\n                var ii, values = {};\n                for (i = 0, ii = name[length]; i < ii; i++) {\n                    values[name[i]] = this.attr(name[i]);\n                }\n                return values;\n            }\n            var params;\n            if (value != null) {\n                params = {};\n                params[name] = value;\n            }\n            value == null && R.is(name, \"object\") && (params = name);\n            if (params) {\n                for (var key in this.paper.customAttributes) if (this.paper.customAttributes[has](key) && params[has](key) && R.is(this.paper.customAttributes[key], \"function\")) {\n                    var par = this.paper.customAttributes[key].apply(this, [][concat](params[key]));\n                    this.attrs[key] = params[key];\n                    for (var subkey in par) if (par[has](subkey)) {\n                        params[subkey] = par[subkey];\n                    }\n                }\n                if (params.text && this.type == \"text\") {\n                    this.node.string = params.text;\n                }\n                setFillAndStroke(this, params);\n                if (params.gradient && (({circle: 1, ellipse: 1})[has](this.type) || Str(params.gradient).charAt() != \"r\")) {\n                    addGradientFill(this, params.gradient);\n                }\n                (!pathlike[has](this.type) || this._.rt.deg) && this.setBox(this.attrs);\n            }\n            return this;\n        };\n        elproto.toFront = function () {\n            !this.removed && this.Group.parentNode[appendChild](this.Group);\n            this.paper.top != this && tofront(this, this.paper);\n            return this;\n        };\n        elproto.toBack = function () {\n            if (this.removed) {\n                return this;\n            }\n            if (this.Group.parentNode.firstChild != this.Group) {\n                this.Group.parentNode.insertBefore(this.Group, this.Group.parentNode.firstChild);\n                toback(this, this.paper);\n            }\n            return this;\n        };\n        elproto.insertAfter = function (element) {\n            if (this.removed) {\n                return this;\n            }\n            if (element.constructor == Set) {\n                element = element[element.length - 1];\n            }\n            if (element.Group.nextSibling) {\n                element.Group.parentNode.insertBefore(this.Group, element.Group.nextSibling);\n            } else {\n                element.Group.parentNode[appendChild](this.Group);\n            }\n            insertafter(this, element, this.paper);\n            return this;\n        };\n        elproto.insertBefore = function (element) {\n            if (this.removed) {\n                return this;\n            }\n            if (element.constructor == Set) {\n                element = element[0];\n            }\n            element.Group.parentNode.insertBefore(this.Group, element.Group);\n            insertbefore(this, element, this.paper);\n            return this;\n        };\n        elproto.blur = function (size) {\n            var s = this.node.runtimeStyle,\n                f = s.filter;\n            f = f.replace(blurregexp, E);\n            if (+size !== 0) {\n                this.attrs.blur = size;\n                s.filter = f + S + ms + \".Blur(pixelradius=\" + (+size || 1.5) + \")\";\n                s.margin = R.format(\"-{0}px 0 0 -{0}px\", round(+size || 1.5));\n            } else {\n                s.filter = f;\n                s.margin = 0;\n                delete this.attrs.blur;\n            }\n        };\n \n        theCircle = function (vml, x, y, r) {\n            var g = createNode(\"group\"),\n                o = createNode(\"oval\"),\n                ol = o.style;\n            g.style.cssText = \"position:absolute;left:0;top:0;width:\" + vml.width + \"px;height:\" + vml.height + \"px\";\n            g.coordsize = coordsize;\n            g.coordorigin = vml.coordorigin;\n            g[appendChild](o);\n            var res = new Element(o, g, vml);\n            res.type = \"circle\";\n            setFillAndStroke(res, {stroke: \"#000\", fill: \"none\"});\n            res.attrs.cx = x;\n            res.attrs.cy = y;\n            res.attrs.r = r;\n            res.setBox({x: x - r, y: y - r, width: r * 2, height: r * 2});\n            vml.canvas[appendChild](g);\n            return res;\n        };\n        function rectPath(x, y, w, h, r) {\n            if (r) {\n                return R.format(\"M{0},{1}l{2},0a{3},{3},0,0,1,{3},{3}l0,{5}a{3},{3},0,0,1,{4},{3}l{6},0a{3},{3},0,0,1,{4},{4}l0,{7}a{3},{3},0,0,1,{3},{4}z\", x + r, y, w - r * 2, r, -r, h - r * 2, r * 2 - w, r * 2 - h);\n            } else {\n                return R.format(\"M{0},{1}l{2},0,0,{3},{4},0z\", x, y, w, h, -w);\n            }\n        }\n        theRect = function (vml, x, y, w, h, r) {\n            var path = rectPath(x, y, w, h, r),\n                res = vml.path(path),\n                a = res.attrs;\n            res.X = a.x = x;\n            res.Y = a.y = y;\n            res.W = a.width = w;\n            res.H = a.height = h;\n            a.r = r;\n            a.path = path;\n            res.type = \"rect\";\n            return res;\n        };\n        theEllipse = function (vml, x, y, rx, ry) {\n            var g = createNode(\"group\"),\n                o = createNode(\"oval\"),\n                ol = o.style;\n            g.style.cssText = \"position:absolute;left:0;top:0;width:\" + vml.width + \"px;height:\" + vml.height + \"px\";\n            g.coordsize = coordsize;\n            g.coordorigin = vml.coordorigin;\n            g[appendChild](o);\n            var res = new Element(o, g, vml);\n            res.type = \"ellipse\";\n            setFillAndStroke(res, {stroke: \"#000\"});\n            res.attrs.cx = x;\n            res.attrs.cy = y;\n            res.attrs.rx = rx;\n            res.attrs.ry = ry;\n            res.setBox({x: x - rx, y: y - ry, width: rx * 2, height: ry * 2});\n            vml.canvas[appendChild](g);\n            return res;\n        };\n        theImage = function (vml, src, x, y, w, h) {\n            var g = createNode(\"group\"),\n                o = createNode(\"image\");\n            g.style.cssText = \"position:absolute;left:0;top:0;width:\" + vml.width + \"px;height:\" + vml.height + \"px\";\n            g.coordsize = coordsize;\n            g.coordorigin = vml.coordorigin;\n            o.src = src;\n            g[appendChild](o);\n            var res = new Element(o, g, vml);\n            res.type = \"image\";\n            res.attrs.src = src;\n            res.attrs.x = x;\n            res.attrs.y = y;\n            res.attrs.w = w;\n            res.attrs.h = h;\n            res.setBox({x: x, y: y, width: w, height: h});\n            vml.canvas[appendChild](g);\n            return res;\n        };\n        theText = function (vml, x, y, text) {\n            var g = createNode(\"group\"),\n                el = createNode(\"shape\"),\n                ol = el.style,\n                path = createNode(\"path\"),\n                ps = path.style,\n                o = createNode(\"textpath\");\n            g.style.cssText = \"position:absolute;left:0;top:0;width:\" + vml.width + \"px;height:\" + vml.height + \"px\";\n            g.coordsize = coordsize;\n            g.coordorigin = vml.coordorigin;\n            path.v = R.format(\"m{0},{1}l{2},{1}\", round(x * 10), round(y * 10), round(x * 10) + 1);\n            path.textpathok = true;\n            ol.width = vml.width;\n            ol.height = vml.height;\n            o.string = Str(text);\n            o.on = true;\n            el[appendChild](o);\n            el[appendChild](path);\n            g[appendChild](el);\n            var res = new Element(o, g, vml);\n            res.shape = el;\n            res.textpath = path;\n            res.type = \"text\";\n            res.attrs.text = text;\n            res.attrs.x = x;\n            res.attrs.y = y;\n            res.attrs.w = 1;\n            res.attrs.h = 1;\n            setFillAndStroke(res, {font: availableAttrs.font, stroke: \"none\", fill: \"#000\"});\n            res.setBox();\n            vml.canvas[appendChild](g);\n            return res;\n        };\n        setSize = function (width, height) {\n            var cs = this.canvas.style;\n            width == +width && (width += \"px\");\n            height == +height && (height += \"px\");\n            cs.width = width;\n            cs.height = height;\n            cs.clip = \"rect(0 \" + width + \" \" + height + \" 0)\";\n            return this;\n        };\n        var createNode;\n        doc.createStyleSheet().addRule(\".rvml\", \"behavior:url(#default#VML)\");\n        try {\n            !doc.namespaces.rvml && doc.namespaces.add(\"rvml\", \"urn:schemas-microsoft-com:vml\");\n            createNode = function (tagName) {\n                return doc.createElement('<rvml:' + tagName + ' class=\"rvml\">');\n            };\n        } catch (e) {\n            createNode = function (tagName) {\n                return doc.createElement('<' + tagName + ' xmlns=\"urn:schemas-microsoft.com:vml\" class=\"rvml\">');\n            };\n        }\n        create = function () {\n            var con = getContainer[apply](0, arguments),\n                container = con.container,\n                height = con.height,\n                s,\n                width = con.width,\n                x = con.x,\n                y = con.y;\n            if (!container) {\n                throw new Error(\"VML container not found.\");\n            }\n            var res = new Paper,\n                c = res.canvas = doc.createElement(\"div\"),\n                cs = c.style;\n            x = x || 0;\n            y = y || 0;\n            width = width || 512;\n            height = height || 342;\n            width == +width && (width += \"px\");\n            height == +height && (height += \"px\");\n            res.width = 1e3;\n            res.height = 1e3;\n            res.coordsize = zoom * 1e3 + S + zoom * 1e3;\n            res.coordorigin = \"0 0\";\n            res.span = doc.createElement(\"span\");\n            res.span.style.cssText = \"position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;\";\n            c[appendChild](res.span);\n            cs.cssText = R.format(\"top:0;left:0;width:{0};height:{1};display:inline-block;position:relative;clip:rect(0 {0} {1} 0);overflow:hidden\", width, height);\n            if (container == 1) {\n                doc.body[appendChild](c);\n                cs.left = x + \"px\";\n                cs.top = y + \"px\";\n                cs.position = \"absolute\";\n            } else {\n                if (container.firstChild) {\n                    container.insertBefore(c, container.firstChild);\n                } else {\n                    container[appendChild](c);\n                }\n            }\n            plugins.call(res, res, R.fn);\n            return res;\n        };\n        paperproto.clear = function () {\n            this.canvas.innerHTML = E;\n            this.span = doc.createElement(\"span\");\n            this.span.style.cssText = \"position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;\";\n            this.canvas[appendChild](this.span);\n            this.bottom = this.top = null;\n        };\n        paperproto.remove = function () {\n            this.canvas.parentNode.removeChild(this.canvas);\n            for (var i in this) {\n                this[i] = removed(i);\n            }\n            return true;\n        };\n    }\n \n    // rest\n    // WebKit rendering bug workaround method\n    var version = navigator.userAgent.match(/Version\\/(.*?)\\s/);\n    if ((navigator.vendor == \"Apple Computer, Inc.\") && (version && version[1] < 4 || navigator.platform.slice(0, 2) == \"iP\")) {\n        paperproto.safari = function () {\n            var rect = this.rect(-99, -99, this.width + 99, this.height + 99).attr({stroke: \"none\"});\n            win.setTimeout(function () {rect.remove();});\n        };\n    } else {\n        paperproto.safari = function () {};\n    }\n \n    // Events\n    var preventDefault = function () {\n        this.returnValue = false;\n    },\n    preventTouch = function () {\n        return this.originalEvent.preventDefault();\n    },\n    stopPropagation = function () {\n        this.cancelBubble = true;\n    },\n    stopTouch = function () {\n        return this.originalEvent.stopPropagation();\n    },\n    addEvent = (function () {\n        if (doc.addEventListener) {\n            return function (obj, type, fn, element) {\n                var realName = supportsTouch && touchMap[type] ? touchMap[type] : type;\n                var f = function (e) {\n                    if (supportsTouch && touchMap[has](type)) {\n                        for (var i = 0, ii = e.targetTouches && e.targetTouches.length; i < ii; i++) {\n                            if (e.targetTouches[i].target == obj) {\n                                var olde = e;\n                                e = e.targetTouches[i];\n                                e.originalEvent = olde;\n                                e.preventDefault = preventTouch;\n                                e.stopPropagation = stopTouch;\n                                break;\n                            }\n                        }\n                    }\n                    return fn.call(element, e);\n                };\n                obj.addEventListener(realName, f, false);\n                return function () {\n                    obj.removeEventListener(realName, f, false);\n                    return true;\n                };\n            };\n        } else if (doc.attachEvent) {\n            return function (obj, type, fn, element) {\n                var f = function (e) {\n                    e = e || win.event;\n                    e.preventDefault = e.preventDefault || preventDefault;\n                    e.stopPropagation = e.stopPropagation || stopPropagation;\n                    return fn.call(element, e);\n                };\n                obj.attachEvent(\"on\" + type, f);\n                var detacher = function () {\n                    obj.detachEvent(\"on\" + type, f);\n                    return true;\n                };\n                return detacher;\n            };\n        }\n    })(),\n    drag = [],\n    dragMove = function (e) {\n        var x = e.clientX,\n            y = e.clientY,\n            scrollY = doc.documentElement.scrollTop || doc.body.scrollTop,\n            scrollX = doc.documentElement.scrollLeft || doc.body.scrollLeft,\n            dragi,\n            j = drag.length;\n        while (j--) {\n            dragi = drag[j];\n            if (supportsTouch) {\n                var i = e.touches.length,\n                    touch;\n                while (i--) {\n                    touch = e.touches[i];\n                    if (touch.identifier == dragi.el._drag.id) {\n                        x = touch.clientX;\n                        y = touch.clientY;\n                        (e.originalEvent ? e.originalEvent : e).preventDefault();\n                        break;\n                    }\n                }\n            } else {\n                e.preventDefault();\n            }\n            x += scrollX;\n            y += scrollY;\n            dragi.move && dragi.move.call(dragi.move_scope || dragi.el, x - dragi.el._drag.x, y - dragi.el._drag.y, x, y, e);\n        }\n    },\n    dragUp = function (e) {\n        R.unmousemove(dragMove).unmouseup(dragUp);\n        var i = drag.length,\n            dragi;\n        while (i--) {\n            dragi = drag[i];\n            dragi.el._drag = {};\n            dragi.end && dragi.end.call(dragi.end_scope || dragi.start_scope || dragi.move_scope || dragi.el, e);\n        }\n        drag = [];\n    };\n    for (var i = events[length]; i--;) {\n        (function (eventName) {\n            R[eventName] = Element[proto][eventName] = function (fn, scope) {\n                if (R.is(fn, \"function\")) {\n                    this.events = this.events || [];\n                    this.events.push({name: eventName, f: fn, unbind: addEvent(this.shape || this.node || doc, eventName, fn, scope || this)});\n                }\n                return this;\n            };\n            R[\"un\" + eventName] = Element[proto][\"un\" + eventName] = function (fn) {\n                var events = this.events,\n                    l = events[length];\n                while (l--) if (events[l].name == eventName && events[l].f == fn) {\n                    events[l].unbind();\n                    events.splice(l, 1);\n                    !events.length && delete this.events;\n                    return this;\n                }\n                return this;\n            };\n        })(events[i]);\n    }\n    elproto.hover = function (f_in, f_out, scope_in, scope_out) {\n        return this.mouseover(f_in, scope_in).mouseout(f_out, scope_out || scope_in);\n    };\n    elproto.unhover = function (f_in, f_out) {\n        return this.unmouseover(f_in).unmouseout(f_out);\n    };\n    elproto.drag = function (onmove, onstart, onend, move_scope, start_scope, end_scope) {\n        this._drag = {};\n        this.mousedown(function (e) {\n            (e.originalEvent || e).preventDefault();\n            var scrollY = doc.documentElement.scrollTop || doc.body.scrollTop,\n                scrollX = doc.documentElement.scrollLeft || doc.body.scrollLeft;\n            this._drag.x = e.clientX + scrollX;\n            this._drag.y = e.clientY + scrollY;\n            this._drag.id = e.identifier;\n            onstart && onstart.call(start_scope || move_scope || this, e.clientX + scrollX, e.clientY + scrollY, e);\n            !drag.length && R.mousemove(dragMove).mouseup(dragUp);\n            drag.push({el: this, move: onmove, end: onend, move_scope: move_scope, start_scope: start_scope, end_scope: end_scope});\n        });\n        return this;\n    };\n    elproto.undrag = function (onmove, onstart, onend) {\n        var i = drag.length;\n        while (i--) {\n            drag[i].el == this && (drag[i].move == onmove && drag[i].end == onend) && drag.splice(i++, 1);\n        }\n        !drag.length && R.unmousemove(dragMove).unmouseup(dragUp);\n    };\n    paperproto.circle = function (x, y, r) {\n        return theCircle(this, x || 0, y || 0, r || 0);\n    };\n    paperproto.rect = function (x, y, w, h, r) {\n        return theRect(this, x || 0, y || 0, w || 0, h || 0, r || 0);\n    };\n    paperproto.ellipse = function (x, y, rx, ry) {\n        return theEllipse(this, x || 0, y || 0, rx || 0, ry || 0);\n    };\n    paperproto.path = function (pathString) {\n        pathString && !R.is(pathString, string) && !R.is(pathString[0], array) && (pathString += E);\n        return thePath(R.format[apply](R, arguments), this);\n    };\n    paperproto.image = function (src, x, y, w, h) {\n        return theImage(this, src || \"about:blank\", x || 0, y || 0, w || 0, h || 0);\n    };\n    paperproto.text = function (x, y, text) {\n        return theText(this, x || 0, y || 0, Str(text));\n    };\n    paperproto.set = function (itemsArray) {\n        arguments[length] > 1 && (itemsArray = Array[proto].splice.call(arguments, 0, arguments[length]));\n        return new Set(itemsArray);\n    };\n    paperproto.setSize = setSize;\n    paperproto.top = paperproto.bottom = null;\n    paperproto.raphael = R;\n    function x_y() {\n        return this.x + S + this.y;\n    }\n    elproto.resetScale = function () {\n        if (this.removed) {\n            return this;\n        }\n        this._.sx = 1;\n        this._.sy = 1;\n        this.attrs.scale = \"1 1\";\n    };\n    elproto.scale = function (x, y, cx, cy) {\n        if (this.removed) {\n            return this;\n        }\n        if (x == null && y == null) {\n            return {\n                x: this._.sx,\n                y: this._.sy,\n                toString: x_y\n            };\n        }\n        y = y || x;\n        !+y && (y = x);\n        var dx,\n            dy,\n            dcx,\n            dcy,\n            a = this.attrs;\n        if (x != 0) {\n            var bb = this.getBBox(),\n                rcx = bb.x + bb.width / 2,\n                rcy = bb.y + bb.height / 2,\n                kx = abs(x / this._.sx),\n                ky = abs(y / this._.sy);\n            cx = (+cx || cx == 0) ? cx : rcx;\n            cy = (+cy || cy == 0) ? cy : rcy;\n            var posx = this._.sx > 0,\n                posy = this._.sy > 0,\n                dirx = ~~(x / abs(x)),\n                diry = ~~(y / abs(y)),\n                dkx = kx * dirx,\n                dky = ky * diry,\n                s = this.node.style,\n                ncx = cx + abs(rcx - cx) * dkx * (rcx > cx == posx ? 1 : -1),\n                ncy = cy + abs(rcy - cy) * dky * (rcy > cy == posy ? 1 : -1),\n                fr = (x * dirx > y * diry ? ky : kx);\n            switch (this.type) {\n                case \"rect\":\n                case \"image\":\n                    var neww = a.width * kx,\n                        newh = a.height * ky;\n                    this.attr({\n                        height: newh,\n                        r: a.r * fr,\n                        width: neww,\n                        x: ncx - neww / 2,\n                        y: ncy - newh / 2\n                    });\n                    break;\n                case \"circle\":\n                case \"ellipse\":\n                    this.attr({\n                        rx: a.rx * kx,\n                        ry: a.ry * ky,\n                        r: a.r * fr,\n                        cx: ncx,\n                        cy: ncy\n                    });\n                    break;\n                case \"text\":\n                    this.attr({\n                        x: ncx,\n                        y: ncy\n                    });\n                    break;\n                case \"path\":\n                    var path = pathToRelative(a.path),\n                        skip = true,\n                        fx = posx ? dkx : kx,\n                        fy = posy ? dky : ky;\n                    for (var i = 0, ii = path[length]; i < ii; i++) {\n                        var p = path[i],\n                            P0 = upperCase.call(p[0]);\n                        if (P0 == \"M\" && skip) {\n                            continue;\n                        } else {\n                            skip = false;\n                        }\n                        if (P0 == \"A\") {\n                            p[path[i][length] - 2] *= fx;\n                            p[path[i][length] - 1] *= fy;\n                            p[1] *= kx;\n                            p[2] *= ky;\n                            p[5] = +(dirx + diry ? !!+p[5] : !+p[5]);\n                        } else if (P0 == \"H\") {\n                            for (var j = 1, jj = p[length]; j < jj; j++) {\n                                p[j] *= fx;\n                            }\n                        } else if (P0 == \"V\") {\n                            for (j = 1, jj = p[length]; j < jj; j++) {\n                                p[j] *= fy;\n                            }\n                         } else {\n                            for (j = 1, jj = p[length]; j < jj; j++) {\n                                p[j] *= (j % 2) ? fx : fy;\n                            }\n                        }\n                    }\n                    var dim2 = pathDimensions(path);\n                    dx = ncx - dim2.x - dim2.width / 2;\n                    dy = ncy - dim2.y - dim2.height / 2;\n                    path[0][1] += dx;\n                    path[0][2] += dy;\n                    this.attr({path: path});\n                break;\n            }\n            if (this.type in {text: 1, image:1} && (dirx != 1 || diry != 1)) {\n                if (this.transformations) {\n                    this.transformations[2] = \"scale(\"[concat](dirx, \",\", diry, \")\");\n                    this.node[setAttribute](\"transform\", this.transformations[join](S));\n                    dx = (dirx == -1) ? -a.x - (neww || 0) : a.x;\n                    dy = (diry == -1) ? -a.y - (newh || 0) : a.y;\n                    this.attr({x: dx, y: dy});\n                    a.fx = dirx - 1;\n                    a.fy = diry - 1;\n                } else {\n                    this.node.filterMatrix = ms + \".Matrix(M11=\"[concat](dirx,\n                        \", M12=0, M21=0, M22=\", diry,\n                        \", Dx=0, Dy=0, sizingmethod='auto expand', filtertype='bilinear')\");\n                    s.filter = (this.node.filterMatrix || E) + (this.node.filterOpacity || E);\n                }\n            } else {\n                if (this.transformations) {\n                    this.transformations[2] = E;\n                    this.node[setAttribute](\"transform\", this.transformations[join](S));\n                    a.fx = 0;\n                    a.fy = 0;\n                } else {\n                    this.node.filterMatrix = E;\n                    s.filter = (this.node.filterMatrix || E) + (this.node.filterOpacity || E);\n                }\n            }\n            a.scale = [x, y, cx, cy][join](S);\n            this._.sx = x;\n            this._.sy = y;\n        }\n        return this;\n    };\n    elproto.clone = function () {\n        if (this.removed) {\n            return null;\n        }\n        var attr = this.attr();\n        delete attr.scale;\n        delete attr.translation;\n        return this.paper[this.type]().attr(attr);\n    };\n    var curveslengths = {},\n    getPointAtSegmentLength = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, length) {\n        var len = 0,\n            precision = 100,\n            name = [p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y].join(),\n            cache = curveslengths[name],\n            old, dot;\n        !cache && (curveslengths[name] = cache = {data: []});\n        cache.timer && clearTimeout(cache.timer);\n        cache.timer = setTimeout(function () {delete curveslengths[name];}, 2000);\n        if (length != null) {\n            var total = getPointAtSegmentLength(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y);\n            precision = ~~total * 10;\n        }\n        for (var i = 0; i < precision + 1; i++) {\n            if (cache.data[length] > i) {\n                dot = cache.data[i * precision];\n            } else {\n                dot = R.findDotsAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, i / precision);\n                cache.data[i] = dot;\n            }\n            i && (len += pow(pow(old.x - dot.x, 2) + pow(old.y - dot.y, 2), .5));\n            if (length != null && len >= length) {\n                return dot;\n            }\n            old = dot;\n        }\n        if (length == null) {\n            return len;\n        }\n    },\n    getLengthFactory = function (istotal, subpath) {\n        return function (path, length, onlystart) {\n            path = path2curve(path);\n            var x, y, p, l, sp = \"\", subpaths = {}, point,\n                len = 0;\n            for (var i = 0, ii = path.length; i < ii; i++) {\n                p = path[i];\n                if (p[0] == \"M\") {\n                    x = +p[1];\n                    y = +p[2];\n                } else {\n                    l = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6]);\n                    if (len + l > length) {\n                        if (subpath && !subpaths.start) {\n                            point = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6], length - len);\n                            sp += [\"C\", point.start.x, point.start.y, point.m.x, point.m.y, point.x, point.y];\n                            if (onlystart) {return sp;}\n                            subpaths.start = sp;\n                            sp = [\"M\", point.x, point.y + \"C\", point.n.x, point.n.y, point.end.x, point.end.y, p[5], p[6]][join]();\n                            len += l;\n                            x = +p[5];\n                            y = +p[6];\n                            continue;\n                        }\n                        if (!istotal && !subpath) {\n                            point = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6], length - len);\n                            return {x: point.x, y: point.y, alpha: point.alpha};\n                        }\n                    }\n                    len += l;\n                    x = +p[5];\n                    y = +p[6];\n                }\n                sp += p;\n            }\n            subpaths.end = sp;\n            point = istotal ? len : subpath ? subpaths : R.findDotsAtSegment(x, y, p[1], p[2], p[3], p[4], p[5], p[6], 1);\n            point.alpha && (point = {x: point.x, y: point.y, alpha: point.alpha});\n            return point;\n        };\n    };\n    var getTotalLength = getLengthFactory(1),\n        getPointAtLength = getLengthFactory(),\n        getSubpathsAtLength = getLengthFactory(0, 1);\n    elproto.getTotalLength = function () {\n        if (this.type != \"path\") {return;}\n        if (this.node.getTotalLength) {\n            return this.node.getTotalLength();\n        }\n        return getTotalLength(this.attrs.path);\n    };\n    elproto.getPointAtLength = function (length) {\n        if (this.type != \"path\") {return;}\n        return getPointAtLength(this.attrs.path, length);\n    };\n    elproto.getSubpath = function (from, to) {\n        if (this.type != \"path\") {return;}\n        if (abs(this.getTotalLength() - to) < \"1e-6\") {\n            return getSubpathsAtLength(this.attrs.path, from).end;\n        }\n        var a = getSubpathsAtLength(this.attrs.path, to, 1);\n        return from ? getSubpathsAtLength(a, from).end : a;\n    };\n\n    // animation easing formulas\n    R.easing_formulas = {\n        linear: function (n) {\n            return n;\n        },\n        \"<\": function (n) {\n            return pow(n, 3);\n        },\n        \">\": function (n) {\n            return pow(n - 1, 3) + 1;\n        },\n        \"<>\": function (n) {\n            n = n * 2;\n            if (n < 1) {\n                return pow(n, 3) / 2;\n            }\n            n -= 2;\n            return (pow(n, 3) + 2) / 2;\n        },\n        backIn: function (n) {\n            var s = 1.70158;\n            return n * n * ((s + 1) * n - s);\n        },\n        backOut: function (n) {\n            n = n - 1;\n            var s = 1.70158;\n            return n * n * ((s + 1) * n + s) + 1;\n        },\n        elastic: function (n) {\n            if (n == 0 || n == 1) {\n                return n;\n            }\n            var p = .3,\n                s = p / 4;\n            return pow(2, -10 * n) * math.sin((n - s) * (2 * PI) / p) + 1;\n        },\n        bounce: function (n) {\n            var s = 7.5625,\n                p = 2.75,\n                l;\n            if (n < (1 / p)) {\n                l = s * n * n;\n            } else {\n                if (n < (2 / p)) {\n                    n -= (1.5 / p);\n                    l = s * n * n + .75;\n                } else {\n                    if (n < (2.5 / p)) {\n                        n -= (2.25 / p);\n                        l = s * n * n + .9375;\n                    } else {\n                        n -= (2.625 / p);\n                        l = s * n * n + .984375;\n                    }\n                }\n            }\n            return l;\n        }\n    };\n\n    var animationElements = [],\n        animation = function () {\n            var Now = +new Date;\n            for (var l = 0; l < animationElements[length]; l++) {\n                var e = animationElements[l];\n                if (e.stop || e.el.removed) {\n                    continue;\n                }\n                var time = Now - e.start,\n                    ms = e.ms,\n                    easing = e.easing,\n                    from = e.from,\n                    diff = e.diff,\n                    to = e.to,\n                    t = e.t,\n                    that = e.el,\n                    set = {},\n                    now;\n                if (time < ms) {\n                    var pos = easing(time / ms);\n                    for (var attr in from) if (from[has](attr)) {\n                        switch (availableAnimAttrs[attr]) {\n                            case \"along\":\n                                now = pos * ms * diff[attr];\n                                to.back && (now = to.len - now);\n                                var point = getPointAtLength(to[attr], now);\n                                that.translate(diff.sx - diff.x || 0, diff.sy - diff.y || 0);\n                                diff.x = point.x;\n                                diff.y = point.y;\n                                that.translate(point.x - diff.sx, point.y - diff.sy);\n                                to.rot && that.rotate(diff.r + point.alpha, point.x, point.y);\n                                break;\n                            case nu:\n                                now = +from[attr] + pos * ms * diff[attr];\n                                break;\n                            case \"colour\":\n                                now = \"rgb(\" + [\n                                    upto255(round(from[attr].r + pos * ms * diff[attr].r)),\n                                    upto255(round(from[attr].g + pos * ms * diff[attr].g)),\n                                    upto255(round(from[attr].b + pos * ms * diff[attr].b))\n                                ][join](\",\") + \")\";\n                                break;\n                            case \"path\":\n                                now = [];\n                                for (var i = 0, ii = from[attr][length]; i < ii; i++) {\n                                    now[i] = [from[attr][i][0]];\n                                    for (var j = 1, jj = from[attr][i][length]; j < jj; j++) {\n                                        now[i][j] = +from[attr][i][j] + pos * ms * diff[attr][i][j];\n                                    }\n                                    now[i] = now[i][join](S);\n                                }\n                                now = now[join](S);\n                                break;\n                            case \"csv\":\n                                switch (attr) {\n                                    case \"translation\":\n                                        var x = pos * ms * diff[attr][0] - t.x,\n                                            y = pos * ms * diff[attr][1] - t.y;\n                                        t.x += x;\n                                        t.y += y;\n                                        now = x + S + y;\n                                    break;\n                                    case \"rotation\":\n                                        now = +from[attr][0] + pos * ms * diff[attr][0];\n                                        from[attr][1] && (now += \",\" + from[attr][1] + \",\" + from[attr][2]);\n                                    break;\n                                    case \"scale\":\n                                        now = [+from[attr][0] + pos * ms * diff[attr][0], +from[attr][1] + pos * ms * diff[attr][1], (2 in to[attr] ? to[attr][2] : E), (3 in to[attr] ? to[attr][3] : E)][join](S);\n                                    break;\n                                    case \"clip-rect\":\n                                        now = [];\n                                        i = 4;\n                                        while (i--) {\n                                            now[i] = +from[attr][i] + pos * ms * diff[attr][i];\n                                        }\n                                    break;\n                                }\n                                break;\n                            default:\n                              var from2 = [].concat(from[attr]);\n                                now = [];\n                                i = that.paper.customAttributes[attr].length;\n                                while (i--) {\n                                    now[i] = +from2[i] + pos * ms * diff[attr][i];\n                                }\n                                break;\n                        }\n                        set[attr] = now;\n                    }\n                    that.attr(set);\n                    that._run && that._run.call(that);\n                } else {\n                    if (to.along) {\n                        point = getPointAtLength(to.along, to.len * !to.back);\n                        that.translate(diff.sx - (diff.x || 0) + point.x - diff.sx, diff.sy - (diff.y || 0) + point.y - diff.sy);\n                        to.rot && that.rotate(diff.r + point.alpha, point.x, point.y);\n                    }\n                    (t.x || t.y) && that.translate(-t.x, -t.y);\n                    to.scale && (to.scale += E);\n                    that.attr(to);\n                    animationElements.splice(l--, 1);\n                }\n            }\n            R.svg && that && that.paper && that.paper.safari();\n            animationElements[length] && setTimeout(animation);\n        },\n        keyframesRun = function (attr, element, time, prev, prevcallback) {\n            var dif = time - prev;\n            element.timeouts.push(setTimeout(function () {\n                R.is(prevcallback, \"function\") && prevcallback.call(element);\n                element.animate(attr, dif, attr.easing);\n            }, prev));\n        },\n        upto255 = function (color) {\n            return mmax(mmin(color, 255), 0);\n        },\n        translate = function (x, y) {\n            if (x == null) {\n                return {x: this._.tx, y: this._.ty, toString: x_y};\n            }\n            this._.tx += +x;\n            this._.ty += +y;\n            switch (this.type) {\n                case \"circle\":\n                case \"ellipse\":\n                    this.attr({cx: +x + this.attrs.cx, cy: +y + this.attrs.cy});\n                    break;\n                case \"rect\":\n                case \"image\":\n                case \"text\":\n                    this.attr({x: +x + this.attrs.x, y: +y + this.attrs.y});\n                    break;\n                case \"path\":\n                    var path = pathToRelative(this.attrs.path);\n                    path[0][1] += +x;\n                    path[0][2] += +y;\n                    this.attr({path: path});\n                break;\n            }\n            return this;\n        };\n    elproto.animateWith = function (element, params, ms, easing, callback) {\n        for (var i = 0, ii = animationElements.length; i < ii; i++) {\n            if (animationElements[i].el.id == element.id) {\n                params.start = animationElements[i].start;\n            }\n        }\n        return this.animate(params, ms, easing, callback);\n    };\n    elproto.animateAlong = along();\n    elproto.animateAlongBack = along(1);\n    function along(isBack) {\n        return function (path, ms, rotate, callback) {\n            var params = {back: isBack};\n            R.is(rotate, \"function\") ? (callback = rotate) : (params.rot = rotate);\n            path && path.constructor == Element && (path = path.attrs.path);\n            path && (params.along = path);\n            return this.animate(params, ms, callback);\n        };\n    }\n    function CubicBezierAtTime(t, p1x, p1y, p2x, p2y, duration) {\n        var cx = 3 * p1x,\n            bx = 3 * (p2x - p1x) - cx,\n            ax = 1 - cx - bx,\n            cy = 3 * p1y,\n            by = 3 * (p2y - p1y) - cy,\n            ay = 1 - cy - by;\n        function sampleCurveX(t) {\n            return ((ax * t + bx) * t + cx) * t;\n        }\n        function solve(x, epsilon) {\n            var t = solveCurveX(x, epsilon);\n            return ((ay * t + by) * t + cy) * t;\n        }\n        function solveCurveX(x, epsilon) {\n            var t0, t1, t2, x2, d2, i;\n            for(t2 = x, i = 0; i < 8; i++) {\n                x2 = sampleCurveX(t2) - x;\n                if (abs(x2) < epsilon) {\n                    return t2;\n                }\n                d2 = (3 * ax * t2 + 2 * bx) * t2 + cx;\n                if (abs(d2) < 1e-6) {\n                    break;\n                }\n                t2 = t2 - x2 / d2;\n            }\n            t0 = 0;\n            t1 = 1;\n            t2 = x;\n            if (t2 < t0) {\n                return t0;\n            }\n            if (t2 > t1) {\n                return t1;\n            }\n            while (t0 < t1) {\n                x2 = sampleCurveX(t2);\n                if (abs(x2 - x) < epsilon) {\n                    return t2;\n                }\n                if (x > x2) {\n                    t0 = t2;\n                } else {\n                    t1 = t2;\n                }\n                t2 = (t1 - t0) / 2 + t0;\n            }\n            return t2;\n        }\n        return solve(t, 1 / (200 * duration));\n    }\n    elproto.onAnimation = function (f) {\n        this._run = f || 0;\n        return this;\n    };\n    elproto.animate = function (params, ms, easing, callback) {\n        var element = this;\n        element.timeouts = element.timeouts || [];\n        if (R.is(easing, \"function\") || !easing) {\n            callback = easing || null;\n        }\n        if (element.removed) {\n            callback && callback.call(element);\n            return element;\n        }\n        var from = {},\n            to = {},\n            animateable = false,\n            diff = {};\n        for (var attr in params) if (params[has](attr)) {\n            if (availableAnimAttrs[has](attr) || element.paper.customAttributes[has](attr)) {\n                animateable = true;\n                from[attr] = element.attr(attr);\n                (from[attr] == null) && (from[attr] = availableAttrs[attr]);\n                to[attr] = params[attr];\n                switch (availableAnimAttrs[attr]) {\n                    case \"along\":\n                        var len = getTotalLength(params[attr]);\n                        var point = getPointAtLength(params[attr], len * !!params.back);\n                        var bb = element.getBBox();\n                        diff[attr] = len / ms;\n                        diff.tx = bb.x;\n                        diff.ty = bb.y;\n                        diff.sx = point.x;\n                        diff.sy = point.y;\n                        to.rot = params.rot;\n                        to.back = params.back;\n                        to.len = len;\n                        params.rot && (diff.r = toFloat(element.rotate()) || 0);\n                        break;\n                    case nu:\n                        diff[attr] = (to[attr] - from[attr]) / ms;\n                        break;\n                    case \"colour\":\n                        from[attr] = R.getRGB(from[attr]);\n                        var toColour = R.getRGB(to[attr]);\n                        diff[attr] = {\n                            r: (toColour.r - from[attr].r) / ms,\n                            g: (toColour.g - from[attr].g) / ms,\n                            b: (toColour.b - from[attr].b) / ms\n                        };\n                        break;\n                    case \"path\":\n                        var pathes = path2curve(from[attr], to[attr]);\n                        from[attr] = pathes[0];\n                        var toPath = pathes[1];\n                        diff[attr] = [];\n                        for (var i = 0, ii = from[attr][length]; i < ii; i++) {\n                            diff[attr][i] = [0];\n                            for (var j = 1, jj = from[attr][i][length]; j < jj; j++) {\n                                diff[attr][i][j] = (toPath[i][j] - from[attr][i][j]) / ms;\n                            }\n                        }\n                        break;\n                    case \"csv\":\n                        var values = Str(params[attr])[split](separator),\n                            from2 = Str(from[attr])[split](separator);\n                        switch (attr) {\n                            case \"translation\":\n                                from[attr] = [0, 0];\n                                diff[attr] = [values[0] / ms, values[1] / ms];\n                            break;\n                            case \"rotation\":\n                                from[attr] = (from2[1] == values[1] && from2[2] == values[2]) ? from2 : [0, values[1], values[2]];\n                                diff[attr] = [(values[0] - from[attr][0]) / ms, 0, 0];\n                            break;\n                            case \"scale\":\n                                params[attr] = values;\n                                from[attr] = Str(from[attr])[split](separator);\n                                diff[attr] = [(values[0] - from[attr][0]) / ms, (values[1] - from[attr][1]) / ms, 0, 0];\n                            break;\n                            case \"clip-rect\":\n                                from[attr] = Str(from[attr])[split](separator);\n                                diff[attr] = [];\n                                i = 4;\n                                while (i--) {\n                                    diff[attr][i] = (values[i] - from[attr][i]) / ms;\n                                }\n                            break;\n                        }\n                        to[attr] = values;\n                        break;\n                    default:\n                        values = [].concat(params[attr]);\n                        from2 = [].concat(from[attr]);\n                        diff[attr] = [];\n                        i = element.paper.customAttributes[attr][length];\n                        while (i--) {\n                            diff[attr][i] = ((values[i] || 0) - (from2[i] || 0)) / ms;\n                        }\n                        break;\n                }\n            }\n        }\n        if (!animateable) {\n            var attrs = [],\n                lastcall;\n            for (var key in params) if (params[has](key) && animKeyFrames.test(key)) {\n                attr = {value: params[key]};\n                key == \"from\" && (key = 0);\n                key == \"to\" && (key = 100);\n                attr.key = toInt(key, 10);\n                attrs.push(attr);\n            }\n            attrs.sort(sortByKey);\n            if (attrs[0].key) {\n                attrs.unshift({key: 0, value: element.attrs});\n            }\n            for (i = 0, ii = attrs[length]; i < ii; i++) {\n                keyframesRun(attrs[i].value, element, ms / 100 * attrs[i].key, ms / 100 * (attrs[i - 1] && attrs[i - 1].key || 0), attrs[i - 1] && attrs[i - 1].value.callback);\n            }\n            lastcall = attrs[attrs[length] - 1].value.callback;\n            if (lastcall) {\n                element.timeouts.push(setTimeout(function () {lastcall.call(element);}, ms));\n            }\n        } else {\n            var easyeasy = R.easing_formulas[easing];\n            if (!easyeasy) {\n                easyeasy = Str(easing).match(bezierrg);\n                if (easyeasy && easyeasy[length] == 5) {\n                    var curve = easyeasy;\n                    easyeasy = function (t) {\n                        return CubicBezierAtTime(t, +curve[1], +curve[2], +curve[3], +curve[4], ms);\n                    };\n                } else {\n                    easyeasy = function (t) {\n                        return t;\n                    };\n                }\n            }\n            animationElements.push({\n                start: params.start || +new Date,\n                ms: ms,\n                easing: easyeasy,\n                from: from,\n                diff: diff,\n                to: to,\n                el: element,\n                t: {x: 0, y: 0}\n            });\n            R.is(callback, \"function\") && (element._ac = setTimeout(function () {\n                callback.call(element);\n            }, ms));\n            animationElements[length] == 1 && setTimeout(animation);\n        }\n        return this;\n    };\n    elproto.stop = function () {\n        for (var i = 0; i < animationElements.length; i++) {\n            animationElements[i].el.id == this.id && animationElements.splice(i--, 1);\n        }\n        for (i = 0, ii = this.timeouts && this.timeouts.length; i < ii; i++) {\n            clearTimeout(this.timeouts[i]);\n        }\n        this.timeouts = [];\n        clearTimeout(this._ac);\n        delete this._ac;\n        return this;\n    };\n    elproto.translate = function (x, y) {\n        return this.attr({translation: x + \" \" + y});\n    };\n    elproto[toString] = function () {\n        return \"Rapha\\xebl\\u2019s object\";\n    };\n    R.ae = animationElements;\n \n    // Set\n    var Set = function (items) {\n        this.items = [];\n        this[length] = 0;\n        this.type = \"set\";\n        if (items) {\n            for (var i = 0, ii = items[length]; i < ii; i++) {\n                if (items[i] && (items[i].constructor == Element || items[i].constructor == Set)) {\n                    this[this.items[length]] = this.items[this.items[length]] = items[i];\n                    this[length]++;\n                }\n            }\n        }\n    };\n    Set[proto][push] = function () {\n        var item,\n            len;\n        for (var i = 0, ii = arguments[length]; i < ii; i++) {\n            item = arguments[i];\n            if (item && (item.constructor == Element || item.constructor == Set)) {\n                len = this.items[length];\n                this[len] = this.items[len] = item;\n                this[length]++;\n            }\n        }\n        return this;\n    };\n    Set[proto].pop = function () {\n        delete this[this[length]--];\n        return this.items.pop();\n    };\n    for (var method in elproto) if (elproto[has](method)) {\n        Set[proto][method] = (function (methodname) {\n            return function () {\n                for (var i = 0, ii = this.items[length]; i < ii; i++) {\n                    this.items[i][methodname][apply](this.items[i], arguments);\n                }\n                return this;\n            };\n        })(method);\n    }\n    Set[proto].attr = function (name, value) {\n        if (name && R.is(name, array) && R.is(name[0], \"object\")) {\n            for (var j = 0, jj = name[length]; j < jj; j++) {\n                this.items[j].attr(name[j]);\n            }\n        } else {\n            for (var i = 0, ii = this.items[length]; i < ii; i++) {\n                this.items[i].attr(name, value);\n            }\n        }\n        return this;\n    };\n    Set[proto].animate = function (params, ms, easing, callback) {\n        (R.is(easing, \"function\") || !easing) && (callback = easing || null);\n        var len = this.items[length],\n            i = len,\n            item,\n            set = this,\n            collector;\n        callback && (collector = function () {\n            !--len && callback.call(set);\n        });\n        easing = R.is(easing, string) ? easing : collector;\n        item = this.items[--i].animate(params, ms, easing, collector);\n        while (i--) {\n            this.items[i] && !this.items[i].removed && this.items[i].animateWith(item, params, ms, easing, collector);\n        }\n        return this;\n    };\n    Set[proto].insertAfter = function (el) {\n        var i = this.items[length];\n        while (i--) {\n            this.items[i].insertAfter(el);\n        }\n        return this;\n    };\n    Set[proto].getBBox = function () {\n        var x = [],\n            y = [],\n            w = [],\n            h = [];\n        for (var i = this.items[length]; i--;) {\n            var box = this.items[i].getBBox();\n            x[push](box.x);\n            y[push](box.y);\n            w[push](box.x + box.width);\n            h[push](box.y + box.height);\n        }\n        x = mmin[apply](0, x);\n        y = mmin[apply](0, y);\n        return {\n            x: x,\n            y: y,\n            width: mmax[apply](0, w) - x,\n            height: mmax[apply](0, h) - y\n        };\n    };\n    Set[proto].clone = function (s) {\n        s = new Set;\n        for (var i = 0, ii = this.items[length]; i < ii; i++) {\n            s[push](this.items[i].clone());\n        }\n        return s;\n    };\n\n    R.registerFont = function (font) {\n        if (!font.face) {\n            return font;\n        }\n        this.fonts = this.fonts || {};\n        var fontcopy = {\n                w: font.w,\n                face: {},\n                glyphs: {}\n            },\n            family = font.face[\"font-family\"];\n        for (var prop in font.face) if (font.face[has](prop)) {\n            fontcopy.face[prop] = font.face[prop];\n        }\n        if (this.fonts[family]) {\n            this.fonts[family][push](fontcopy);\n        } else {\n            this.fonts[family] = [fontcopy];\n        }\n        if (!font.svg) {\n            fontcopy.face[\"units-per-em\"] = toInt(font.face[\"units-per-em\"], 10);\n            for (var glyph in font.glyphs) if (font.glyphs[has](glyph)) {\n                var path = font.glyphs[glyph];\n                fontcopy.glyphs[glyph] = {\n                    w: path.w,\n                    k: {},\n                    d: path.d && \"M\" + path.d[rp](/[mlcxtrv]/g, function (command) {\n                            return {l: \"L\", c: \"C\", x: \"z\", t: \"m\", r: \"l\", v: \"c\"}[command] || \"M\";\n                        }) + \"z\"\n                };\n                if (path.k) {\n                    for (var k in path.k) if (path[has](k)) {\n                        fontcopy.glyphs[glyph].k[k] = path.k[k];\n                    }\n                }\n            }\n        }\n        return font;\n    };\n    paperproto.getFont = function (family, weight, style, stretch) {\n        stretch = stretch || \"normal\";\n        style = style || \"normal\";\n        weight = +weight || {normal: 400, bold: 700, lighter: 300, bolder: 800}[weight] || 400;\n        if (!R.fonts) {\n            return;\n        }\n        var font = R.fonts[family];\n        if (!font) {\n            var name = new RegExp(\"(^|\\\\s)\" + family[rp](/[^\\w\\d\\s+!~.:_-]/g, E) + \"(\\\\s|$)\", \"i\");\n            for (var fontName in R.fonts) if (R.fonts[has](fontName)) {\n                if (name.test(fontName)) {\n                    font = R.fonts[fontName];\n                    break;\n                }\n            }\n        }\n        var thefont;\n        if (font) {\n            for (var i = 0, ii = font[length]; i < ii; i++) {\n                thefont = font[i];\n                if (thefont.face[\"font-weight\"] == weight && (thefont.face[\"font-style\"] == style || !thefont.face[\"font-style\"]) && thefont.face[\"font-stretch\"] == stretch) {\n                    break;\n                }\n            }\n        }\n        return thefont;\n    };\n    paperproto.print = function (x, y, string, font, size, origin, letter_spacing) {\n        origin = origin || \"middle\"; // baseline|middle\n        letter_spacing = mmax(mmin(letter_spacing || 0, 1), -1);\n        var out = this.set(),\n            letters = Str(string)[split](E),\n            shift = 0,\n            path = E,\n            scale;\n        R.is(font, string) && (font = this.getFont(font));\n        if (font) {\n            scale = (size || 16) / font.face[\"units-per-em\"];\n            var bb = font.face.bbox.split(separator),\n                top = +bb[0],\n                height = +bb[1] + (origin == \"baseline\" ? bb[3] - bb[1] + (+font.face.descent) : (bb[3] - bb[1]) / 2);\n            for (var i = 0, ii = letters[length]; i < ii; i++) {\n                var prev = i && font.glyphs[letters[i - 1]] || {},\n                    curr = font.glyphs[letters[i]];\n                shift += i ? (prev.w || font.w) + (prev.k && prev.k[letters[i]] || 0) + (font.w * letter_spacing) : 0;\n                curr && curr.d && out[push](this.path(curr.d).attr({fill: \"#000\", stroke: \"none\", translation: [shift, 0]}));\n            }\n            out.scale(scale, scale, top, height).translate(x - top, y - height);\n        }\n        return out;\n    };\n\n    R.format = function (token, params) {\n        var args = R.is(params, array) ? [0][concat](params) : arguments;\n        token && R.is(token, string) && args[length] - 1 && (token = token[rp](formatrg, function (str, i) {\n            return args[++i] == null ? E : args[i];\n        }));\n        return token || E;\n    };\n    R.ninja = function () {\n        oldRaphael.was ? (win.Raphael = oldRaphael.is) : delete Raphael;\n        return R;\n    };\n    R.el = elproto;\n    R.st = Set[proto];\n\n    oldRaphael.was ? (win.Raphael = R) : (Raphael = R);\n})();/*!\n * g.Raphael 0.4.1 - Charting library, based on Raphaël\n *\n * Copyright (c) 2009 Dmitry Baranovskiy (http://g.raphaeljs.com)\n * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.\n */\n \n \n(function () {\n    var mmax = Math.max,\n        mmin = Math.min;\n    Raphael.fn.g = Raphael.fn.g || {};\n    Raphael.fn.g.markers = {\n        disc: \"disc\",\n        o: \"disc\",\n        flower: \"flower\",\n        f: \"flower\",\n        diamond: \"diamond\",\n        d: \"diamond\",\n        square: \"square\",\n        s: \"square\",\n        triangle: \"triangle\",\n        t: \"triangle\",\n        star: \"star\",\n        \"*\": \"star\",\n        cross: \"cross\",\n        x: \"cross\",\n        plus: \"plus\",\n        \"+\": \"plus\",\n        arrow: \"arrow\",\n        \"->\": \"arrow\"\n    };\n    Raphael.fn.g.shim = {stroke: \"none\", fill: \"#000\", \"fill-opacity\": 0};\n    Raphael.fn.g.txtattr = {font: \"12px Arial, sans-serif\"};\n    Raphael.fn.g.colors = [];\n    var hues = [.6, .2, .05, .1333, .75, 0];\n    for (var i = 0; i < 10; i++) {\n        if (i < hues.length) {\n            Raphael.fn.g.colors.push(\"hsb(\" + hues[i] + \", .75, .75)\");\n        } else {\n            Raphael.fn.g.colors.push(\"hsb(\" + hues[i - hues.length] + \", 1, .5)\");\n        }\n    }\n    Raphael.fn.g.text = function (x, y, text) {\n        return this.text(x, y, text).attr(this.g.txtattr);\n    };\n    Raphael.fn.g.labelise = function (label, val, total) {\n        if (label) {\n            return (label + \"\").replace(/(##+(?:\\.#+)?)|(%%+(?:\\.%+)?)/g, function (all, value, percent) {\n                if (value) {\n                    return (+val).toFixed(value.replace(/^#+\\.?/g, \"\").length);\n                }\n                if (percent) {\n                    return (val * 100 / total).toFixed(percent.replace(/^%+\\.?/g, \"\").length) + \"%\";\n                }\n            });\n        } else {\n            return (+val).toFixed(0);\n        }\n    };\n\n    Raphael.fn.g.finger = function (x, y, width, height, dir, ending, isPath) {\n        // dir 0 for horisontal and 1 for vertical\n        if ((dir && !height) || (!dir && !width)) {\n            return isPath ? \"\" : this.path();\n        }\n        ending = {square: \"square\", sharp: \"sharp\", soft: \"soft\"}[ending] || \"round\";\n        var path;\n        height = Math.round(height);\n        width = Math.round(width);\n        x = Math.round(x);\n        y = Math.round(y);\n        switch (ending) {\n            case \"round\":\n            if (!dir) {\n                var r = ~~(height / 2);\n                if (width < r) {\n                    r = width;\n                    path = [\"M\", x + .5, y + .5 - ~~(height / 2), \"l\", 0, 0, \"a\", r, ~~(height / 2), 0, 0, 1, 0, height, \"l\", 0, 0, \"z\"];\n                } else {\n                    path = [\"M\", x + .5, y + .5 - r, \"l\", width - r, 0, \"a\", r, r, 0, 1, 1, 0, height, \"l\", r - width, 0, \"z\"];\n                }\n            } else {\n                r = ~~(width / 2);\n                if (height < r) {\n                    r = height;\n                    path = [\"M\", x - ~~(width / 2), y, \"l\", 0, 0, \"a\", ~~(width / 2), r, 0, 0, 1, width, 0, \"l\", 0, 0, \"z\"];\n                } else {\n                    path = [\"M\", x - r, y, \"l\", 0, r - height, \"a\", r, r, 0, 1, 1, width, 0, \"l\", 0, height - r, \"z\"];\n                }\n            }\n            break;\n            case \"sharp\":\n            if (!dir) {\n                var half = ~~(height / 2);\n                path = [\"M\", x, y + half, \"l\", 0, -height, mmax(width - half, 0), 0, mmin(half, width), half, -mmin(half, width), half + (half * 2 < height), \"z\"];\n            } else {\n                half = ~~(width / 2);\n                path = [\"M\", x + half, y, \"l\", -width, 0, 0, -mmax(height - half, 0), half, -mmin(half, height), half, mmin(half, height), half, \"z\"];\n            }\n            break;\n            case \"square\":\n            if (!dir) {\n                path = [\"M\", x, y + ~~(height / 2), \"l\", 0, -height, width, 0, 0, height, \"z\"];\n            } else {\n                path = [\"M\", x + ~~(width / 2), y, \"l\", 1 - width, 0, 0, -height, width - 1, 0, \"z\"];\n            }\n            break;\n            case \"soft\":\n            if (!dir) {\n                r = mmin(width, Math.round(height / 5));\n                path = [\"M\", x + .5, y + .5 - ~~(height / 2), \"l\", width - r, 0, \"a\", r, r, 0, 0, 1, r, r, \"l\", 0, height - r * 2, \"a\", r, r, 0, 0, 1, -r, r, \"l\", r - width, 0, \"z\"];\n            } else {\n                r = mmin(Math.round(width / 5), height);\n                path = [\"M\", x - ~~(width / 2), y, \"l\", 0, r - height, \"a\", r, r, 0, 0, 1, r, -r, \"l\", width - 2 * r, 0, \"a\", r, r, 0, 0, 1, r, r, \"l\", 0, height - r, \"z\"];\n            }\n        }\n        if (isPath) {\n            return path.join(\",\");\n        } else {\n            return this.path(path);\n        }\n    };\n\n    // Symbols\n    Raphael.fn.g.disc = function (cx, cy, r) {\n        return this.circle(cx, cy, r);\n    };\n    Raphael.fn.g.line = function (cx, cy, r) {\n        return this.rect(cx - r, cy - r / 5, 2 * r, 2 * r / 5);\n    };\n    Raphael.fn.g.square = function (cx, cy, r) {\n        r = r * .7;\n        return this.rect(cx - r, cy - r, 2 * r, 2 * r);\n    };\n    Raphael.fn.g.triangle = function (cx, cy, r) {\n        r *= 1.75;\n        return this.path(\"M\".concat(cx, \",\", cy, \"m0-\", r * .58, \"l\", r * .5, \",\", r * .87, \"-\", r, \",0z\"));\n    };\n    Raphael.fn.g.diamond = function (cx, cy, r) {\n        return this.path([\"M\", cx, cy - r, \"l\", r, r, -r, r, -r, -r, r, -r, \"z\"]);\n    };\n    Raphael.fn.g.flower = function (cx, cy, r, n) {\n        r = r * 1.25;\n        var rout = r,\n            rin = rout * .5;\n        n = +n < 3 || !n ? 5 : n;\n        var points = [\"M\", cx, cy + rin, \"Q\"],\n            R;\n        for (var i = 1; i < n * 2 + 1; i++) {\n            R = i % 2 ? rout : rin;\n            points = points.concat([+(cx + R * Math.sin(i * Math.PI / n)).toFixed(3), +(cy + R * Math.cos(i * Math.PI / n)).toFixed(3)]);\n        }\n        points.push(\"z\");\n        return this.path(points.join(\",\"));\n    };\n    Raphael.fn.g.star = function (cx, cy, r, r2, rays) {\n        r2 = r2 || r * .382;\n        rays = rays || 5;\n        var points = [\"M\", cx, cy + r2, \"L\"],\n            R;\n        for (var i = 1; i < rays * 2; i++) {\n            R = i % 2 ? r : r2;\n            points = points.concat([(cx + R * Math.sin(i * Math.PI / rays)), (cy + R * Math.cos(i * Math.PI / rays))]);\n        }\n        points.push(\"z\");\n        return this.path(points.join(\",\"));\n    };\n    Raphael.fn.g.cross = function (cx, cy, r) {\n        r = r / 2.5;\n        return this.path(\"M\".concat(cx - r, \",\", cy, \"l\", [-r, -r, r, -r, r, r, r, -r, r, r, -r, r, r, r, -r, r, -r, -r, -r, r, -r, -r, \"z\"]));\n    };\n    Raphael.fn.g.plus = function (cx, cy, r) {\n        r = r / 2;\n        return this.path(\"M\".concat(cx - r / 2, \",\", cy - r / 2, \"l\", [0, -r, r, 0, 0, r, r, 0, 0, r, -r, 0, 0, r, -r, 0, 0, -r, -r, 0, 0, -r, \"z\"]));\n    };\n    Raphael.fn.g.arrow = function (cx, cy, r) {\n        return this.path(\"M\".concat(cx - r * .7, \",\", cy - r * .4, \"l\", [r * .6, 0, 0, -r * .4, r, r * .8, -r, r * .8, 0, -r * .4, -r * .6, 0], \"z\"));\n    };\n\n    // Tooltips\n    Raphael.fn.g.tag = function (x, y, text, angle, r) {\n        angle = angle || 0;\n        r = r == null ? 5 : r;\n        text = text == null ? \"$9.99\" : text;\n        var R = .5522 * r,\n            res = this.set(),\n            d = 3;\n        res.push(this.path().attr({fill: \"#000\", stroke: \"#000\"}));\n        res.push(this.text(x, y, text).attr(this.g.txtattr).attr({fill: \"#fff\", \"font-family\": \"Helvetica, Arial\"}));\n        res.update = function () {\n            this.rotate(0, x, y);\n            var bb = this[1].getBBox();\n            if (bb.height >= r * 2) {\n                this[0].attr({path: [\"M\", x, y + r, \"a\", r, r, 0, 1, 1, 0, -r * 2, r, r, 0, 1, 1, 0, r * 2, \"m\", 0, -r * 2 -d, \"a\", r + d, r + d, 0, 1, 0, 0, (r + d) * 2, \"L\", x + r + d, y + bb.height / 2 + d, \"l\", bb.width + 2 * d, 0, 0, -bb.height - 2 * d, -bb.width - 2 * d, 0, \"L\", x, y - r - d].join(\",\")});\n            } else {\n                var dx = Math.sqrt(Math.pow(r + d, 2) - Math.pow(bb.height / 2 + d, 2));\n                this[0].attr({path: [\"M\", x, y + r, \"c\", -R, 0, -r, R - r, -r, -r, 0, -R, r - R, -r, r, -r, R, 0, r, r - R, r, r, 0, R, R - r, r, -r, r, \"M\", x + dx, y - bb.height / 2 - d, \"a\", r + d, r + d, 0, 1, 0, 0, bb.height + 2 * d, \"l\", r + d - dx + bb.width + 2 * d, 0, 0, -bb.height - 2 * d, \"L\", x + dx, y - bb.height / 2 - d].join(\",\")});\n            }\n            this[1].attr({x: x + r + d + bb.width / 2, y: y});\n            angle = (360 - angle) % 360;\n            this.rotate(angle, x, y);\n            angle > 90 && angle < 270 && this[1].attr({x: x - r - d - bb.width / 2, y: y, rotation: [180 + angle, x, y]});\n            return this;\n        };\n        res.update();\n        return res;\n    };\n    Raphael.fn.g.popupit = function (x, y, set, dir, size) {\n        dir = dir == null ? 2 : dir;\n        size = size || 5;\n        x = Math.round(x);\n        y = Math.round(y);\n        var bb = set.getBBox(),\n            w = Math.round(bb.width / 2),\n            h = Math.round(bb.height / 2),\n            dx = [0, w + size * 2, 0, -w - size * 2],\n            dy = [-h * 2 - size * 3, -h - size, 0, -h - size],\n            p = [\"M\", x - dx[dir], y - dy[dir], \"l\", -size, (dir == 2) * -size, -mmax(w - size, 0), 0, \"a\", size, size, 0, 0, 1, -size, -size,\n                \"l\", 0, -mmax(h - size, 0), (dir == 3) * -size, -size, (dir == 3) * size, -size, 0, -mmax(h - size, 0), \"a\", size, size, 0, 0, 1, size, -size,\n                \"l\", mmax(w - size, 0), 0, size, !dir * -size, size, !dir * size, mmax(w - size, 0), 0, \"a\", size, size, 0, 0, 1, size, size,\n                \"l\", 0, mmax(h - size, 0), (dir == 1) * size, size, (dir == 1) * -size, size, 0, mmax(h - size, 0), \"a\", size, size, 0, 0, 1, -size, size,\n                \"l\", -mmax(w - size, 0), 0, \"z\"].join(\",\"),\n            xy = [{x: x, y: y + size * 2 + h}, {x: x - size * 2 - w, y: y}, {x: x, y: y - size * 2 - h}, {x: x + size * 2 + w, y: y}][dir];\n        set.translate(xy.x - w - bb.x, xy.y - h - bb.y);\n        return this.path(p).attr({fill: \"#000\", stroke: \"none\"}).insertBefore(set.node ? set : set[0]);\n    };\n    Raphael.fn.g.popup = function (x, y, text, dir, size) {\n        dir = dir == null ? 2 : dir > 3 ? 3 : dir;\n        size = size || 5;\n        text = text || \"$9.99\";\n        var res = this.set(),\n            d = 3;\n        res.push(this.path().attr({fill: \"#000\", stroke: \"#000\"}));\n        res.push(this.text(x, y, text).attr(this.g.txtattr).attr({fill: \"#fff\", \"font-family\": \"Helvetica, Arial\"}));\n        res.update = function (X, Y, withAnimation) {\n            X = X || x;\n            Y = Y || y;\n            var bb = this[1].getBBox(),\n                w = bb.width / 2,\n                h = bb.height / 2,\n                dx = [0, w + size * 2, 0, -w - size * 2],\n                dy = [-h * 2 - size * 3, -h - size, 0, -h - size],\n                p = [\"M\", X - dx[dir], Y - dy[dir], \"l\", -size, (dir == 2) * -size, -mmax(w - size, 0), 0, \"a\", size, size, 0, 0, 1, -size, -size,\n                    \"l\", 0, -mmax(h - size, 0), (dir == 3) * -size, -size, (dir == 3) * size, -size, 0, -mmax(h - size, 0), \"a\", size, size, 0, 0, 1, size, -size,\n                    \"l\", mmax(w - size, 0), 0, size, !dir * -size, size, !dir * size, mmax(w - size, 0), 0, \"a\", size, size, 0, 0, 1, size, size,\n                    \"l\", 0, mmax(h - size, 0), (dir == 1) * size, size, (dir == 1) * -size, size, 0, mmax(h - size, 0), \"a\", size, size, 0, 0, 1, -size, size,\n                    \"l\", -mmax(w - size, 0), 0, \"z\"].join(\",\"),\n                xy = [{x: X, y: Y + size * 2 + h}, {x: X - size * 2 - w, y: Y}, {x: X, y: Y - size * 2 - h}, {x: X + size * 2 + w, y: Y}][dir];\n            xy.path = p;\n            if (withAnimation) {\n                this.animate(xy, 500, \">\");\n            } else {\n                this.attr(xy);\n            }\n            return this;\n        };\n        return res.update(x, y);\n    };\n    Raphael.fn.g.flag = function (x, y, text, angle) {\n        angle = angle || 0;\n        text = text || \"$9.99\";\n        var res = this.set(),\n            d = 3;\n        res.push(this.path().attr({fill: \"#000\", stroke: \"#000\"}));\n        res.push(this.text(x, y, text).attr(this.g.txtattr).attr({fill: \"#fff\", \"font-family\": \"Helvetica, Arial\"}));\n        res.update = function (x, y) {\n            this.rotate(0, x, y);\n            var bb = this[1].getBBox(),\n                h = bb.height / 2;\n            this[0].attr({path: [\"M\", x, y, \"l\", h + d, -h - d, bb.width + 2 * d, 0, 0, bb.height + 2 * d, -bb.width - 2 * d, 0, \"z\"].join(\",\")});\n            this[1].attr({x: x + h + d + bb.width / 2, y: y});\n            angle = 360 - angle;\n            this.rotate(angle, x, y);\n            angle > 90 && angle < 270 && this[1].attr({x: x - r - d - bb.width / 2, y: y, rotation: [180 + angle, x, y]});\n            return this;\n        };\n        return res.update(x, y);\n    };\n    Raphael.fn.g.label = function (x, y, text) {\n        var res = this.set();\n        res.push(this.rect(x, y, 10, 10).attr({stroke: \"none\", fill: \"#000\"}));\n        res.push(this.text(x, y, text).attr(this.g.txtattr).attr({fill: \"#fff\"}));\n        res.update = function () {\n            var bb = this[1].getBBox(),\n                r = mmin(bb.width + 10, bb.height + 10) / 2;\n            this[0].attr({x: bb.x - r / 2, y: bb.y - r / 2, width: bb.width + r, height: bb.height + r, r: r});\n        };\n        res.update();\n        return res;\n    };\n    Raphael.fn.g.labelit = function (set) {\n        var bb = set.getBBox(),\n            r = mmin(20, bb.width + 10, bb.height + 10) / 2;\n        return this.rect(bb.x - r / 2, bb.y - r / 2, bb.width + r, bb.height + r, r).attr({stroke: \"none\", fill: \"#000\"}).insertBefore(set.node ? set : set[0]);\n    };\n    Raphael.fn.g.drop = function (x, y, text, size, angle) {\n        size = size || 30;\n        angle = angle || 0;\n        var res = this.set();\n        res.push(this.path([\"M\", x, y, \"l\", size, 0, \"A\", size * .4, size * .4, 0, 1, 0, x + size * .7, y - size * .7, \"z\"]).attr({fill: \"#000\", stroke: \"none\", rotation: [22.5 - angle, x, y]}));\n        angle = (angle + 90) * Math.PI / 180;\n        res.push(this.text(x + size * Math.sin(angle), y + size * Math.cos(angle), text).attr(this.g.txtattr).attr({\"font-size\": size * 12 / 30, fill: \"#fff\"}));\n        res.drop = res[0];\n        res.text = res[1];\n        return res;\n    };\n    Raphael.fn.g.blob = function (x, y, text, angle, size) {\n        angle = (+angle + 1 ? angle : 45) + 90;\n        size = size || 12;\n        var rad = Math.PI / 180,\n            fontSize = size * 12 / 12;\n        var res = this.set();\n        res.push(this.path().attr({fill: \"#000\", stroke: \"none\"}));\n        res.push(this.text(x + size * Math.sin((angle) * rad), y + size * Math.cos((angle) * rad) - fontSize / 2, text).attr(this.g.txtattr).attr({\"font-size\": fontSize, fill: \"#fff\"}));\n        res.update = function (X, Y, withAnimation) {\n            X = X || x;\n            Y = Y || y;\n            var bb = this[1].getBBox(),\n                w = mmax(bb.width + fontSize, size * 25 / 12),\n                h = mmax(bb.height + fontSize, size * 25 / 12),\n                x2 = X + size * Math.sin((angle - 22.5) * rad),\n                y2 = Y + size * Math.cos((angle - 22.5) * rad),\n                x1 = X + size * Math.sin((angle + 22.5) * rad),\n                y1 = Y + size * Math.cos((angle + 22.5) * rad),\n                dx = (x1 - x2) / 2,\n                dy = (y1 - y2) / 2,\n                rx = w / 2,\n                ry = h / 2,\n                k = -Math.sqrt(Math.abs(rx * rx * ry * ry - rx * rx * dy * dy - ry * ry * dx * dx) / (rx * rx * dy * dy + ry * ry * dx * dx)),\n                cx = k * rx * dy / ry + (x1 + x2) / 2,\n                cy = k * -ry * dx / rx + (y1 + y2) / 2;\n            if (withAnimation) {\n                this.animate({x: cx, y: cy, path: [\"M\", x, y, \"L\", x1, y1, \"A\", rx, ry, 0, 1, 1, x2, y2, \"z\"].join(\",\")}, 500, \">\");\n            } else {\n                this.attr({x: cx, y: cy, path: [\"M\", x, y, \"L\", x1, y1, \"A\", rx, ry, 0, 1, 1, x2, y2, \"z\"].join(\",\")});\n            }\n            return this;\n        };\n        res.update(x, y);\n        return res;\n    };\n\n    Raphael.fn.g.colorValue = function (value, total, s, b) {\n        return \"hsb(\" + [mmin((1 - value / total) * .4, 1), s || .75, b || .75] + \")\";\n    };\n\n    Raphael.fn.g.snapEnds = function (from, to, steps) {\n        var f = from,\n            t = to;\n        if (f == t) {\n            return {from: f, to: t, power: 0};\n        }\n        function round(a) {\n            return Math.abs(a - .5) < .25 ? ~~(a) + .5 : Math.round(a);\n        }\n        var d = (t - f) / steps,\n            r = ~~(d),\n            R = r,\n            i = 0;\n        if (r) {\n            while (R) {\n                i--;\n                R = ~~(d * Math.pow(10, i)) / Math.pow(10, i);\n            }\n            i ++;\n        } else {\n            while (!r) {\n                i = i || 1;\n                r = ~~(d * Math.pow(10, i)) / Math.pow(10, i);\n                i++;\n            }\n            i && i--;\n        }\n        t = round(to * Math.pow(10, i)) / Math.pow(10, i);\n        if (t < to) {\n            t = round((to + .5) * Math.pow(10, i)) / Math.pow(10, i);\n        }\n        f = round((from - (i > 0 ? 0 : .5)) * Math.pow(10, i)) / Math.pow(10, i);\n        return {from: f, to: t, power: i};\n    };\n    Raphael.fn.g.axis = function (x, y, length, from, to, steps, orientation, labels, type, dashsize) {\n        dashsize = dashsize == null ? 2 : dashsize;\n        type = type || \"t\";\n        steps = steps || 10;\n        var path = type == \"|\" || type == \" \" ? [\"M\", x + .5, y, \"l\", 0, .001] : orientation == 1 || orientation == 3 ? [\"M\", x + .5, y, \"l\", 0, -length] : [\"M\", x, y + .5, \"l\", length, 0],\n            ends = this.g.snapEnds(from, to, steps),\n            f = ends.from,\n            t = ends.to,\n            i = ends.power,\n            j = 0,\n            text = this.set();\n        d = (t - f) / steps;\n        var label = f,\n            rnd = i > 0 ? i : 0;\n            dx = length / steps;\n        if (+orientation == 1 || +orientation == 3) {\n            var Y = y,\n                addon = (orientation - 1 ? 1 : -1) * (dashsize + 3 + !!(orientation - 1));\n            while (Y >= y - length) {\n                type != \"-\" && type != \" \" && (path = path.concat([\"M\", x - (type == \"+\" || type == \"|\" ? dashsize : !(orientation - 1) * dashsize * 2), Y + .5, \"l\", dashsize * 2 + 1, 0]));\n                text.push(this.text(x + addon, Y, (labels && labels[j++]) || (Math.round(label) == label ? label : +label.toFixed(rnd))).attr(this.g.txtattr).attr({\"text-anchor\": orientation - 1 ? \"start\" : \"end\"}));\n                label += d;\n                Y -= dx;\n            }\n            if (Math.round(Y + dx - (y - length))) {\n                type != \"-\" && type != \" \" && (path = path.concat([\"M\", x - (type == \"+\" || type == \"|\" ? dashsize : !(orientation - 1) * dashsize * 2), y - length + .5, \"l\", dashsize * 2 + 1, 0]));\n                text.push(this.text(x + addon, y - length, (labels && labels[j]) || (Math.round(label) == label ? label : +label.toFixed(rnd))).attr(this.g.txtattr).attr({\"text-anchor\": orientation - 1 ? \"start\" : \"end\"}));\n            }\n        } else {\n            label = f;\n            rnd = (i > 0) * i;\n            addon = (orientation ? -1 : 1) * (dashsize + 9 + !orientation);\n            var X = x,\n                dx = length / steps,\n                txt = 0,\n                prev = 0;\n            while (X <= x + length) {\n                type != \"-\" && type != \" \" && (path = path.concat([\"M\", X + .5, y - (type == \"+\" ? dashsize : !!orientation * dashsize * 2), \"l\", 0, dashsize * 2 + 1]));\n                text.push(txt = this.text(X, y + addon, (labels && labels[j++]) || (Math.round(label) == label ? label : +label.toFixed(rnd))).attr(this.g.txtattr));\n                var bb = txt.getBBox();\n                if (prev >= bb.x - 5) {\n                    text.pop(text.length - 1).remove();\n                } else {\n                    prev = bb.x + bb.width;\n                }\n                label += d;\n                X += dx;\n            }\n            if (Math.round(X - dx - x - length)) {\n                type != \"-\" && type != \" \" && (path = path.concat([\"M\", x + length + .5, y - (type == \"+\" ? dashsize : !!orientation * dashsize * 2), \"l\", 0, dashsize * 2 + 1]));\n                text.push(this.text(x + length, y + addon, (labels && labels[j]) || (Math.round(label) == label ? label : +label.toFixed(rnd))).attr(this.g.txtattr));\n            }\n        }\n        var res = this.path(path);\n        res.text = text;\n        res.all = this.set([res, text]);\n        res.remove = function () {\n            this.text.remove();\n            this.constructor.prototype.remove.call(this);\n        };\n        return res;\n    };\n\n    Raphael.el.lighter = function (times) {\n        times = times || 2;\n        var fs = [this.attrs.fill, this.attrs.stroke];\n        this.fs = this.fs || [fs[0], fs[1]];\n        fs[0] = Raphael.rgb2hsb(Raphael.getRGB(fs[0]).hex);\n        fs[1] = Raphael.rgb2hsb(Raphael.getRGB(fs[1]).hex);\n        fs[0].b = mmin(fs[0].b * times, 1);\n        fs[0].s = fs[0].s / times;\n        fs[1].b = mmin(fs[1].b * times, 1);\n        fs[1].s = fs[1].s / times;\n        this.attr({fill: \"hsb(\" + [fs[0].h, fs[0].s, fs[0].b] + \")\", stroke: \"hsb(\" + [fs[1].h, fs[1].s, fs[1].b] + \")\"});\n    };\n    Raphael.el.darker = function (times) {\n        times = times || 2;\n        var fs = [this.attrs.fill, this.attrs.stroke];\n        this.fs = this.fs || [fs[0], fs[1]];\n        fs[0] = Raphael.rgb2hsb(Raphael.getRGB(fs[0]).hex);\n        fs[1] = Raphael.rgb2hsb(Raphael.getRGB(fs[1]).hex);\n        fs[0].s = mmin(fs[0].s * times, 1);\n        fs[0].b = fs[0].b / times;\n        fs[1].s = mmin(fs[1].s * times, 1);\n        fs[1].b = fs[1].b / times;\n        this.attr({fill: \"hsb(\" + [fs[0].h, fs[0].s, fs[0].b] + \")\", stroke: \"hsb(\" + [fs[1].h, fs[1].s, fs[1].b] + \")\"});\n    };\n    Raphael.el.original = function () {\n        if (this.fs) {\n            this.attr({fill: this.fs[0], stroke: this.fs[1]});\n            delete this.fs;\n        }\n    };\n})();/*!\n * g.Raphael 0.4.1 - Charting library, based on Raphaël\n *\n * Copyright (c) 2009 Dmitry Baranovskiy (http://g.raphaeljs.com)\n * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.\n */\nRaphael.fn.g.barchart = function (x, y, width, height, values, opts) {\n    opts = opts || {};\n    var type = {round: \"round\", sharp: \"sharp\", soft: \"soft\"}[opts.type] || \"square\",\n        gutter = parseFloat(opts.gutter || \"20%\"),\n        chart = this.set(),\n        bars = this.set(),\n        covers = this.set(),\n        covers2 = this.set(),\n        total = Math.max.apply(Math, values),\n        stacktotal = [],\n        paper = this,\n        multi = 0,\n        colors = opts.colors || this.g.colors,\n        len = values.length;\n    if (this.raphael.is(values[0], \"array\")) {\n        total = [];\n        multi = len;\n        len = 0;\n        for (var i = values.length; i--;) {\n            bars.push(this.set());\n            total.push(Math.max.apply(Math, values[i]));\n            len = Math.max(len, values[i].length);\n        }\n        if (opts.stacked) {\n            for (var i = len; i--;) {\n                var tot = 0;\n                for (var j = values.length; j--;) {\n                    tot +=+ values[j][i] || 0;\n                }\n                stacktotal.push(tot);\n            }\n        }\n        for (var i = values.length; i--;) {\n            if (values[i].length < len) {\n                for (var j = len; j--;) {\n                    values[i].push(0);\n                }\n            }\n        }\n        total = Math.max.apply(Math, opts.stacked ? stacktotal : total);\n    }\n    \n    total = (opts.to) || total;\n    var barwidth = width / (len * (100 + gutter) + gutter) * 100,\n        barhgutter = barwidth * gutter / 100,\n        barvgutter = opts.vgutter == null ? 20 : opts.vgutter,\n        stack = [],\n        X = x + barhgutter,\n        Y = (height - 2 * barvgutter) / total;\n    if (!opts.stretch) {\n        barhgutter = Math.round(barhgutter);\n        barwidth = Math.floor(barwidth);\n    }\n    !opts.stacked && (barwidth /= multi || 1);\n    for (var i = 0; i < len; i++) {\n        stack = [];\n        for (var j = 0; j < (multi || 1); j++) {\n            var h = Math.round((multi ? values[j][i] : values[i]) * Y),\n                top = y + height - barvgutter - h,\n                bar = this.g.finger(Math.round(X + barwidth / 2), top + h, barwidth, h, true, type).attr({stroke: \"none\", fill: colors[multi ? j : i]});\n            if (multi) {\n                bars[j].push(bar);\n            } else {\n                bars.push(bar);\n            }\n            bar.y = top;\n            bar.x = Math.round(X + barwidth / 2);\n            bar.w = barwidth;\n            bar.h = h;\n\t\t\t\t\t\tbar.index = i;\n            bar.value = multi ? values[j][i] : values[i];\n            if (!opts.stacked) {\n                X += barwidth;\n            } else {\n                stack.push(bar);\n            }\n        }\n        if (opts.stacked) {\n            var cvr;\n            covers2.push(cvr = this.rect(stack[0].x - stack[0].w / 2, y, barwidth, height).attr(this.g.shim));\n            cvr.bars = this.set();\n            var size = 0;\n            for (var s = stack.length; s--;) {\n                stack[s].toFront();\n            }\n            for (var s = 0, ss = stack.length; s < ss; s++) {\n                var bar = stack[s],\n                    cover,\n                    h = (size + bar.value) * Y,\n                    path = this.g.finger(bar.x, y + height - barvgutter - !!size * .5, barwidth, h, true, type, 1);\n                cvr.bars.push(bar);\n                size && bar.attr({path: path});\n                bar.h = h;\n                bar.y = y + height - barvgutter - !!size * .5 - h;\n                covers.push(cover = this.rect(bar.x - bar.w / 2, bar.y, barwidth, bar.value * Y).attr(this.g.shim));\n                cover.bar = bar;\n                cover.value = bar.value;\n                size += bar.value;\n            }\n            X += barwidth;\n        }\n        X += barhgutter;\n    }\n    covers2.toFront();\n    X = x + barhgutter;\n    if (!opts.stacked) {\n        for (var i = 0; i < len; i++) {\n            for (var j = 0; j < (multi || 1); j++) {\n                var cover;\n                covers.push(cover = this.rect(Math.round(X), y + barvgutter, barwidth, height - barvgutter).attr(this.g.shim));\n                cover.bar = multi ? bars[j][i] : bars[i];\n                cover.value = cover.bar.value;\n                X += barwidth;\n            }\n            X += barhgutter;\n        }\n    }\n    chart.label = function (labels, isBottom, rotate) {\n        labels = labels || [];\n        isBottom = isBottom == undefined ? true : isBottom;\n\trotate = rotate == undefined ? false : rotate;\n        this.labels = paper.set();\n        var L, l = -Infinity;\n        if (opts.stacked) {\n            for (var i = 0; i < len; i++) {\n                var tot = 0;\n                for (var j = 0; j < (multi || 1); j++) {\n                    tot += multi ? values[j][i] : values[i];\n                    if (j == 0) {\n                        var label = paper.g.labelise(labels[j][i], tot, total);\n                        L = paper.g.text(bars[j][i].x, isBottom ? y + height - barvgutter / 2 : bars[j][i].y - 10, label);\n\t\t\tif (rotate) {\n\t\t\t\tL.rotate(90);\n\t\t\t}\n                        var bb = L.getBBox();\n                        if (bb.x - 7 < l) {\n                            L.remove();\n                        } else {\n                            this.labels.push(L);\n                            l = bb.x + (rotate ? bb.height : bb.width);\n                        }\n                    }\n                }\n            }\n        } else {\n            for (var i = 0; i < len; i++) {\n                for (var j = 0; j < (multi || 1); j++) {\n                    // did not remove the loop because don't yet know whether to accept multi array input for arrays\n                    var label = paper.g.labelise(multi ? labels[0] && labels[0][i] : labels[i], multi ? values[0][i] : values[i], total);\n                     L = paper.g.text(bars[0][i].x, isBottom ? y + 5 + height - barvgutter / 2 : bars[0][i].y - 10, label);\n\t\t\tif (rotate) {\n\t\t\t\tL.rotate(90);\n\t\t\t\t// If we rotated it, we need to move it as well. Still have to use the width\n\t\t\t\t// to get the \"length\" of the label, divided it in two and shift down.\n\t\t\t\tL.translate(0, (L.getBBox().width / 2));\n\t\t\t}\n                    var bb = L.getBBox();\n//                    if (bb.x - 7 < l) {\n                    if (bb.x - (this.getBBox().width) < l) {\n                        L.remove();\n                    } else {\n                        this.labels.push(L);\n                        l = bb.x + (rotate ? bb.height : bb.width);\n                    }\n                }\n            }\n        }\n        return this;\n    };\n    chart.hover = function (fin, fout) {\n        covers2.hide();\n        covers.show();\n        covers.mouseover(fin).mouseout(fout);\n        return this;\n    };\n    chart.hoverColumn = function (fin, fout) {\n        covers.hide();\n        covers2.show();\n        fout = fout || function () {};\n        covers2.mouseover(fin).mouseout(fout);\n        return this;\n    };\n    chart.click = function (f) {\n        covers2.hide();\n        covers.show();\n        covers.click(f);\n        return this;\n    };\n    chart.each = function (f) {\n        if (!Raphael.is(f, \"function\")) {\n            return this;\n        }\n        for (var i = covers.length; i--;) {\n            f.call(covers[i]);\n        }\n        return this;\n    };\n    chart.eachColumn = function (f) {\n        if (!Raphael.is(f, \"function\")) {\n            return this;\n        }\n        for (var i = covers2.length; i--;) {\n            f.call(covers2[i]);\n        }\n        return this;\n    };\n    chart.clickColumn = function (f) {\n        covers.hide();\n        covers2.show();\n        covers2.click(f);\n        return this;\n    };\n    chart.push(bars, covers, covers2);\n    chart.bars = bars;\n    chart.covers = covers;\n    return chart;\n};\nRaphael.fn.g.hbarchart = function (x, y, width, height, values, opts) {\n    opts = opts || {};\n    var type = {round: \"round\", sharp: \"sharp\", soft: \"soft\"}[opts.type] || \"square\",\n        gutter = parseFloat(opts.gutter || \"20%\"),\n        chart = this.set(),\n        bars = this.set(),\n        covers = this.set(),\n        covers2 = this.set(),\n        total = Math.max.apply(Math, values),\n        stacktotal = [],\n        paper = this,\n        multi = 0,\n        colors = opts.colors || this.g.colors,\n        len = values.length;\n    if (this.raphael.is(values[0], \"array\")) {\n        total = [];\n        multi = len;\n        len = 0;\n        for (var i = values.length; i--;) {\n            bars.push(this.set());\n            total.push(Math.max.apply(Math, values[i]));\n            len = Math.max(len, values[i].length);\n        }\n        if (opts.stacked) {\n            for (var i = len; i--;) {\n                var tot = 0;\n                for (var j = values.length; j--;) {\n                    tot +=+ values[j][i] || 0;\n                }\n                stacktotal.push(tot);\n            }\n        }\n        for (var i = values.length; i--;) {\n            if (values[i].length < len) {\n                for (var j = len; j--;) {\n                    values[i].push(0);\n                }\n            }\n        }\n        total = Math.max.apply(Math, opts.stacked ? stacktotal : total);\n    }\n    \n    total = (opts.to) || total;\n    var barheight = Math.floor(height / (len * (100 + gutter) + gutter) * 100),\n        bargutter = Math.floor(barheight * gutter / 100),\n        stack = [],\n        Y = y + bargutter,\n        X = (width - 1) / total;\n    !opts.stacked && (barheight /= multi || 1);\n    for (var i = 0; i < len; i++) {\n        stack = [];\n        for (var j = 0; j < (multi || 1); j++) {\n            var val = multi ? values[j][i] : values[i],\n                bar = this.g.finger(x, Y + barheight / 2, Math.round(val * X), barheight - 1, false, type).attr({stroke: \"none\", fill: colors[multi ? j : i]});\n            if (multi) {\n                bars[j].push(bar);\n            } else {\n                bars.push(bar);\n            }\n            bar.x = x + Math.round(val * X);\n            bar.y = Y + barheight / 2;\n            bar.w = Math.round(val * X);\n            bar.h = barheight;\n            bar.value = +val;\n            if (!opts.stacked) {\n                Y += barheight;\n            } else {\n                stack.push(bar);\n            }\n        }\n        if (opts.stacked) {\n            var cvr = this.rect(x, stack[0].y - stack[0].h / 2, width, barheight).attr(this.g.shim);\n            covers2.push(cvr);\n            cvr.bars = this.set();\n            var size = 0;\n            for (var s = stack.length; s--;) {\n                stack[s].toFront();\n            }\n            for (var s = 0, ss = stack.length; s < ss; s++) {\n                var bar = stack[s],\n                    cover,\n                    val = Math.round((size + bar.value) * X),\n                    path = this.g.finger(x, bar.y, val, barheight - 1, false, type, 1);\n                cvr.bars.push(bar);\n                size && bar.attr({path: path});\n                bar.w = val;\n                bar.x = x + val;\n                covers.push(cover = this.rect(x + size * X, bar.y - bar.h / 2, bar.value * X, barheight).attr(this.g.shim));\n                cover.bar = bar;\n                size += bar.value;\n            }\n            Y += barheight;\n        }\n        Y += bargutter;\n    }\n    covers2.toFront();\n    Y = y + bargutter;\n    if (!opts.stacked) {\n        for (var i = 0; i < len; i++) {\n            for (var j = 0; j < (multi || 1); j++) {\n                var cover = this.rect(x, Y, width, barheight).attr(this.g.shim);\n                covers.push(cover);\n                cover.bar = multi ? bars[j][i] : bars[i];\n                cover.value = cover.bar.value;\n                Y += barheight;\n            }\n            Y += bargutter;\n        }\n    }\n    chart.label = function (labels, isRight) {\n        labels = labels || [];\n        this.labels = paper.set();\n        for (var i = 0; i < len; i++) {\n            for (var j = 0; j < multi; j++) {\n                var  label = paper.g.labelise(multi ? labels[j] && labels[j][i] : labels[i], multi ? values[j][i] : values[i], total);\n                var X = isRight ? bars[i * (multi || 1) + j].x - barheight / 2 + 3 : x + 5,\n                    A = isRight ? \"end\" : \"start\",\n                    L;\n                this.labels.push(L = paper.g.text(X, bars[i * (multi || 1) + j].y, label).attr({\"text-anchor\": A}).insertBefore(covers[0]));\n                if (L.getBBox().x < x + 5) {\n                    L.attr({x: x + 5, \"text-anchor\": \"start\"});\n                } else {\n                    bars[i * (multi || 1) + j].label = L;\n                }\n            }\n        }\n        return this;\n    };\n    chart.hover = function (fin, fout) {\n        covers2.hide();\n        covers.show();\n        fout = fout || function () {};\n        covers.mouseover(fin).mouseout(fout);\n        return this;\n    };\n    chart.hoverColumn = function (fin, fout) {\n        covers.hide();\n        covers2.show();\n        fout = fout || function () {};\n        covers2.mouseover(fin).mouseout(fout);\n        return this;\n    };\n    chart.each = function (f) {\n        if (!Raphael.is(f, \"function\")) {\n            return this;\n        }\n        for (var i = covers.length; i--;) {\n            f.call(covers[i]);\n        }\n        return this;\n    };\n    chart.eachColumn = function (f) {\n        if (!Raphael.is(f, \"function\")) {\n            return this;\n        }\n        for (var i = covers2.length; i--;) {\n            f.call(covers2[i]);\n        }\n        return this;\n    };\n    chart.click = function (f) {\n        covers2.hide();\n        covers.show();\n        covers.click(f);\n        return this;\n    };\n    chart.clickColumn = function (f) {\n        covers.hide();\n        covers2.show();\n        covers2.click(f);\n        return this;\n    };\n    chart.push(bars, covers, covers2);\n    chart.bars = bars;\n    chart.covers = covers;\n    return chart;\n};\n/*!\n * g.Raphael 0.4.1 - Charting library, based on Raphaël\n *\n * Copyright (c) 2009 Dmitry Baranovskiy (http://g.raphaeljs.com)\n * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.\n */\nRaphael.fn.g.dotchart = function (x, y, width, height, valuesx, valuesy, size, opts) {\n    function drawAxis(ax) {\n        +ax[0] && (ax[0] = paper.g.axis(x + gutter, y + gutter, width - 2 * gutter, minx, maxx, opts.axisxstep || Math.floor((width - 2 * gutter) / 20), 2, opts.axisxlabels || null, opts.axisxtype || \"t\"));\n        +ax[1] && (ax[1] = paper.g.axis(x + width - gutter, y + height - gutter, height - 2 * gutter, miny, maxy, opts.axisystep || Math.floor((height - 2 * gutter) / 20), 3, opts.axisylabels || null, opts.axisytype || \"t\"));\n        +ax[2] && (ax[2] = paper.g.axis(x + gutter, y + height - gutter + maxR, width - 2 * gutter, minx, maxx, opts.axisxstep || Math.floor((width - 2 * gutter) / 20), 0, opts.axisxlabels || null, opts.axisxtype || \"t\"));\n        +ax[3] && (ax[3] = paper.g.axis(x + gutter - maxR, y + height - gutter, height - 2 * gutter, miny, maxy, opts.axisystep || Math.floor((height - 2 * gutter) / 20), 1, opts.axisylabels || null, opts.axisytype || \"t\"));\n    }\n    opts = opts || {};\n    var xdim = this.g.snapEnds(Math.min.apply(Math, valuesx), Math.max.apply(Math, valuesx), valuesx.length - 1),\n        minx = xdim.from,\n        maxx = xdim.to,\n        gutter = opts.gutter || 10,\n        ydim = this.g.snapEnds(Math.min.apply(Math, valuesy), Math.max.apply(Math, valuesy), valuesy.length - 1),\n        miny = ydim.from,\n        maxy = ydim.to,\n        len = Math.max(valuesx.length, valuesy.length, size.length),\n        symbol = this.g.markers[opts.symbol] || \"disc\",\n        res = this.set(),\n        series = this.set(),\n        max = opts.max || 100,\n        top = Math.max.apply(Math, size),\n        R = [],\n        paper = this,\n        k = Math.sqrt(top / Math.PI) * 2 / max;\n\n    for (var i = 0; i < len; i++) {\n        R[i] = Math.min(Math.sqrt(size[i] / Math.PI) * 2 / k, max);\n    }\n    gutter = Math.max.apply(Math, R.concat(gutter));\n    var axis = this.set(),\n        maxR = Math.max.apply(Math, R);\n    if (opts.axis) {\n        var ax = (opts.axis + \"\").split(/[,\\s]+/);\n        drawAxis(ax);\n        var g = [], b = [];\n        for (var i = 0, ii = ax.length; i < ii; i++) {\n            var bb = ax[i].all ? ax[i].all.getBBox()[[\"height\", \"width\"][i % 2]] : 0;\n            g[i] = bb + gutter;\n            b[i] = bb;\n        }\n        gutter = Math.max.apply(Math, g.concat(gutter));\n        for (var i = 0, ii = ax.length; i < ii; i++) if (ax[i].all) {\n            ax[i].remove();\n            ax[i] = 1;\n        }\n        drawAxis(ax);\n        for (var i = 0, ii = ax.length; i < ii; i++) if (ax[i].all) {\n            axis.push(ax[i].all);\n        }\n        res.axis = axis;\n    }\n    var kx = (width - gutter * 2) / ((maxx - minx) || 1),\n        ky = (height - gutter * 2) / ((maxy - miny) || 1);\n    for (var i = 0, ii = valuesy.length; i < ii; i++) {\n        var sym = this.raphael.is(symbol, \"array\") ? symbol[i] : symbol,\n            X = x + gutter + (valuesx[i] - minx) * kx,\n            Y = y + height - gutter - (valuesy[i] - miny) * ky;\n        sym && R[i] && series.push(this.g[sym](X, Y, R[i]).attr({fill: opts.heat ? this.g.colorValue(R[i], maxR) : Raphael.fn.g.colors[0], \"fill-opacity\": opts.opacity ? R[i] / max : 1, stroke: \"none\"}));\n    }\n    var covers = this.set();\n    for (var i = 0, ii = valuesy.length; i < ii; i++) {\n        var X = x + gutter + (valuesx[i] - minx) * kx,\n            Y = y + height - gutter - (valuesy[i] - miny) * ky;\n        covers.push(this.circle(X, Y, maxR).attr(this.g.shim));\n        opts.href && opts.href[i] && covers[i].attr({href: opts.href[i]});\n        covers[i].r = +R[i].toFixed(3);\n        covers[i].x = +X.toFixed(3);\n        covers[i].y = +Y.toFixed(3);\n        covers[i].X = valuesx[i];\n        covers[i].Y = valuesy[i];\n        covers[i].value = size[i] || 0;\n        covers[i].dot = series[i];\n    }\n    res.covers = covers;\n    res.series = series;\n    res.push(series, axis, covers);\n    res.hover = function (fin, fout) {\n        covers.mouseover(fin).mouseout(fout);\n        return this;\n    };\n    res.click = function (f) {\n        covers.click(f);\n        return this;\n    };\n    res.each = function (f) {\n        if (!Raphael.is(f, \"function\")) {\n            return this;\n        }\n        for (var i = covers.length; i--;) {\n            f.call(covers[i]);\n        }\n        return this;\n    };\n    res.href = function (map) {\n        var cover;\n        for (var i = covers.length; i--;) {\n            cover = covers[i];\n            if (cover.X == map.x && cover.Y == map.y && cover.value == map.value) {\n                cover.attr({href: map.href});\n            }\n        }\n    };\n    return res;\n};\n/*!\n * g.Raphael 0.4.2 - Charting library, based on Raphaël\n *\n * Copyright (c) 2009 Dmitry Baranovskiy (http://g.raphaeljs.com)\n * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.\n */\nRaphael.fn.g.linechart = function (x, y, width, height, valuesx, valuesy, opts) {\n    function shrink(values, dim) {\n        var k = values.length / dim,\n            j = 0,\n            l = k,\n            sum = 0,\n            res = [];\n        while (j < values.length) {\n            l--;\n            if (l < 0) {\n                sum += values[j] * (1 + l);\n                res.push(sum / k);\n                sum = values[j++] * -l;\n                l += k;\n            } else {\n                sum += values[j++];\n            }\n        }\n        return res;\n    }\n    function getAnchors(p1x, p1y, p2x, p2y, p3x, p3y) {\n        var l1 = (p2x - p1x) / 2,\n            l2 = (p3x - p2x) / 2,\n            a = Math.atan((p2x - p1x) / Math.abs(p2y - p1y)),\n            b = Math.atan((p3x - p2x) / Math.abs(p2y - p3y));\n        a = p1y < p2y ? Math.PI - a : a;\n        b = p3y < p2y ? Math.PI - b : b;\n        var alpha = Math.PI / 2 - ((a + b) % (Math.PI * 2)) / 2,\n            dx1 = l1 * Math.sin(alpha + a),\n            dy1 = l1 * Math.cos(alpha + a),\n            dx2 = l2 * Math.sin(alpha + b),\n            dy2 = l2 * Math.cos(alpha + b);\n        return {\n            x1: p2x - dx1,\n            y1: p2y + dy1,\n            x2: p2x + dx2,\n            y2: p2y + dy2\n        };\n    }\n    opts = opts || {};\n    if (!this.raphael.is(valuesx[0], \"array\")) {\n        valuesx = [valuesx];\n    }\n    if (!this.raphael.is(valuesy[0], \"array\")) {\n        valuesy = [valuesy];\n    }\n    var gutter = opts.gutter || 10,\n        len = Math.max(valuesx[0].length, valuesy[0].length),\n        symbol = opts.symbol || \"\",\n        colors = opts.colors || Raphael.fn.g.colors,\n        that = this,\n        columns = null,\n        dots = null,\n        chart = this.set(),\n        path = [];\n\n    for (var i = 0, ii = valuesy.length; i < ii; i++) {\n        len = Math.max(len, valuesy[i].length);\n    }\n    var shades = this.set();\n    for (i = 0, ii = valuesy.length; i < ii; i++) {\n        if (opts.shade) {\n            shades.push(this.path().attr({stroke: \"none\", fill: colors[i], opacity: opts.nostroke ? 1 : .3}));\n        }\n        if (valuesy[i].length > width - 2 * gutter) {\n            valuesy[i] = shrink(valuesy[i], width - 2 * gutter);\n            len = width - 2 * gutter;\n        }\n        if (valuesx[i] && valuesx[i].length > width - 2 * gutter) {\n            valuesx[i] = shrink(valuesx[i], width - 2 * gutter);\n        }\n    }\n    var allx = Array.prototype.concat.apply([], valuesx),\n        ally = Array.prototype.concat.apply([], valuesy),\n        xdim = this.g.snapEnds(Math.min.apply(Math, allx), Math.max.apply(Math, allx), valuesx[0].length - 1);\n        if(opts.clip) {\n            var minx = opts.minx || xdim.from,\n                maxx = opts.maxx || xdim.to,\n                ydim = this.g.snapEnds(Math.min.apply(Math, ally), Math.max.apply(Math, ally), valuesy[0].length - 1),\n                miny = opts.miny || ydim.from,\n                maxy = opts.maxy || ydim.to;\n        } else {\n            var minx = opts.minx && Math.min(opts.minx, xdim.from) || xdim.from,\n                maxx = opts.maxx && Math.max(opts.maxx, xdimt.to) || xdim.to,\n                ydim = this.g.snapEnds(Math.min.apply(Math, ally), Math.max.apply(Math, ally), valuesy[0].length - 1),\n                miny = opts.miny && Math.min(opts.miny, ydim.from) || ydim.from,\n                maxy = opts.maxy && Math.max(opts.maxy, ydim.to) || ydim.to;\n        }\n        kx = (width - gutter * 2) / ((maxx - minx) || 1),\n        ky = (height - gutter * 2) / ((maxy - miny) || 1);\n\n    var lines = this.set(),\n        symbols = this.set(),\n        line;\n    for (i = 0, ii = valuesy.length; i < ii; i++) {\n        if (!opts.nostroke) {\n            lines.push(line = this.path().attr({\n                stroke: colors[i],\n                \"stroke-width\": opts.width || 2,\n                \"stroke-linejoin\": \"round\",\n                \"stroke-linecap\": \"round\",\n                \"stroke-dasharray\": opts.dash || \"\"\n            }));\n        }\n        var sym = this.raphael.is(symbol, \"array\") ? symbol[i] : symbol,\n            symset = this.set();\n        path = [];\n        for (var j = 0, jj = valuesy[i].length; j < jj; j++) {\n            var X = x + gutter + ((valuesx[i] || valuesx[0])[j] - minx) * kx,\n                Y = y + height - gutter - (valuesy[i][j] - miny) * ky;\n            (Raphael.is(sym, \"array\") ? sym[j] : sym) && symset.push(this.g[Raphael.fn.g.markers[this.raphael.is(sym, \"array\") ? sym[j] : sym]](X, Y, (opts.width || 2) * 3).attr({fill: colors[i], stroke: \"none\"}));\n            if (opts.smooth) {\n                if (j && j != jj - 1) {\n                    var X0 = x + gutter + ((valuesx[i] || valuesx[0])[j - 1] - minx) * kx,\n                        Y0 = y + height - gutter - (valuesy[i][j - 1] - miny) * ky,\n                        X2 = x + gutter + ((valuesx[i] || valuesx[0])[j + 1] - minx) * kx,\n                        Y2 = y + height - gutter - (valuesy[i][j + 1] - miny) * ky;\n                    var a = getAnchors(X0, Y0, X, Y, X2, Y2);\n                    path = path.concat([a.x1, a.y1, X, Y, a.x2, a.y2]);\n                }\n                if (!j) {\n                    path = [\"M\", X, Y, \"C\", X, Y];\n                }\n            } else {\n                path = path.concat([j ? \"L\" : \"M\", X, Y]);\n            }\n        }\n        if (opts.smooth) {\n            path = path.concat([X, Y, X, Y]);\n        }\n        symbols.push(symset);\n        if (opts.shade) {\n            shades[i].attr({path: path.concat([\"L\", X, y + height - gutter, \"L\",  x + gutter + ((valuesx[i] || valuesx[0])[0] - minx) * kx, y + height - gutter, \"z\"]).join(\",\")});\n        }\n        !opts.nostroke && line.attr({path: path.join(\",\"), 'clip-rect': [x + gutter, y + gutter, width - 2 * gutter, height - 2 * gutter].join(\",\")});\n    }\n\n    function createColumns(f) {\n        // unite Xs together\n        var Xs = [];\n        for (var i = 0, ii = valuesx.length; i < ii; i++) {\n            Xs = Xs.concat(valuesx[i]);\n        }\n        Xs.sort(function(a,b) { return a - b; });\n        // remove duplicates\n        var Xs2 = [],\n            xs = [];\n        for (i = 0, ii = Xs.length; i < ii; i++) {\n            Xs[i] != Xs[i - 1] && Xs2.push(Xs[i]) && xs.push(x + gutter + (Xs[i] - minx) * kx);\n        }\n        Xs = Xs2;\n        ii = Xs.length;\n        var cvrs = f || that.set();\n        for (i = 0; i < ii; i++) {\n            var X = xs[i] - (xs[i] - (xs[i - 1] || x)) / 2,\n                w = ((xs[i + 1] || x + width) - xs[i]) / 2 + (xs[i] - (xs[i - 1] || x)) / 2,\n                C;\n            f ? (C = {}) : cvrs.push(C = that.rect(X - 1, y, Math.max(w + 1, 1), height).attr({stroke: \"none\", fill: \"#000\", opacity: 0}));\n            C.values = [];\n            C.symbols = that.set();\n            C.y = [];\n            C.x = xs[i];\n            C.axis = Xs[i];\n            for (var j = 0, jj = valuesy.length; j < jj; j++) {\n                Xs2 = valuesx[j] || valuesx[0];\n                for (var k = 0, kk = Xs2.length; k < kk; k++) {\n                    if (Xs2[k] == Xs[i]) {\n                        C.values.push(valuesy[j][k]);\n                        C.y.push(y + height - gutter - (valuesy[j][k] - miny) * ky);\n                        C.symbols.push(chart.symbols[j][k]);\n                    }\n                }\n            }\n            f && f.call(C);\n        }\n        !f && (columns = cvrs);\n    }\n    function createDots(f) {\n        var cvrs = f || that.set(),\n            C;\n        for (var i = 0, ii = valuesy.length; i < ii; i++) {\n            for (var j = 0, jj = valuesy[i].length; j < jj; j++) {\n                var X = x + gutter + ((valuesx[i] || valuesx[0])[j] - minx) * kx,\n                    nearX = x + gutter + ((valuesx[i] || valuesx[0])[j ? j - 1 : 1] - minx) * kx,\n                    Y = y + height - gutter - (valuesy[i][j] - miny) * ky;\n                f ? (C = {}) : cvrs.push(C = that.circle(X, Y, Math.abs(nearX - X) / 2).attr({stroke: \"none\", fill: \"#000\", opacity: 0}));\n                C.x = X;\n                C.y = Y;\n                C.value = valuesy[i][j];\n                C.line = chart.lines[i];\n                C.shade = chart.shades[i];\n                C.symbol = chart.symbols[i][j];\n                C.symbols = chart.symbols[i];\n                C.axis = (valuesx[i] || valuesx[0])[j];\n                f && f.call(C);\n            }\n        }\n        !f && (dots = cvrs);\n    }\n\n    var axis = this.set();\n    if (opts.axis) {\n        var ax = (opts.axis + \"\").split(/[,\\s]+/);\n        +ax[0] && axis.push(this.g.axis(x + gutter, y + gutter, width - 2 * gutter, minx, maxx, opts.axisxstep || Math.floor((width - 2 * gutter) / 20), 2, opts.axisxlabels || null, opts.axisxtype || \"t\"));\n        +ax[1] && axis.push(this.g.axis(x + width - gutter, y + height - gutter, height - 2 * gutter, miny, maxy, opts.axisystep || Math.floor((height - 2 * gutter) / 20), 3, opts.axisylabels || null, opts.axisytype || \"t\"));\n        +ax[2] && axis.push(this.g.axis(x + gutter, y + height - gutter, width - 2 * gutter, minx, maxx, opts.axisxstep || Math.floor((width - 2 * gutter) / 20), 0, opts.axisxlabels || null, opts.axisxtype || \"t\"));\n        +ax[3] && axis.push(this.g.axis(x + gutter, y + height - gutter, height - 2 * gutter, miny, maxy, opts.axisystep || Math.floor((height - 2 * gutter) / 20), 1, opts.axisylabels || null, opts.axisytype || \"t\"));\n    }\n\n    chart.push(lines, shades, symbols, axis, columns, dots);\n    chart.lines = lines;\n    chart.shades = shades;\n    chart.symbols = symbols;\n    chart.axis = axis;\n    chart.hoverColumn = function (fin, fout) {\n        !columns && createColumns();\n        columns.mouseover(fin).mouseout(fout);\n        return this;\n    };\n    chart.clickColumn = function (f) {\n        !columns && createColumns();\n        columns.click(f);\n        return this;\n    };\n    chart.hrefColumn = function (cols) {\n        var hrefs = that.raphael.is(arguments[0], \"array\") ? arguments[0] : arguments;\n        if (!(arguments.length - 1) && typeof cols == \"object\") {\n            for (var x in cols) {\n                for (var i = 0, ii = columns.length; i < ii; i++) if (columns[i].axis == x) {\n                    columns[i].attr(\"href\", cols[x]);\n                }\n            }\n        }\n        !columns && createColumns();\n        for (i = 0, ii = hrefs.length; i < ii; i++) {\n            columns[i] && columns[i].attr(\"href\", hrefs[i]);\n        }\n        return this;\n    };\n    chart.hover = function (fin, fout) {\n        !dots && createDots();\n        dots.mouseover(fin).mouseout(fout);\n        return this;\n    };\n    chart.click = function (f) {\n        !dots && createDots();\n        dots.click(f);\n        return this;\n    };\n    chart.each = function (f) {\n        createDots(f);\n        return this;\n    };\n    chart.eachColumn = function (f) {\n        createColumns(f);\n        return this;\n    };\n    return chart;\n};\n/*!\n * g.Raphael 0.4.1 - Charting library, based on Raphaël\n *\n * Copyright (c) 2009 Dmitry Baranovskiy (http://g.raphaeljs.com)\n * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.\n */\nRaphael.fn.g.piechart = function (cx, cy, r, values, opts) {\n    opts = opts || {};\n    var paper = this,\n        sectors = [],\n        covers = this.set(),\n        chart = this.set(),\n        series = this.set(),\n        order = [],\n        len = values.length,\n        angle = 0,\n        total = 0,\n        others = 0,\n        cut = 9,\n        defcut = true;\n\n    var sum = 0;\n    for (var i = 0; i < len; i++)\n        sum += values[i];\n    var single = false;\n    var single_index = -1;\n    for (var i = 0; i < len; i++)\n        if (sum == values[i]) {\n            single = true;\n            single_index = i;\n            break;\n        }\n    if (len == 1 || single == true) {\n        for(var i = 0; i < len; i++) {\n            var radius = 0.1;\n            if (i == single_index) {\n                radius = r;\n            }\n            series.push(this.circle(cx, cy, radius).attr({fill: opts.colors && opts.colors[i] || this.g.colors[i], stroke: opts.stroke || \"#fff\", \"stroke-width\": opts.strokewidth == null ? 1 : opts.strokewidth}));\n            covers.push(this.circle(cx, cy, radius).attr({href: opts.href ? opts.href[i] : null}).attr(this.g.shim));\n            values[i] = {value: values[i], order: i, valueOf: function () { return this.value; }};\n            series[i].middle = {x: cx, y: cy};\n            series[i].mangle = 180;\n        }\n        total = values[single_index];\n    } else {\n        function sector(cx, cy, r, startAngle, endAngle, fill) {\n            var rad = Math.PI / 180,\n                x1 = cx + r * Math.cos(-startAngle * rad),\n                x2 = cx + r * Math.cos(-endAngle * rad),\n                xm = cx + r / 2 * Math.cos(-(startAngle + (endAngle - startAngle) / 2) * rad),\n                y1 = cy + r * Math.sin(-startAngle * rad),\n                y2 = cy + r * Math.sin(-endAngle * rad),\n                ym = cy + r / 2 * Math.sin(-(startAngle + (endAngle - startAngle) / 2) * rad),\n                res = [\"M\", cx, cy, \"L\", x1, y1, \"A\", r, r, 0, +(Math.abs(endAngle - startAngle) > 180), 1, x2, y2, \"z\"];\n            res.middle = {x: xm, y: ym};\n            return res;\n        }\n        for (var i = 0; i < len; i++) {\n            total += values[i];\n            values[i] = {value: values[i], order: i, valueOf: function () { return this.value; }};\n        }\n        values.sort(function (a, b) {\n            return b.value - a.value;\n        });\n        for (i = 0; i < len; i++) {\n            if (defcut && values[i] * 360 / total <= 1.5) {\n                cut = i;\n                defcut = false;\n            }\n            if (i > cut) {\n                defcut = false;\n                values[cut].value += values[i];\n                values[cut].others = true;\n                others = values[cut].value;\n            }\n        }\n        len = Math.min(cut + 1, values.length);\n        others && values.splice(len) && (values[cut].others = true);\n        for (i = 0; i < len; i++) {\n            var valueOrder = values[i].order;\n            var mangle = angle - 360 * values[i] / total / 2;\n            if (!i) {\n                angle = 90 - mangle;\n                mangle = angle - 360 * values[i] / total / 2;\n            }\n            if (opts.init) {\n                var ipath = sector(cx, cy, 1, angle, angle - 360 * values[i] / total).join(\",\");\n            }\n            var path = sector(cx, cy, r, angle, angle -= 360 * values[i] / total);\n            var p = this.path(opts.init ? ipath : path).attr({fill: opts.colors && opts.colors[valueOrder] || this.g.colors[valueOrder] || \"#666\", stroke: opts.stroke || \"#fff\", \"stroke-width\": (opts.strokewidth == null ? 1 : opts.strokewidth), \"stroke-linejoin\": \"round\"});\n            p.value = values[i];\n            p.middle = path.middle;\n            p.mangle = mangle;\n            sectors.push(p);\n            series.push(p);\n            opts.init && p.animate({path: path.join(\",\")}, (+opts.init - 1) || 1000, \">\");\n        }\n        for (i = 0; i < len; i++) {\n            p = paper.path(sectors[i].attr(\"path\")).attr(this.g.shim);\n            var valueOrder = values[i].order;\n            opts.href && opts.href[valueOrder] && p.attr({href: opts.href[valueOrder]});\n            //p.attr = function () {}; // this breaks translate!\n            covers.push(p);\n        }\n    }\n\n    chart.hover = function (fin, fout) {\n        fout = fout || function () {};\n        var that = this;\n        for (var i = 0; i < len; i++) {\n            (function (sector, cover, j) {\n                var o = {\n                    sector: sector,\n                    cover: cover,\n                    cx: cx,\n                    cy: cy,\n                    mx: sector.middle.x,\n                    my: sector.middle.y,\n                    mangle: sector.mangle,\n                    r: r,\n                    value: values[j],\n                    total: total,\n                    label: that.labels && that.labels[j]\n                };\n                cover.mouseover(function () {\n                    fin.call(o);\n                }).mouseout(function () {\n                    fout.call(o);\n                });\n            })(series[i], covers[i], i);\n        }\n        return this;\n    };\n    // x: where label could be put\n    // y: where label could be put\n    // value: value to show\n    // total: total number to count %\n    chart.each = function (f) {\n        var that = this;\n        for (var i = 0; i < len; i++) {\n            (function (sector, cover, j) {\n                var o = {\n                    sector: sector,\n                    cover: cover,\n                    cx: cx,\n                    cy: cy,\n                    x: sector.middle.x,\n                    y: sector.middle.y,\n                    mangle: sector.mangle,\n                    r: r,\n                    value: values[j],\n                    total: total,\n                    label: that.labels && that.labels[j]\n                };\n                f.call(o);\n            })(series[i], covers[i], i);\n        }\n        return this;\n    };\n    chart.click = function (f) {\n        var that = this;\n        for (var i = 0; i < len; i++) {\n            (function (sector, cover, j) {\n                var o = {\n                    sector: sector,\n                    cover: cover,\n                    cx: cx,\n                    cy: cy,\n                    mx: sector.middle.x,\n                    my: sector.middle.y,\n                    mangle: sector.mangle,\n                    r: r,\n                    value: values[j],\n                    total: total,\n                    label: that.labels && that.labels[j]\n                };\n                cover.click(function () { f.call(o); });\n            })(series[i], covers[i], i);\n        }\n        return this;\n    };\n    chart.inject = function (element) {\n        element.insertBefore(covers[0]);\n    };\n    var legend = function (labels, otherslabel, mark, dir) {\n        var x = cx + r + r / 5,\n            y = cy,\n            h = y + 10;\n        labels = labels || [];\n        dir = (dir && dir.toLowerCase && dir.toLowerCase()) || \"east\";\n        mark = paper.g.markers[mark && mark.toLowerCase()] || \"disc\";\n        chart.labels = paper.set();\n        for (var i = 0; i < len; i++) {\n            var clr = series[i].attr(\"fill\"),\n                j = values[i].order,\n                txt;\n            values[i].others && (labels[j] = otherslabel || \"Others\");\n            labels[j] = paper.g.labelise(labels[j], values[i], total);\n            chart.labels.push(paper.set());\n            chart.labels[i].push(paper.g[mark](x + 5, h, 5).attr({fill: clr, stroke: \"none\"}));\n            chart.labels[i].push(txt = paper.text(x + 20, h, labels[j] || values[j]).attr(paper.g.txtattr).attr({fill: opts.legendcolor || \"#000\", \"text-anchor\": \"start\"}));\n            covers[i].label = chart.labels[i];\n            h += txt.getBBox().height * 1.2;\n        }\n        var bb = chart.labels.getBBox(),\n            tr = {\n                east: [0, -bb.height / 2],\n                west: [-bb.width - 2 * r - 20, -bb.height / 2],\n                north: [-r - bb.width / 2, -r - bb.height - 10],\n                south: [-r - bb.width / 2, r + 10]\n            }[dir];\n        chart.labels.translate.apply(chart.labels, tr);\n        chart.push(chart.labels);\n    };\n    if (opts.legend) {\n        legend(opts.legend, opts.legendothers, opts.legendmark, opts.legendpos);\n    }\n    chart.push(series, covers);\n    chart.series = series;\n    chart.covers = covers;\n    \n    var w = paper.width,\n        h = paper.height,\n        bb = chart.getBBox(),\n        tr = [(w - bb.width)/2 - bb.x, (h - bb.height)/2 - bb.y];\n    cx += tr[0];\n    cy += tr[1];\n    chart.translate.apply(chart, tr);\n    return chart;\n};\n\n/*!\n * date-range-parser.js\n * Contributed to the Apache Software Foundation by:\n *    Ben Birch - Aconex\n * fork me at https://github.com/mobz/date-range-parser\n\nLicensed to the Apache Software Foundation (ASF) under one\nor more contributor license agreements.  See the NOTICE file\ndistributed with this work for additional information\nregarding copyright ownership.  The ASF licenses this file\nto you under the Apache License, Version 2.0 (the\n\"License\"); you may not use this file except in compliance\nwith the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing,\nsoftware distributed under the License is distributed on an\n\"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\nKIND, either express or implied.  See the License for the\nspecific language governing permissions and limitations\nunder the License.\n\n*/\n\n(function() {\n\n\tvar drp = window.dateRangeParser = {};\n\n\tdrp.defaultRange = 1000 * 60 * 60 * 24;\n\n\tdrp.now = null; // set a different value for now than the time at function invocation\n\n\tdrp.parse = function(v) {\n\t\ttry {\n\t\t\tvar r = drp._parse(v);\n\t\t\tr.end && r.end--; // remove 1 millisecond from the final end range\n\t\t} catch(e) {\n\t\t\tr = null;\n\t\t}\n\t\treturn r;\n\t};\n\n\tdrp.print = function(t, p) {\n\t\tvar format = [\"\", \"-\", \"-\", \" \", \":\", \":\", \".\"];\n\t\tvar da = makeArray(t);\n\t\tvar str = \"\";\n\t\tfor(var i = 0; i <= p; i++) {\n\t\t\tstr += format[i] + (da[i] < 10 ? \"0\" : \"\") + da[i];\n\t\t}\n\t\treturn str;\n\t};\n\n\t(function() {\n\t\tdrp._relTokens = {};\n\n\t\tvar values = {\n\t\t\t\"yr\"  : 365*24*60*60*1000,\n\t\t\t\"mon\" : 31*24*60*60*1000,\n\t\t\t\"day\" : 24*60*60*1000,\n\t\t\t\"hr\"  : 60*60*1000,\n\t\t\t\"min\" : 60*1000,\n\t\t\t\"sec\" : 1000\n\t\t};\n\n\t\tvar alias_lu = {\n\t\t\t\"yr\" : \"y,yr,yrs,year,years\",\n\t\t\t\"mon\" : \"mo,mon,mos,mons,month,months\",\n\t\t\t\"day\" : \"d,dy,dys,day,days\",\n\t\t\t\"hr\" : \"h,hr,hrs,hour,hours\",\n\t\t\t\"min\" : \"m,min,mins,minute,minutes\",\n\t\t\t\"sec\" : \"s,sec,secs,second,seconds\"\n\t\t};\n\n\t\tfor(var key in alias_lu) {\n\t\t\tif(alias_lu.hasOwnProperty(key)) {\n\t\t\t\tvar aliases = alias_lu[key].split(\",\");\n\t\t\t\tfor(var i = 0; i < aliases.length; i++) {\n\t\t\t\t\tdrp._relTokens[aliases[i]] = values[key];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t})();\n\n\tfunction makeArray(d) {\n\t\tvar da = new Date(d);\n\t\treturn [ da.getUTCFullYear(), da.getUTCMonth()+1, da.getUTCDate(), da.getUTCHours(), da.getUTCMinutes(), da.getUTCSeconds(), da.getUTCMilliseconds() ];\n\t}\n\n\tfunction fromArray(a) {\n\t\tvar d = [].concat(a); d[1]--;\n\t\treturn Date.UTC.apply(null, d);\n\t}\n\n\tdrp._parse = function parse(v) {\n\t\tvar now = this.now || new Date().getTime();\n\n\t\tfunction precArray(d, p, offset) {\n\t\t\tvar tn = makeArray(d);\n\t\t\ttn[p] += offset || 0;\n\t\t\tfor(var i = p+1; i < 7; i++) {\n\t\t\t\ttn[i] = i < 3 ? 1 : 0;\n\t\t\t}\n\t\t\treturn tn;\n\t\t}\n\t\tfunction makePrecRange(dt, p, r) {\n\t\t\tvar ret = { };\n\t\t\tret.start = fromArray(dt);\n\t\t\tdt[p] += r || 1;\n\t\t\tret.end = fromArray(dt);\n\t\t\treturn ret;\n\t\t}\n\t\tfunction procTerm(term) {\n\t\t\tvar m = term.replace(/\\s/g, \"\").toLowerCase().match(/^([a-z ]+)$|^([ 0-9:-]+)$|^(\\d+[a-z]+)$/);\n\t\t\tif(m[1]) {\t// matches ([a-z ]+)\n\t\t\t\tfunction dra(p, o, r) {\n\t\t\t\t\tvar dt = precArray(now, p, o);\n\t\t\t\t\tif(r) {\n\t\t\t\t\t\tdt[2] -= new Date(fromArray(dt)).getUTCDay();\n\t\t\t\t\t}\n\t\t\t\t\treturn makePrecRange(dt, p, r);\n\t\t\t\t}\n\t\t\t\tswitch( m[1]) {\n\t\t\t\t\tcase \"now\" : return { start: now, end: now, now: now };\n\t\t\t\t\tcase \"today\" : return dra( 2, 0 );\n\t\t\t\t\tcase \"thisweek\" : return dra( 2, 0, 7 );\n\t\t\t\t\tcase \"thismonth\" : return dra( 1, 0 );\n\t\t\t\t\tcase \"thisyear\" : return dra( 0, 0 );\n\t\t\t\t\tcase \"yesterday\" : return dra( 2, -1 );\n\t\t\t\t\tcase \"lastweek\" : return dra( 2, -7, 7 );\n\t\t\t\t\tcase \"lastmonth\" : return dra( 1, -1 );\n\t\t\t\t\tcase \"lastyear\" : return dra( 0, -1 );\n\t\t\t\t\tcase \"tomorrow\" : return dra( 2, 1 );\n\t\t\t\t\tcase \"nextweek\" : return dra( 2, 7, 7 );\n\t\t\t\t\tcase \"nextmonth\" : return dra( 1, 1 );\n\t\t\t\t\tcase \"nextyear\" : return dra(0, 1 );\n\t\t\t\t}\n\t\t\t\tthrow \"unknown token \" +  m[1];\n\t\t\t} else if(m[2]) { // matches ([ 0-9:-]+)\n\t\t\t\tdn = makeArray(now);\n\t\t\t\tvar dt = m[2].match(/^(?:(\\d{4})(?:\\-(\\d\\d))?(?:\\-(\\d\\d))?)? ?(?:(\\d{1,2})(?:\\:(\\d\\d)(?:\\:(\\d\\d))?)?)?$/);\n\t\t\t\tdt.shift();\n\t\t\t\tfor(var p = 0, z = false, i = 0; i < 7; i++) {\n\t\t\t\t\tif(dt[i]) {\n\t\t\t\t\t\tdn[i] = parseInt(dt[i], 10);\n\t\t\t\t\t\tp = i;\n\t\t\t\t\t\tz = true;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif(z)\n\t\t\t\t\t\t\tdn[i] = i < 3 ? 1 : 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn makePrecRange(dn, p);\n\t\t\t} else if(m[3]) { // matches (\\d+[a-z]{1,4})\n\t\t\t\tvar dr = m[3].match(/(\\d+)\\s*([a-z]+)/i);\n\t\t\t\tvar n = parseInt(dr[1], 10);\n\t\t\t\treturn { rel: n * drp._relTokens[dr[2]] };\n\t\t\t}\n\t\t\tthrow \"unknown term \" + term;\n\t\t}\n\n\t\tif(!v) {\n\t\t\treturn { start: null, end: null };\n\t\t}\n\t\tvar terms = v.split(/\\s*([^<>]*[^<>-])?\\s*(->|<>|<)?\\s*([^<>]+)?\\s*/);\n\n\t\tvar term1 = terms[1] ? procTerm(terms[1]) : null;\n\t\tvar op = terms[2] || \"\";\n\t\tvar term2 = terms[3] ? procTerm(terms[3]) : null;\n\n\t\tif(op === \"<\" || op === \"->\" ) {\n\t\t\tif(term1 && !term2) {\n\t\t\t\treturn { start: term1.start, end: null };\n\t\t\t} else if(!term1 && term2) {\n\t\t\t\treturn { start: null, end: term2.end };\n\t\t\t} else {\n\t\t\t\tif(term2.rel) {\n\t\t\t\t\treturn { start: term1.start, end: term1.end + term2.rel };\n\t\t\t\t} else if(term1.rel) {\n\t\t\t\t\treturn { start: term2.start - term1.rel, end: term2.end };\n\t\t\t\t} else {\n\t\t\t\t\treturn { start: term1.start, end: term2.end };\n\t\t\t\t}\n\t\t\t}\n\t\t} else if(op === \"<>\") {\n\t\t\tif(!term2) {\n\t\t\t\treturn { start: term1.start - drp.defaultRange, end: term1.end + drp.defaultRange }\n\t\t\t} else {\n\t\t\t\tif(! (\"rel\" in term2)) throw \"second term did not hav a range\";\n\t\t\t\treturn { start: term1.start - term2.rel, end: term1.end + term2.rel };\n\t\t\t}\n\t\t} else {\n\t\t\tif(term1.rel) {\n\t\t\t\treturn { start: now - term1.rel, end: now + term1.rel };\n\t\t\t} else if(term1.now) {\n\t\t\t\treturn { start: term1.now - drp.defaultRange, end: term1.now + drp.defaultRange };\n\t\t\t} else {\n\t\t\t\treturn { start: term1.start, end: term1.end };\n\t\t\t}\n\t\t}\n\t\tthrow \"could not process value \" + v;\n\t};\n})();"
  },
  {
    "path": "elasticsearch-head.sublime-project",
    "content": "{\n\t\"folders\":\n\t[\n\t\t{\n\t\t\t\"path\": \".\",\n\t\t\t\"folder_exclude_patterns\": [ \"node_modules\", \"_site\" ]\n\t\t}\n\t]\n}\n"
  },
  {
    "path": "grunt_fileSets.js",
    "content": "exports.vendorJs = [\n\t'src/vendor/jquery/jquery.js',\n\t'src/vendor/joey/joey.js',\n\t'src/vendor/nohtml/jquery-nohtml.js',\n\t'src/vendor/graphael/g.raphael.standalone.js',\n\t'src/vendor/dateRangeParser/date-range-parser.js'\n];\n\nexports.vendorCss = [\n\t'src/vendor/font-awesome/css/font-awesome.css'\n];\n\nexports.srcJs = [\n\t'src/app/base/boot.js',\n\n\t'src/app/ux/class.js',\n\t'src/app/ux/templates/templates.js',\n\t'src/app/ux/observable.js',\n\t'src/app/ux/singleton.js',\n\t'src/app/ux/dragdrop.js',\n\t'src/app/ux/fieldCollection.js',\n\n\t'src/app/data/model/model.js',\n\t'src/app/data/dataSourceInterface.js',\n\t'src/app/data/resultDataSourceInterface.js',\n\t'src/app/data/metaData.js',\n\t'src/app/data/metaDataFactory.js',\n\t'src/app/data/query.js',\n\t'src/app/data/queryDataSourceInterface.js',\n\t'src/app/data/boolQuery.js',\n\n\t'src/app/services/preferences/preferences.js',\n\t'src/app/services/cluster/cluster.js',\n\t'src/app/services/clusterState/clusterState.js',\n\n\t'src/app/ui/abstractWidget/abstractWidget.js',\n\t'src/app/ui/abstractField/abstractField.js',\n\t'src/app/ui/textField/textField.js',\n\t'src/app/ui/checkField/checkField.js',\n\t'src/app/ui/button/button.js',\n\t'src/app/ui/menuButton/menuButton.js',\n\t'src/app/ui/splitButton/splitButton.js',\n\t'src/app/ui/refreshButton/refreshButton.js',\n\t'src/app/ui/toolbar/toolbar.js',\n\t'src/app/ui/abstractPanel/abstractPanel.js',\n\t'src/app/ui/draggablePanel/draggablePanel.js',\n\t'src/app/ui/infoPanel/infoPanel.js',\n\t'src/app/ui/dialogPanel/dialogPanel.js',\n\t'src/app/ui/menuPanel/menuPanel.js',\n\t'src/app/ui/selectMenuPanel/selectMenuPanel.js',\n\t'src/app/ui/table/table.js',\n\t'src/app/ui/csvTable/csvTable.js',\n\t'src/app/ui/jsonPretty/jsonPretty.js',\n\t'src/app/ui/panelForm/panelForm.js',\n\t'src/app/ui/helpPanel/helpPanel.js',\n\t'src/app/ui/jsonPanel/jsonPanel.js',\n\t'src/app/ui/sidebarSection/sidebarSection.js',\n\t'src/app/ui/resultTable/resultTable.js',\n\t'src/app/ui/queryFilter/queryFilter.js',\n\t'src/app/ui/page/page.js',\n\t'src/app/ui/browser/browser.js',\n\t'src/app/ui/anyRequest/anyRequest.js',\n\t'src/app/ui/nodesView/nodesView.js',\n\t'src/app/ui/clusterOverview/clusterOverview.js',\n\t'src/app/ui/dateHistogram/dateHistogram.js',\n\t'src/app/ui/clusterConnect/clusterConnect.js',\n\t'src/app/ui/structuredQuery/structuredQuery.js',\n\t'src/app/ui/filterBrowser/filterBrowser.js',\n\t'src/app/ui/indexSelector/indexSelector.js',\n\t'src/app/ui/header/header.js',\n\t'src/app/ui/indexOverview/indexOverview.js',\n\n\t'src/app/app.js'\n];\n\nexports.srcCss = [\n\t'src/app/ux/table.css',\n\t'src/app/ui/abstractField/abstractField.css',\n\t'src/app/ui/button/button.css',\n\t'src/app/ui/menuButton/menuButton.css',\n\t'src/app/ui/splitButton/splitButton.css',\n\t'src/app/ui/toolbar/toolbar.css',\n\t'src/app/ui/abstractPanel/abstractPanel.css',\n\t'src/app/ui/infoPanel/infoPanel.css',\n\t'src/app/ui/menuPanel/menuPanel.css',\n\t'src/app/ui/selectMenuPanel/selectMenuPanel.css',\n\t'src/app/ui/table/table.css',\n\t'src/app/ui/jsonPretty/jsonPretty.css',\n\t'src/app/ui/jsonPanel/jsonPanel.css',\n\t'src/app/ui/panelForm/panelForm.css',\n\t'src/app/ui/sidebarSection/sidebarSection.css',\n\t'src/app/ui/queryFilter/queryFilter.css',\n\t'src/app/ui/browser/browser.css',\n\t'src/app/ui/anyRequest/anyRequest.css',\n\t'src/app/ui/nodesView/nodesView.css',\n\t'src/app/ui/clusterOverview/clusterOverview.css',\n\t'src/app/ui/clusterConnect/clusterConnect.css',\n\t'src/app/ui/structuredQuery/structuredQuery.css',\n\t'src/app/ui/filterBrowser/filterBrowser.css',\n\t'src/app/ui/header/header.css',\n\t'src/app/app.css'\n];\n"
  },
  {
    "path": "index.html",
    "content": "<!DOCTYPE html>\n\n<html>\n\t<head>\n\t\t<meta charset=\"UTF-8\">\n\t\t<title>elasticsearch-head</title>\n\t\t<link rel=\"stylesheet\" href=\"_site/base/reset.css\">\n\t\t<link rel=\"stylesheet\" href=\"_site/vendor.css\">\n\t\t<link rel=\"stylesheet\" href=\"_site/app.css\">\n\t\t<script src=\"_site/i18n.js\" data-baseDir=\"_site/lang\" data-langs=\"en,fr,pt,zh,zh-TW,tr,ja\"></script>\n\t\t<script src=\"_site/vendor.js\"></script>\n\t\t<script src=\"_site/app.js\"></script>\n\t\t<script>\n\t\t\twindow.onload = function() {\n\t\t\t\tif(location.href.contains(\"/_plugin/\")) {\n\t\t\t\t\tvar base_uri = location.href.replace(/_plugin\\/.*/, '');\n\t\t\t\t}\n\t\t\t\tvar args = location.search.substring(1).split(\"&\").reduce(function(r, p) {\n\t\t\t\t\tr[decodeURIComponent(p.split(\"=\")[0])] = decodeURIComponent(p.split(\"=\")[1]); return r;\n\t\t\t\t}, {});\n\t\t\t\tnew app.App(\"body\", {\n\t\t\t\t\tid: \"es\",\n\t\t\t\t\tbase_uri: args[\"base_uri\"] || base_uri,\n\t\t\t\t\tauth_user : args[\"auth_user\"] || \"\",\n\t\t\t\t\tauth_password : args[\"auth_password\"],\n\t\t\t\t\tdashboard: args[\"dashboard\"]\n\t\t\t\t});\n\t\t\t};\n\t\t</script>\n\t\t<link rel=\"icon\" href=\"_site/base/favicon.png\" type=\"image/png\">\n\t</head>\n\t<body></body>\n</html>\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"elasticsearch-head\",\n  \"version\": \"0.0.0\",\n  \"description\": \"Front end for an elasticsearch cluster\",\n  \"main\": \"_site/index.html\",\n  \"directories\": {\n    \"test\": \"test\"\n  },\n  \"scripts\": {\n    \"start\": \"grunt server\",\n    \"test\": \"grunt jasmine\",\n    \"proxy\": \"node proxy/index.js\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/mobz/elasticsearch-head.git\"\n  },\n  \"author\": \"\",\n  \"license\": \"Apache2\",\n  \"gitHead\": \"0c2ac0b5723b493e4454baa7398f386ecb829412\",\n  \"readmeFilename\": \"README.textile\",\n  \"devDependencies\": {\n    \"grunt\": \"1.0.1\",\n    \"grunt-contrib-concat\": \"1.0.1\",\n    \"grunt-contrib-watch\": \"1.0.0\",\n    \"grunt-contrib-connect\": \"1.0.2\",\n    \"grunt-contrib-copy\": \"1.0.0\",\n    \"grunt-contrib-clean\": \"1.0.0\",\n    \"grunt-contrib-jasmine\": \"1.0.3\",\n    \"karma\": \"1.3.0\",\n    \"grunt-karma\": \"2.0.0\",\n    \"http-proxy\": \"1.16.x\"\n  }\n}\n"
  },
  {
    "path": "plugin-descriptor.properties",
    "content": "description=head - A web front end for an elastic search cluster\nversion=master\nsite=true\nname=head\n"
  },
  {
    "path": "proxy/clusters/localhost9200.json",
    "content": "{\n\t\"name\": \"localhost:9200\",\n\t\"enabled\": true,\n\t\"recipe\": \"http-proxy\",\n\t\"bind\": 9101,\n\t\"settings\": {\n\t\t\"target\": \"http://localhost:9200\"\n\t}\n}\n"
  },
  {
    "path": "proxy/clusters/xpack.json",
    "content": "{\n\t\"name\": \"xpack-default\",\n\t\"enabled\": false,\n\t\"recipe\": \"http-proxy\",\n\t\"bind\": 9102,\n\t\"settings\": {\n\t\t\"target\": \"http://localhost:9200\",\n\t\t\"username\": \"elastic\",\n\t\t\"password\": \"changeme\"\n\t}\n}\n"
  },
  {
    "path": "proxy/index.js",
    "content": "const http = require(\"http\");\n\nconst CORS_SETTINGS = {\n\torigin: \"http://localhost:9100\",\n\tmethods: \"GET, PUT, POST, DELETE, OPTIONS, HEAD\",\n\theaders: \"Authorization, Content-Type\"\n}\n\n\nconst recipes = {};\nrecipes['http-proxy'] = require(\"./recipes/http_proxy.js\");\n\n\nconst clusters = [];\nclusters.push( require(\"./clusters/localhost9200.json\") );\n\n\nclusters.forEach( cluster => {\n\tif( cluster.enabled ) {\n\t\tconsole.log( `creating proxy ${cluster.name}` );\n\n\t\trecipes[ cluster.recipe ]( cluster.settings )\n\t\t\t.then( function( proxy ) {\n\t\t\t\tconst server = http.createServer();\n\t\t\t\tserver.on('request', (req, res ) => {\n\t\t\t\t\tconsole.log( `${req.method} ${cluster.name} ${req.url}` );\n\n\t\t\t\t\tres.setHeader(\"Access-Control-Allow-Origin\", CORS_SETTINGS.origin );\n\t\t\t\t\tres.setHeader(\"Access-Control-Allow-Methods\", CORS_SETTINGS.methods );\n\t\t\t\t\tres.setHeader(\"Access-Control-Allow-Headers\", CORS_SETTINGS.headers );\n\n\t\t\t\t\tif (req.method === 'OPTIONS') {\n\t\t\t\t\t\tres.writeHead(200);\n\t\t\t\t\t\tres.end();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tproxy.request( req, res );\n\t\t\t\t\t}\n\t\t\t\t} );\n\n\t\t\t\tserver.listen( cluster.bind );\n\t\t\t\tconsole.log( `\\tlocal:  http://localhost:${cluster.bind}` );\n\t\t\t});\n\t}\n});\n\n"
  },
  {
    "path": "proxy/recipes/http_proxy.js",
    "content": "const httpProxy = require(\"http-proxy\");\n\nmodule.exports =  function( settings ) {\n\tconst proxy = httpProxy.createProxy( { secure: false } );\n\n\tproxy.on('proxyReq', function(proxyReq, req, res, options) {\n\t\tif( settings.username ) {\n\t\t\tproxyReq.setHeader( \"Authorization\", \"Basic \" + new Buffer(settings.username + \":\" + settings.password).toString(\"base64\") );\n\t\t}\n\t});\n\n\tfunction request( req, res ) {\n\t\tproxy.web( req, res, { target: settings.target } );\n\t};\n\n\tfunction close() {\n\t\tproxy.close();\n\t}\n\n\tconsole.log( `\\tremote: ${settings.target}` );\n\n\treturn new Promise( function( resolve, reject ) {\n\t\tresolve( {\n\t\t\trequest: request,\n\t\t\tclose: close\n\t\t} );\n\t} );\n\n\n};\n"
  },
  {
    "path": "src/app/app.css",
    "content": ".uiApp-header {\n\tbackground: #eee;\n\tposition: fixed;\n\twidth: 100%;\n\tz-index: 9;\n}\n\n.uiApp-header H1 {\n\tmargin: -2px 0 -4px 0;\n\tfloat: left;\n\tpadding-right: 25px;\n}\n\n.uiApp-headerMenu {\n\tborder-bottom: 1px solid #bbb;\n\tpadding: 0px 3px;\n\theight: 22px;\n}\n\n.uiApp-headerMenu .active {\n\tbackground: white;\n\tborder-bottom-color: white;\n}\n\n.uiApp-headerMenuItem {\n\tborder: 1px solid #bbb;\n\tpadding: 4px 8px 1px ;\n\tmargin: 2px 1px 0;\n\theight: 14px;\n\tcursor: pointer;\n}\n\n.uiApp-body {\n\tpadding: 51px 0px 0px 0px;\n}\n\n.uiApp-headerNewMenuItem {\n\tcolor: blue;\n}\n"
  },
  {
    "path": "src/app/app.js",
    "content": "(function( app, i18n ) {\n\n\tvar ui = app.ns(\"ui\");\n\tvar services = app.ns(\"services\");\n\n\tapp.App = ui.AbstractWidget.extend({\n\t\tdefaults: {\n\t\t\tbase_uri: null\n\t\t},\n\t\tinit: function(parent) {\n\t\t\tthis._super();\n\t\t\tthis.prefs = services.Preferences.instance();\n\t\t\tthis.base_uri = this.config.base_uri || this.prefs.get(\"app-base_uri\") || \"http://localhost:9200\";\n\t\t\tif( this.base_uri.charAt( this.base_uri.length - 1 ) !== \"/\" ) {\n\t\t\t\t// XHR request fails if the URL is not ending with a \"/\"\n\t\t\t\tthis.base_uri += \"/\";\n\t\t\t}\n\t\t\tif( this.config.auth_user ) {\n\t\t\t\tvar credentials = window.btoa( this.config.auth_user + \":\" + this.config.auth_password );\n\t\t\t\t$.ajaxSetup({\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t\"Authorization\": \"Basic \" + credentials\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t\tthis.cluster = new services.Cluster({ base_uri: this.base_uri });\n\t\t\tthis._clusterState = new services.ClusterState({\n\t\t\t\tcluster: this.cluster\n\t\t\t});\n\n\t\t\tthis._header = new ui.Header({ cluster: this.cluster, clusterState: this._clusterState });\n\t\t\tthis.$body = $.joey( this._body_template() );\n\t\t\tthis.el = $.joey(this._main_template());\n\t\t\tthis.attach( parent );\n\t\t\tthis.instances = {};\n\t\t\tthis.el.find(\".uiApp-headerMenuItem:first\").click();\n\t\t\tif( this.config.dashboard ) {\n\t\t\t\tif( this.config.dashboard === \"cluster\" ) {\n\t\t\t\t\tvar page = this.instances[\"ClusterOverview\"];\n\t\t\t\t\tpage._refreshButton.set( 5000 );\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\tnavigateTo: function( type, config, ev ) {\n\t\t\tif( ev.target.classList.contains( \"uiApp-headerNewMenuItem\" ) ) {\n\t\t\t\tthis.showNew( type, config, ev );\n\t\t\t} else {\n\t\t\t\tvar ref = type + \"0\";\n\t\t\t\tif(! this.instances[ ref ]) {\n\t\t\t\t\tthis.createPage( type, 0, config );\n\t\t\t\t}\n\t\t\t\tthis.show( ref, ev );\n\t\t\t}\n\t\t},\n\n\t\tcreatePage: function( type, id, config ) {\n\t\t\tvar page = this.instances[ type + id ] = new ui[ type ]( config );\n\t\t\tthis.$body.append( page );\n\t\t\treturn page;\n\t\t},\n\n\t\tshow: function( ref, ev ) {\n\t\t\t$( ev.target ).closest(\"DIV.uiApp-headerMenuItem\").addClass(\"active\").siblings().removeClass(\"active\");\n\t\t\tfor(var p in this.instances) {\n\t\t\t\tthis.instances[p][ p === ref ? \"show\" : \"hide\" ]();\n\t\t\t}\n\t\t},\n\n\t\tshowNew: function( type, config, jEv ) {\n\t\t\tvar ref, page, $tab,\n\t\t\t\ttype_index = 0;\n\n\t\t\twhile ( ! page ) {\n\t\t\t\tref = type + ( ++type_index );\n\t\t\t\tif (! ( ref in this.instances ) ) {\n\t\t\t\t\tpage = this.createPage( type, type_index, config );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add the tab and its click handlers\n\t\t\t$tab = $.joey({\n\t\t\t\ttag: \"DIV\",\n\t\t\t\tcls: \"uiApp-headerMenuItem pull-left\",\n\t\t\t\ttext: i18n.text(\"Nav.\" + type ) + \" \" + type_index,\n\t\t\t\tonclick: function( ev ) { this.show( ref, ev ); }.bind(this),\n\t\t\t\tchildren: [\n\t\t\t\t\t{ tag: \"A\", text: \" [-]\", onclick: function (ev) {\n\t\t\t\t\t\t$tab.remove();\n\t\t\t\t\t\tpage.remove();\n\t\t\t\t\t\tdelete this.instances[ ref ];\n\t\t\t\t\t}.bind(this) }\n\t\t\t\t]\n\t\t\t});\n\n\t\t\t$('.uiApp-headerMenu').append( $tab );\n\t\t\t$tab.trigger(\"click\");\n\t\t},\n\n\t\t_openAnyRequest_handler: function(ev) { this.navigateTo(\"AnyRequest\", { cluster: this.cluster }, ev ); },\n\t\t_openStructuredQuery_handler: function(ev) { this.navigateTo(\"StructuredQuery\", { cluster: this.cluster }, ev ); },\n\t\t_openBrowser_handler: function(ev) { this.navigateTo(\"Browser\", { cluster: this.cluster }, ev );  },\n\t\t_openClusterOverview_handler: function(ev) { this.navigateTo(\"ClusterOverview\", { cluster: this.cluster, clusterState: this._clusterState }, ev ); },\n\t\t_openIndexOverview_handler: function(ev) { this.navigateTo(\"IndexOverview\", { cluster: this.cluster, clusterState: this._clusterState }, ev ); },\n\n\t\t_body_template: function() { return (\n\t\t\t{ tag: \"DIV\", id: this.id(\"body\"), cls: \"uiApp-body\" }\n\t\t); },\n\n\t\t_main_template: function() {\n\t\t\treturn { tag: \"DIV\", cls: \"uiApp\", children: [\n\t\t\t\t{ tag: \"DIV\", id: this.id(\"header\"), cls: \"uiApp-header\", children: [\n\t\t\t\t\tthis._header,\n\t\t\t\t\t{ tag: \"DIV\", cls: \"uiApp-headerMenu\", children: [\n\t\t\t\t\t\t{ tag: \"DIV\", cls: \"uiApp-headerMenuItem pull-left\", text: i18n.text(\"Nav.Overview\"), onclick: this._openClusterOverview_handler },\n\t\t\t\t\t\t{ tag: \"DIV\", cls: \"uiApp-headerMenuItem pull-left\", text: i18n.text(\"Nav.Indices\"), onclick: this._openIndexOverview_handler },\n\t\t\t\t\t\t{ tag: \"DIV\", cls: \"uiApp-headerMenuItem pull-left\", text: i18n.text(\"Nav.Browser\"), onclick: this._openBrowser_handler },\n\t\t\t\t\t\t{ tag: \"DIV\", cls: \"uiApp-headerMenuItem pull-left\", text: i18n.text(\"Nav.StructuredQuery\"), onclick: this._openStructuredQuery_handler, children: [\n\t\t\t\t\t\t\t{ tag: \"A\", cls: \"uiApp-headerNewMenuItem \", text: ' [+]' }\n\t\t\t\t\t\t] },\n\t\t\t\t\t\t{ tag: \"DIV\", cls: \"uiApp-headerMenuItem pull-left\", text: i18n.text(\"Nav.AnyRequest\"), onclick: this._openAnyRequest_handler, children: [\n\t\t\t\t\t\t\t{ tag: \"A\", cls: \"uiApp-headerNewMenuItem \", text: ' [+]' }\n\t\t\t\t\t\t] },\n\t\t\t\t\t]}\n\t\t\t\t]},\n\t\t\t\tthis.$body\n\t\t\t]};\n\t\t}\n\t\t\n\t});\n\n})( this.app, this.i18n );\n"
  },
  {
    "path": "src/app/base/boot.js",
    "content": "(function() {\n\n\tvar window = this,\n\t\t$ = jQuery;\n\n\tfunction ns( namespace ) {\n\t\treturn (namespace || \"\").split(\".\").reduce( function( space, name ) {\n\t\t\treturn space[ name ] || ( space[ name ] = { ns: ns } );\n\t\t}, this );\n\t}\n\n\tvar app = ns(\"app\");\n\n\tvar acx = ns(\"acx\");\n\n\t/**\n\t * object iterator, returns an array with one element for each property of the object\n\t * @function\n\t */\n\tacx.eachMap = function(obj, fn, thisp) {\n\t\tvar ret = [];\n\t\tfor(var n in obj) {\n\t\t\tret.push(fn.call(thisp, n, obj[n], obj));\n\t\t}\n\t\treturn ret;\n\t};\n\n\t/**\n\t * augments the first argument with the properties of the second and subsequent arguments\n\t * like {@link $.extend} except that existing properties are not overwritten\n\t */\n\tacx.augment = function() {\n\t\tvar args = Array.prototype.slice.call(arguments),\n\t\t\tsrc = (args.length === 1) ? this : args.shift(),\n\t\t\taugf = function(n, v) {\n\t\t\t\tif(! (n in src)) {\n\t\t\t\t\tsrc[n] = v;\n\t\t\t\t}\n\t\t\t};\n\t\tfor(var i = 0; i < args.length; i++) {\n\t\t\t$.each(args[i], augf);\n\t\t}\n\t\treturn src;\n\t};\n\n\t/**\n\t * tests whether the argument is an array\n\t * @function\n\t */\n\tacx.isArray = $.isArray;\n\n\t/**\n\t * tests whether the argument is an object\n\t * @function\n\t */\n\tacx.isObject = function (value) {\n\t\treturn Object.prototype.toString.call(value) == \"[object Object]\";\n\t};\n\n\t/**\n\t * tests whether the argument is a function\n\t * @function\n\t */\n\tacx.isFunction = $.isFunction;\n\n\t/**\n\t * tests whether the argument is a date\n\t * @function\n\t */\n\tacx.isDate = function (value) {\n\t\treturn Object.prototype.toString.call(value) == \"[object Date]\";\n\t};\n\n\t/**\n\t * tests whether the argument is a regexp\n\t * @function\n\t */\n\tacx.isRegExp = function (value) {\n\t\treturn Object.prototype.toString.call(value) == \"[object RegExp]\";\n\t};\n\n\t/**\n\t * tests whether the value is blank or empty\n\t * @function\n\t */\n\tacx.isEmpty = function (value, allowBlank) {\n\t\treturn value === null || value === undefined || ((acx.isArray(value) && !value.length)) || (!allowBlank ? value === '' : false);\n\t};\n\n\t/**\n\t * data type for performing chainable geometry calculations<br>\n\t * can be initialised x,y | {x, y} | {left, top}\n\t */\n\tacx.vector = function(x, y) {\n\t\treturn new acx.vector.prototype.Init(x, y);\n\t};\n\n\tacx.vector.prototype = {\n\t\tInit : function(x, y) {\n\t\t\tx = x || 0;\n\t\t\tthis.y = isFinite(x.y) ? x.y : (isFinite(x.top) ? x.top : (isFinite(y) ? y : 0));\n\t\t\tthis.x = isFinite(x.x) ? x.x : (isFinite(x.left) ? x.left : (isFinite(x) ? x : 0));\n\t\t},\n\t\t\n\t\tadd : function(i, j) {\n\t\t\tvar d = acx.vector(i, j);\n\t\t\treturn new this.Init(this.x + d.x, this.y + d.y);\n\t\t},\n\t\t\n\t\tsub : function(i, j) {\n\t\t\tvar d = acx.vector(i, j);\n\t\t\treturn new this.Init(this.x - d.x, this.y - d.y);\n\t\t},\n\t\t\n\t\taddX : function(i) {\n\t\t\treturn new this.Init(this.x + i, this.y);\n\t\t},\n\t\t\n\t\taddY : function(j) {\n\t\t\treturn new this.Init(this.x, this.y + j);\n\t\t},\n\n\t\tmod : function(fn) { // runs a function against the x and y values\n\t\t\treturn new this.Init({x: fn.call(this, this.x, \"x\"), y: fn.call(this, this.y, \"y\")});\n\t\t},\n\t\t\n\t\t/** returns true if this is within a rectangle formed by the points p and q */\n\t\twithin : function(p, q) {\n\t\t\treturn ( this.x >= ((p.x < q.x) ? p.x : q.x) && this.x <= ((p.x > q.x) ? p.x : q.x) &&\n\t\t\t\t\tthis.y >= ((p.y < q.y) ? p.y : q.y) && this.y <= ((p.y > q.y) ? p.y : q.y) );\n\t\t},\n\t\t\n\t\tasOffset : function() {\n\t\t\treturn { top: this.y, left: this.x };\n\t\t},\n\t\t\n\t\tasSize : function() {\n\t\t\treturn { height: this.y, width: this.x };\n\t\t}\n\t};\n\n\tacx.vector.prototype.Init.prototype = acx.vector.prototype;\n\n\t/**\n\t * short cut functions for working with vectors and jquery.\n\t * Each function returns the equivalent jquery value in a two dimentional vector\n\t */\n\t$.fn.vSize = function() { return acx.vector(this.width(), this.height()); };\n\t$.fn.vOuterSize = function(margin) { return acx.vector(this.outerWidth(margin), this.outerHeight(margin)); };\n\t$.fn.vScroll = function() { return acx.vector(this.scrollLeft(), this.scrollTop()); };\n\t$.fn.vOffset = function() { return acx.vector(this.offset()); };\n\t$.fn.vPosition = function() { return acx.vector(this.position()); };\n\t$.Event.prototype.vMouse = function() { return acx.vector(this.pageX, this.pageY); };\n\n\t/**\n\t * object extensions (ecma5 compatible)\n\t */\n\tacx.augment(Object, {\n\t\tkeys: function(obj) {\n\t\t\tvar ret = [];\n\t\t\tfor(var n in obj) if(Object.prototype.hasOwnProperty.call(obj, n)) ret.push(n);\n\t\t\treturn ret;\n\t\t}\n\t});\n\n\t/**\n\t * Array prototype extensions\n\t */\n\tacx.augment(Array.prototype, {\n\t\t'contains' : function(needle) {\n\t\t\treturn this.indexOf(needle) !== -1;\n\t\t},\n\n\t\t// returns a new array consisting of all the members that are in both arrays\n\t\t'intersection' : function(b) {\n\t\t\tvar ret = [];\n\t\t\tfor(var i = 0; i < this.length; i++) {\n\t\t\t\tif(b.contains(this[i])) {\n\t\t\t\t\tret.push(this[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn ret;\n\t\t},\n\t\t\n\t\t'remove' : function(value) {\n\t\t\tvar i = this.indexOf(value);\n\t\t\tif(i !== -1) {\n\t\t\t\tthis.splice(i, 1);\n\t\t\t}\n\t\t}\n\t});\n\n\t/**\n\t * String prototype extensions\n\t */\n\tacx.augment(String.prototype, {\n\t\t'contains' : function(needle) {\n\t\t\treturn this.indexOf(needle) !== -1;\n\t\t},\n\n\t\t'equalsIgnoreCase' : function(match) {\n\t\t\treturn this.toLowerCase() === match.toLowerCase();\n\t\t},\n\n\t\t'escapeHtml' : function() {\n\t\t\treturn this.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n\t\t},\n\n\t\t'escapeJS' : function() {\n\t\t\tvar meta = {'\"':'\\\\\"', '\\\\':'\\\\\\\\', '/':'\\\\/', '\\b':'\\\\b', '\\f':'\\\\f', '\\n':'\\\\n', '\\r':'\\\\r', '\\t':'\\\\t'},\n\t\t\t\txfrm = function(c) { return meta[c] || \"\\\\u\" + c.charCodeAt(0).toString(16).zeroPad(4); };\n\t\t\treturn this.replace(new RegExp('([\"\\\\\\\\\\x00-\\x1f\\x7f-\\uffff])', 'g'), xfrm);\n\t\t},\n\n\t\t'escapeRegExp' : function() {\n\t\t\tvar ret = \"\", esc = \"\\\\^$*+?.()=|{,}[]-\";\n\t\t\tfor ( var i = 0; i < this.length; i++) {\n\t\t\t\tret += (esc.contains(this.charAt(i)) ? \"\\\\\" : \"\") + this.charAt(i);\n\t\t\t}\n\t\t\treturn ret;\n\t\t},\n\t\t\n\t\t'zeroPad' : function(len) {\n\t\t\treturn (\"0000000000\" + this).substring(this.length - len + 10);\n\t\t}\n\t});\n\n\t$.fn.forEach = Array.prototype.forEach;\n\n\t// joey / jquery integration\n\t$.joey = function( obj ) {\n\t\treturn $( window.joey( obj ) );\n\t};\n\n\twindow.joey.plugins.push( function( obj ) {\n\t\tif( obj instanceof jQuery ) {\n\t\t\treturn obj[0];\n\t\t}\n\t});\n\n})();\n"
  },
  {
    "path": "src/app/base/reset.css",
    "content": "BODY {\n\tfont-family: Verdana, sans-serif;\n\tfont-size: 73%;\n\tpadding: 0;\n\tmargin: 0;\n}\n\nINPUT, SELECT, TEXTAREA {\n\tborder: 1px solid #cecece;\n\tpadding: 1px 3px;\n\tbackground: white;\n}\n\nSELECT {\n\tpadding: 0;\n}\n\n.saf SELECT {\n\tmargin-top: 0;\n\tmargin-bottom: 0;\n}\n\nTEXTAREA, CODE {\n\tfont-family: monospace;\n\tfont-size: 13px;\n}\n\nBUTTON::-moz-focus-inner {\n\tborder: none;\n}\n\n.pull-left {\n\tfloat: left;\n}\n\n.pull-right {\n\tfloat: right;\n}\n\n.loading  {\n\tbackground-image: url(loading.gif);\n\tbackground-repeat: no-repeat;\n\ttext-indent: 20px;\n}\n"
  },
  {
    "path": "src/app/data/boolQuery.js",
    "content": "(function( app ) {\n\n\tvar data = app.ns(\"data\");\n\tvar ux = app.ns(\"ux\");\n\n\tdata.BoolQuery = ux.Observable.extend({\n\t\tdefaults: {\n\t\t\tsize: 50\t\t// size of pages to return\n\t\t},\n\t\tinit: function() {\n\t\t\tthis._super();\n\t\t\tthis.refuid = 0;\n\t\t\tthis.refmap = {};\n\t\t\tthis.search = {\n\t\t\t\tquery: { bool: { must: [], must_not: [], should: [] } },\n\t\t\t\tfrom: 0,\n\t\t\t\tsize: this.config.size,\n\t\t\t\tsort: [],\n\t\t\t\taggs: {}\n\t\t\t};\n\t\t\tthis.defaultClause = this.addClause();\n\t\t},\n\t\tsetSize: function(size) {\n\t\t\tthis.search.size = parseInt( size, 10 );\n\t\t},\n\t\tsetPage: function(page) {\n\t\t\tthis.search.from = this.config.size * (page - 1) + 1;\n\t\t},\n\t\taddClause: function(value, field, op, bool) {\n\t\t\tbool = bool || \"should\";\n\t\t\top = op || \"match_all\";\n\t\t\tfield = field || \"_all\";\n\t\t\tvar clause = this._setClause(value, field, op, bool);\n\t\t\tvar uqid = \"q-\" + this.refuid++;\n\t\t\tthis.refmap[uqid] = { clause: clause, value: value, field: field, op: op, bool: bool };\n\t\t\tif(this.search.query.bool.must.length + this.search.query.bool.should.length > 1) {\n\t\t\t\tthis.removeClause(this.defaultClause);\n\t\t\t}\n\t\t\tthis.fire(\"queryChanged\", this, { uqid: uqid, search: this.search} );\n\t\t\treturn uqid; // returns reference to inner query object to allow fast updating\n\t\t},\n\t\tremoveClause: function(uqid) {\n\t\t\tvar ref = this.refmap[uqid],\n\t\t\t\tbool = this.search.query.bool[ref.bool];\n\t\t\tvar clauseIdx = bool.indexOf(ref.clause);\n\t\t\t// Check that this clause hasn't already been removed\n\t\t\tif (clauseIdx >=0) {\n\t\t\t\tbool.splice(clauseIdx, 1);\n\t\t\t}\n\t\t},\n\t\t_setClause: function(value, field, op, bool) {\n\t\t\tvar clause = {}, query = {};\n\t\t\tif(op === \"match_all\") {\n\t\t\t} else if(op === \"query_string\") {\n\t\t\t\tquery[\"default_field\"] = field.substring(field.indexOf(\".\")+1);\n\t\t\t\tquery[\"query\"] = value;\n\t\t\t} else if(op === \"missing\") {\n\t\t\t\top = \"exists\";\n\t\t\t\tif (bool === \"must_not\") {\n\t\t\t\t\tbool = \"must\"\n\t\t\t\t} else if (bool === \"must\") {\n\t\t\t\t\tbool = \"must_not\"\n\t\t\t\t}\n\t\t\t\tquery[\"field\"] = field.substring(field.indexOf(\".\")+1);\n\t\t\t} else {\n\t\t\t\tquery[field.substring(field.indexOf(\".\")+1)] = value;\n\t\t\t}\n\t\t\tclause[op] = query;\n\t\t\tthis.search.query.bool[bool].push(clause);\n\t\t\treturn clause;\n\t\t},\n\t\tgetData: function() {\n\t\t\treturn JSON.stringify(this.search);\n\t\t}\n\t});\n\n})( this.app );"
  },
  {
    "path": "src/app/data/dataSourceInterface.js",
    "content": "(function( app ) {\n\n\tvar data = app.ns(\"data\");\n\tvar ux = app.ns(\"ux\");\n\n\tdata.DataSourceInterface = ux.Observable.extend({\n\t\t/*\n\t\tproperties\n\t\t\tmeta = { total: 0 },\n\t\t\theaders = [ { name: \"\" } ],\n\t\t\tdata = [ { column: value, column: value } ],\n\t\t\tsort = { column: \"name\", dir: \"desc\" }\n\t\tevents\n\t\t\tdata: function( DataSourceInterface )\n\t\t */\n\t\t_getSummary: function(res) {\n\t\t\tthis.summary = i18n.text(\"TableResults.Summary\", res._shards.successful, res._shards.total, (typeof res.hits.total === 'object') ? res.hits.total.value : res.hits.total, (res.took / 1000).toFixed(3));\n\t\t},\n\t\t_getMeta: function(res) {\n\t\t\tthis.meta = { total: res.hits.total, shards: res._shards, tool: res.took };\n\t\t}\n\t});\n\n})( this.app );"
  },
  {
    "path": "src/app/data/metaData.js",
    "content": "(function( app ) {\n\n\t/*\n\tnotes on elasticsearch terminology used in this project\n\n\tindices[index] contains one or more\n\ttypes[type] contains one or more\n\tdocuments contain one or more\n\tpaths[path]\n\teach path contains one element of data\n\teach path maps to one field\n\n\teg PUT, \"/twitter/tweet/1\"\n\t{\n\t\tuser: \"mobz\",\n\t\tdate: \"2011-01-01\",\n\t\tmessage: \"You know, for browsing elasticsearch\",\n\t\tname: {\n\t\t\tfirst: \"Ben\",\n\t\t\tlast: \"Birch\"\n\t\t}\n\t}\n\n\tcreates\n\t\t1 index: twitter\n\t\t\t\tthis is the collection of index data\n\t\t1 type: tweet\n\t\t\t\tthis is the type of document (kind of like a table in sql)\n\t\t1 document: /twitter/tweet/1\n\t\t\t\tthis is an actual document in the index ( kind of like a row in sql)\n\t\t5 paths: [ [\"user\"], [\"date\"], [\"message\"], [\"name\",\"first\"], [\"name\",\"last\"] ]\n\t\t\t\tsince documents can be heirarchical this maps a path from a document root to a piece of data\n\t\t5 fields: [ \"user\", \"date\", \"message\", \"first\", \"last\" ]\n\t\t\t\tthis is an indexed 'column' of data. fields are not heirarchical\n\n\t\tthe relationship between a path and a field is called a mapping. mappings also contain a wealth of information about how es indexes the field\n\n\tnotes\n\t1) a path is stored as an array, the dpath is  <index> . <type> . path.join(\".\"),\n\t\t\twhich can be considered the canonical reference for a mapping\n\t2) confusingly, es uses the term index for both the collection of indexed data, and the individually indexed fields\n\t\t\tso the term index_name is the same as field_name in this sense.\n\n\t*/\n\n\tvar data = app.ns(\"data\");\n\tvar ux = app.ns(\"ux\");\n\n\tvar coretype_map = {\n\t\t\"string\" : \"string\",\n\t\t\"keyword\" : \"string\",\n\t\t\"text\" : \"string\",\n\t\t\"byte\" : \"number\",\n\t\t\"short\" : \"number\",\n\t\t\"long\" : \"number\",\n\t\t\"integer\" : \"number\",\n\t\t\"float\" : \"number\",\n\t\t\"double\" : \"number\",\n\t\t\"ip\" : \"number\",\n\t\t\"date\" : \"date\",\n\t\t\"boolean\" : \"boolean\",\n\t\t\"binary\" : \"binary\",\n\t\t\"multi_field\" : \"multi_field\"\n\t};\n\n\tvar default_property_map = {\n\t\t\"string\" : { \"store\" : \"no\", \"index\" : \"analysed\" },\n\t\t\"number\" : { \"store\" : \"no\", \"precision_steps\" : 4 },\n\t\t\"date\" : { \"store\" : \"no\", \"format\" : \"dateOptionalTime\", \"index\": \"yes\", \"precision_steps\": 4 },\n\t\t\"boolean\" : { \"store\" : \"no\", \"index\": \"yes\" },\n\t\t\"binary\" : { },\n\t\t\"multi_field\" : { }\n\t};\n\n\t// parses metatdata from a cluster, into a bunch of useful data structures\n\tdata.MetaData = ux.Observable.extend({\n\t\tdefaults: {\n\t\t\tstate: null // (required) response from a /_cluster/state request\n\t\t},\n\t\tinit: function() {\n\t\t\tthis._super();\n\t\t\tthis.refresh(this.config.state);\n\t\t},\n\t\tgetIndices: function(alias) {\n\t\t\treturn alias ? this.aliases[alias] : this.indicesList;\n\t\t},\n\t\t// returns an array of strings containing all types that are in all of the indices passed in, or all types\n\t\tgetTypes: function(indices) {\n\t\t\tvar indices = indices || [], types = [];\n\t\t\tthis.typesList.forEach(function(type) {\n\t\t\t\tfor(var i = 0; i < indices.length; i++) {\n\t\t\t\t\tif(! this.indices[indices[i]].types.contains(type))\n\t\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\ttypes.push(type);\n\t\t\t}, this);\n\t\t\treturn types;\n\t\t},\n\t\trefresh: function(state) {\n\t\t\t// currently metadata expects all like named fields to have the same type, even when from different types and indices\n\t\t\tvar aliases = this.aliases = {};\n\t\t\tvar indices = this.indices = {};\n\t\t\tvar types = this.types = {};\n\t\t\tvar fields = this.fields = {};\n\t\t\tvar paths = this.paths = {};\n\n\t\t\tfunction createField( mapping, index, type, path, name ) {\n\t\t\t\tvar dpath = [ index, type ].concat( path ).join( \".\" );\n\t\t\t\tvar field_name = mapping.index_name || path.join( \".\" );\n\t\t\t\tvar field = paths[ dpath ] = fields[ field_name ] || $.extend({\n\t\t\t\t\tfield_name : field_name,\n\t\t\t\t\tcore_type : coretype_map[ mapping.type ],\n\t\t\t\t\tdpaths : []\n\t\t\t\t}, default_property_map[ coretype_map[ mapping.type ] ], mapping );\n\n\t\t\t\tif (field.type === \"multi_field\" && typeof field.fields !== \"undefined\") {\n\t\t\t\t\tfor (var subField in field.fields) {\n\t\t\t\t\t\tfield.fields[ subField ] = createField( field.fields[ subField ], index, type, path.concat( subField ), name + \".\" + subField );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (fields.dpaths) {\n\t\t\t\t\tfield.dpaths.push(dpath);\n\t\t\t\t}\n\t\t\t\treturn field;\n\t\t\t}\n\t\t\tfunction getFields(properties, type, index, listeners) {\n\t\t\t\t(function procPath(prop, path) {\n\t\t\t\t\tfor (var n in prop) {\n\t\t\t\t\t\tif (\"properties\" in prop[n]) {\n\t\t\t\t\t\t\tprocPath( prop[ n ].properties, path.concat( n ) );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tvar field = createField(prop[n], index, type, path.concat(n), n);\t\t\t\t\t\t\t\n\t\t\t\t\t\t\tlisteners.forEach( function( listener ) {\n\t\t\t\t\t\t\t\tlistener[ field.field_name ] = field;\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})(properties, []);\n\t\t\t}\n\t\t\tfor (var index in state.metadata.indices) {\n\t\t\t\tindices[index] = {\n\t\t\t\t\ttypes : [], fields : {}, paths : {}, parents : {}\n\t\t\t\t};\n\t\t\t\tindices[index].aliases = state.metadata.indices[index].aliases;\n\t\t\t\tindices[index].aliases.forEach(function(alias) {\n\t\t\t\t\t(aliases[alias] || (aliases[alias] = [])).push(index);\n\t\t\t\t});\n\t\t\t\tvar mapping = state.metadata.indices[index].mappings;\n\t\t\t\tfor (var type in mapping) {\n\t\t\t\t\tindices[index].types.push(type);\n\t\t\t\t\tif ( type in types) {\n\t\t\t\t\t\ttypes[type].indices.push(index);\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttypes[type] = {\n\t\t\t\t\t\t\tindices : [index], fields : {}\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\tgetFields(mapping[type].properties, type, index, [fields, types[type].fields, indices[index].fields]);\n\t\t\t\t\tif ( typeof mapping[type]._parent !== \"undefined\") {\n\t\t\t\t\t\tindices[index].parents[type] = mapping[type]._parent.type;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.aliasesList = Object.keys(aliases);\n\t\t\tthis.indicesList = Object.keys(indices);\n\t\t\tthis.typesList = Object.keys(types);\n\t\t\tthis.fieldsList = Object.keys(fields);\n\t\t}\n\t});\n\n})( this.app );\t\n"
  },
  {
    "path": "src/app/data/metaDataFactory.js",
    "content": "(function( app ) {\n\n\tvar data = app.ns(\"data\");\n\tvar ux = app.ns(\"ux\");\n\n\tdata.MetaDataFactory = ux.Observable.extend({\n\t\tdefaults: {\n\t\t\tcluster: null // (required) an app.services.Cluster\n\t\t},\n\t\tinit: function() {\n\t\t\tthis._super();\n\t\t\tvar _cluster = this.config.cluster;\n\t\t\tthis.config.cluster.get(\"_cluster/state\", function(data) {\n\t\t\t\tthis.metaData = new app.data.MetaData({state: data});\n\t\t\t\tthis.fire(\"ready\", this.metaData,  { originalData: data, \"k\": 1 }); // TODO originalData needed for legacy ui.FilterBrowser\n\t\t\t}.bind(this), function() {\n\t\t\t\t\n\t\t\t\tvar _this = this;\n\t\t\t\t\n\t\t\t\t_cluster.get(\"_all\", function( data ) {\n\t\t\t\t\tclusterState = {routing_table:{indices:{}}, metadata:{indices:{}}};\n\t\t\t\t\t\n\t\t\t\t\tfor(var k in data) {\n\t\t\t\t\t\tclusterState[\"routing_table\"][\"indices\"][k] = {\"shards\":{\"1\":[{\n                            \"state\":\"UNASSIGNED\",\n                            \"primary\":false,\n                            \"node\":\"unknown\",\n                            \"relocating_node\":null,\n                            \"shard\":'?',\n                            \"index\":k\n                        }]}};\n\t\t\t\t\t\t\n\n\t\t\t\t\t\tclusterState[\"metadata\"][\"indices\"][k] = {};\n\t\t\t\t\t\tclusterState[\"metadata\"][\"indices\"][k][\"mappings\"] = data[k][\"mappings\"];\n\t\t\t\t\t\tclusterState[\"metadata\"][\"indices\"][k][\"aliases\"] = $.makeArray(Object.keys(data[k][\"aliases\"]));\n\t\t\t\t\t\tclusterState[\"metadata\"][\"indices\"][k][\"settings\"] = data[k][\"settings\"];\n\t\t\t\t\t\tclusterState[\"metadata\"][\"indices\"][k][\"fields\"] = {};\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\t_this.metaData = new app.data.MetaData({state: clusterState});\n\t\t\t\t\t_this.fire(\"ready\", _this.metaData, {originalData: clusterState});\n\t\t\t\t});\t\t\t\t\n\n\t\t\t}.bind(this));\n\t\t}\n\t});\n\n})( this.app );\n"
  },
  {
    "path": "src/app/data/model/model.js",
    "content": "(function( $, app ) {\n\n\tvar data = app.ns(\"data\");\n\tvar ux = app.ns(\"ux\");\n\n\tdata.Model = ux.Observable.extend({\n\t\tdefaults: {\n\t\t\tdata: null\n\t\t},\n\t\tinit: function() {\n\t\t\tthis.set( this.config.data );\n\t\t},\n\t\tset: function( key, value ) {\n\t\t\tif( arguments.length === 1 ) {\n\t\t\t\tthis._data = $.extend( {}, key );\n\t\t\t} else {\n\t\t\t\tkey.split(\".\").reduce(function( ptr, prop, i, props) {\n\t\t\t\t\tif(i === (props.length - 1) ) {\n\t\t\t\t\t\tptr[prop] = value;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif( !(prop in ptr) ) {\n\t\t\t\t\t\t\tptr[ prop ] = {};\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn ptr[prop];\n\t\t\t\t\t}\n\t\t\t\t}, this._data );\n\t\t\t}\n\t\t},\n\t\tget: function( key ) {\n\t\t\treturn key.split(\".\").reduce( function( ptr, prop ) {\n\t\t\t\treturn ( ptr && ( prop in ptr ) ) ? ptr[ prop ] : undefined;\n\t\t\t}, this._data );\n\t\t},\n\t});\n})( this.jQuery, this.app );\n"
  },
  {
    "path": "src/app/data/model/modelSpec.js",
    "content": "describe(\"app.data.Model\", function() {\n\n\tvar Model = window.app.data.Model;\n\n\tit(\"test setting model does a shallow copy\", function() {\n\t\tvar test = {};\n\t\tvar array = [ 1, 2, 3 ];\n\t\tvar m = new Model({\n\t\t\tdata: {\n\t\t\t\t\"foo\": \"bar\",\n\t\t\t\t\"test\": test,\n\t\t\t\t\"array\": array\n\t\t\t}\n\t\t});\n\t\texpect( m.get(\"foo\") ).toBe(\"bar\");\n\t\texpect( m.get(\"array\").length ).toBe(  3  );\n\t\texpect( m.get(\"array\")[1] ).toBe( 2 );\n\t\texpect( m.get(\"array\") ).toBe( array );\n\t\texpect( m.get(\"test\") ).toBe( test );\n\t});\n\n\tit(\"should replace model with shallow copy when put with no path\", function() {\n\t\tvar m = new Model({ foo: \"bar\" });\n\t\tm.set({ bar: \"blat\" });\n\t\texpect( m.get(\"foo\")).toBe( undefined );\n\t\texpect( m.get(\"bar\")).toBe(\"blat\");\n\t});\n\n\tit(\"test getting values from deep in a model\", function() {\n\t\tvar m = new Model({\n\t\t\tdata: {\n\t\t\t\t\"foo\": {\n\t\t\t\t\t\"bar\": {\n\t\t\t\t\t\t\"baz\": {\n\t\t\t\t\t\t\t\"quix\": \"abcdefg\"\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\texpect( m.get(\"foo.bar.baz.quix\") ).toBe( \"abcdefg\" );\n\t});\n\n\tit(\"test setting non-existant values creates new values\", function() {\n\t\tvar m = new Model({\n\t\t\tdata: {\n\t\t\t\t\"foo\": {\n\t\t\t\t\t\"bar\": \"abc\"\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\tm.set(\"foo.bar\", \"123\" );\n\t\tm.set(\"foo.baz\", \"456\" );\n\t\texpect( m.get(\"foo.bar\") ).toBe( \"123\" );\n\t\texpect( m.get(\"foo.baz\") ).toBe( \"456\" );\n\t});\n\n\tit(\"test setting values deep in a model\", function() {\n\t\tvar m = new Model({\n\t\t\tdata: {\n\t\t\t\t\"foo\": {\n\t\t\t\t\t\"bar\": \"abc\"\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\tm.set(\"foo.bar\", \"123\" );\n\t\tm.set(\"foo.baz\", \"456\" );\n\t\tm.set(\"foo.something.else.is.here\", \"xyz\" );\n\t\texpect( m.get(\"foo.something.else.is\").here ).toBe( \"xyz\" );\n\t\texpect( m.get(\"foo.something.else.is.here\") ).toBe( \"xyz\" );\n\t});\n\n});\n"
  },
  {
    "path": "src/app/data/query.js",
    "content": "(function( app ) {\n\n\tvar data = app.ns(\"data\");\n\tvar ux = app.ns(\"ux\");\n\n\tdata.Query = ux.Observable.extend({\n\t\tdefaults: {\n\t\t\tcluster: null,  // (required) instanceof app.services.Cluster\n\t\t\tsize: 50        // size of pages to return\n\t\t},\n\t\tinit: function() {\n\t\t\tthis._super();\n\t\t\tthis.cluster = this.config.cluster;\n\t\t\tthis.refuid = 0;\n\t\t\tthis.refmap = {};\n\t\t\tthis.indices = [];\n\t\t\tthis.types = [];\n\t\t\tthis.search = {\n\t\t\t\tquery: { bool: { must: [], must_not: [], should: [] } },\n\t\t\t\tfrom: 0,\n\t\t\t\tsize: this.config.size,\n\t\t\t\tsort: [],\n\t\t\t\taggs: {},\n\t\t\t\tversion: true\n\t\t\t};\n\t\t\tthis.defaultClause = this.addClause();\n\t\t\tthis.history = [ this.getState() ];\n\t\t},\n\t\tclone: function() {\n\t\t\tvar q = new data.Query({ cluster: this.cluster });\n\t\t\tq.restoreState(this.getState());\n\t\t\tfor(var uqid in q.refmap) {\n\t\t\t\tq.removeClause(uqid);\n\t\t\t}\n\t\t\treturn q;\n\t\t},\n\t\tgetState: function() {\n\t\t\treturn $.extend(true, {}, { search: this.search, indices: this.indices, types: this.types });\n\t\t},\n\t\trestoreState: function(state) {\n\t\t\tstate = $.extend(true, {}, state || this.history[this.history.length - 1]);\n\t\t\tthis.indices = state.indices;\n\t\t\tthis.types = state.types;\n\t\t\tthis.search = state.search;\n\t\t},\n\t\tgetData: function() {\n\t\t\treturn JSON.stringify(this.search);\n\t\t},\n\t\tquery: function() {\n\t\t\tvar state = this.getState();\n\t\t\tthis.cluster.post(\n\t\t\t\t\t(this.indices.join(\",\") || \"_all\") + \"/\" + ( this.types.length ? this.types.join(\",\") + \"/\" : \"\") + \"_search\",\n\t\t\t\t\tthis.getData(),\n\t\t\t\t\tfunction(results) {\n\t\t\t\t\t\tif(results === null) {\n\t\t\t\t\t\t\talert(i18n.text(\"Query.FailAndUndo\"));\n\t\t\t\t\t\t\tthis.restoreState();\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.history.push(state);\n\n\t\t\t\t\t\tthis.fire(\"results\", this, results);\n\t\t\t\t\t}.bind(this));\n\t\t},\n\t\tloadParents: function(res,metadata){\n\t\t\t//create data for mget\n\t\t\tvar data = { docs :[] };\n\t\t\tvar indexToTypeToParentIds = {};\n\t\t\tres.hits.hits.forEach(function(hit) {\n\t\t\tif (typeof hit.fields != \"undefined\"){\n\t\t\t\tif (typeof hit.fields._parent != \"undefined\"){\n\t\t\t\t\tvar parentType = metadata.indices[hit._index].parents[hit._type];\n\t\t\t\t\tif (typeof indexToTypeToParentIds[hit._index] == \"undefined\"){\n\t\t\t\t\t\tindexToTypeToParentIds[hit._index] = new Object();\n\t\t\t\t\t}\n\t\t\t\t\tif (typeof indexToTypeToParentIds[hit._index][hit._type] == \"undefined\"){\n\t\t\t\t\t\tindexToTypeToParentIds[hit._index][hit._type] = new Object();\n\t\t\t\t\t}\n\t\t\t\t\tif (typeof indexToTypeToParentIds[hit._index][hit._type][hit.fields._parent] == \"undefined\"){\n\t\t\t\t\t\tindexToTypeToParentIds[hit._index][hit._type][hit.fields._parent] = null;\n\t\t\t\t\t\tdata.docs.push({ _index:hit._index, _type:parentType, _id:hit.fields._parent});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\t//load parents\n\t\tvar state = this.getState();\n\t\t\tthis.cluster.post(\"_mget\",JSON.stringify(data),\n\t\t\t\tfunction(results) {\n\t\t\t\t\tif(results === null) {\n\t\t\t\t\t\talert(i18n.text(\"Query.FailAndUndo\"));\n\t\t\t\t\t\tthis.restoreState();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tthis.history.push(state);\n\t\t\t\t\tvar indexToTypeToParentIdToHit = new Object();\n\t\t\t\t\tresults.docs.forEach(function(doc) {\n\t\t\t\t\t\tif (typeof indexToTypeToParentIdToHit[doc._index] == \"undefined\"){\n\t\t\t\t\t\tindexToTypeToParentIdToHit[doc._index] = new Object();\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\tif (typeof indexToTypeToParentIdToHit[doc._index][doc._type] == \"undefined\"){\n\t\t\t\t\t\tindexToTypeToParentIdToHit[doc._index][doc._type] = new Object();\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\tindexToTypeToParentIdToHit[doc._index][doc._type][doc._id] = doc;\n\t\t\t\t\t});\n\t\t\t\t\t\n\t\t\t\t\tres.hits.hits.forEach(function(hit) {\n\t\t\t\t\t\tif (typeof hit.fields != \"undefined\"){\n\t\t\t\t\t\t\tif (typeof hit.fields._parent != \"undefined\"){\n\t\t\t\t\t\t\t\tvar parentType = metadata.indices[hit._index].parents[hit._type];\n\t\t\t\t\t\t\t\thit._parent = indexToTypeToParentIdToHit[hit._index][parentType][hit.fields._parent];\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\tthis.fire(\"resultsWithParents\", this, res);\n\t\t\t\t}.bind(this));\n\t\t},\n\t\tsetPage: function(page) {\n\t\t\tthis.search.from = this.config.size * (page - 1);\n\t\t},\n\t\tsetSort: function(index, desc) {\n\t\t\tvar sortd = {}; sortd[index] = { order: desc ? 'asc' : 'desc' };\n\t\t\tthis.search.sort.unshift( sortd );\n\t\t\tfor(var i = 1; i < this.search.sort.length; i++) {\n\t\t\t\tif(Object.keys(this.search.sort[i])[0] === index) {\n\t\t\t\t\tthis.search.sort.splice(i, 1);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tsetIndex: function(index, add) {\n\t\t\tif(add) {\n\t\t\t\tif(! this.indices.contains(index)) this.indices.push(index);\n\t\t\t} else {\n\t\t\t\tthis.indices.remove(index);\n\t\t\t}\n\t\t\tthis.fire(\"setIndex\", this, { index: index, add: !!add });\n\t\t},\n\t\tsetType: function(type, add) {\n\t\t\tif(add) {\n\t\t\t\tif(! this.types.contains(type)) this.types.push(type);\n\t\t\t} else {\n\t\t\t\tthis.types.remove(type);\n\t\t\t}\n\t\t\tthis.fire(\"setType\", this, { type: type, add: !!add });\n\t\t},\n\t\taddClause: function(value, field, op, bool) {\n\t\t\tbool = bool || \"should\";\n\t\t\top = op || \"match_all\";\n\t\t\tfield = field || \"_all\";\n\t\t\tvar clause = this._setClause(value, field, op, bool);\n\t\t\tvar uqid = \"q-\" + this.refuid++;\n\t\t\tthis.refmap[uqid] = { clause: clause, value: value, field: field, op: op, bool: bool };\n\t\t\tif(this.search.query.bool.must.length + this.search.query.bool.should.length > 1) {\n\t\t\t\tthis.removeClause(this.defaultClause);\n\t\t\t}\n\t\t\tthis.fire(\"queryChanged\", this, { uqid: uqid, search: this.search} );\n\t\t\treturn uqid; // returns reference to inner query object to allow fast updating\n\t\t},\n\t\tremoveClause: function(uqid) {\n\t\t\tvar ref = this.refmap[uqid],\n\t\t\t\tbool = this.search.query.bool[ref.bool];\n\t\t\tbool.remove(ref.clause);\n\t\t\tif(this.search.query.bool.must.length + this.search.query.bool.should.length === 0) {\n\t\t\t\tthis.defaultClause = this.addClause();\n\t\t\t}\n\t\t},\n\t\taddAggs: function(aggs) {\n\t\t\tvar aggsId = \"f-\" + this.refuid++;\n\t\t\tthis.search.aggs[aggsId] = aggs;\n\t\t\tthis.refmap[aggsId] = { aggsId: aggsId, aggs: aggs };\n\t\t\treturn aggsId;\n\t\t},\n\t\tremoveAggs: function(aggsId) {\n\t\t\tdelete this.search.aggs[aggsId];\n\t\t\tdelete this.refmap[aggsId];\n\t\t},\n\t\t_setClause: function(value, field, op, bool) {\n\t\t\tvar clause = {}, query = {};\n\t\t\tif(op === \"match_all\") {\n\t\t\t} else if(op === \"query_string\") {\n\t\t\t\tquery[\"default_field\"] = field;\n\t\t\t\tquery[\"query\"] = value;\n\t\t\t} else if(op === \"missing\") {\n\t\t\t\top = \"constant_score\"\n\t\t\t\tvar missing = {}, filter = {};\n\t\t\t\tmissing[\"field\"] = field;\n\t\t\t\tfilter[\"missing\"] = missing\n\t\t\t\tquery[\"filter\"] = filter;\n\t\t\t} else {\n\t\t\t\tquery[field] = value;\n\t\t\t}\n\t\t\tclause[op] = query;\n\t\t\tthis.search.query.bool[bool].push(clause);\n\t\t\treturn clause;\n\t\t}\n\t});\n\n})( this.app );\n"
  },
  {
    "path": "src/app/data/queryDataSourceInterface.js",
    "content": "(function( app ) {\n\n\tvar data = app.ns(\"data\");\n\n\tdata.QueryDataSourceInterface = data.DataSourceInterface.extend({\n\t\tdefaults: {\n\t\t\tmetadata: null, // (required) instanceof app.data.MetaData, the cluster metadata\n\t\t\tquery: null     // (required) instanceof app.data.Query the data source\n\t\t},\n\t\tinit: function() {\n\t\t\tthis._super();\n\t\t\tthis.config.query.on(\"results\", this._results_handler.bind(this) );\n\t\t\tthis.config.query.on(\"resultsWithParents\", this._load_parents.bind(this) );\n\t\t},\n\t\t_results_handler: function(query, res) {\n\t\t\tthis._getSummary(res);\n\t\t\tthis._getMeta(res);\n\t\t\tvar sort = query.search.sort[0] || { \"_score\": { order: \"asc\" }};\n\t\t\tvar sortField = Object.keys(sort)[0];\n\t\t\tthis.sort = { column: sortField, dir: sort[sortField].order };\n\t\t\tthis._getData(res, this.config.metadata);\n\t\t\tthis.fire(\"data\", this);\n\t\t},\n\t\t_load_parents: function(query, res) {\n\t\t\tquery.loadParents(res, this.config.metadata);\n\t\t},\n\t\t_getData: function(res, metadata) {\n\t\t\tvar metaColumns = [\"_index\", \"_type\", \"_id\", \"_score\"];\n\t\t\tvar columns = this.columns = [].concat(metaColumns);\n\n\t\t\tthis.data = res.hits.hits.map(function(hit) {\n\t\t\t\tvar row = (function(path, spec, row) {\n\t\t\t\t\tfor(var prop in spec) {\n\t\t\t\t\t\tif(acx.isObject(spec[prop])) {\n\t\t\t\t\t\t\targuments.callee(path.concat(prop), spec[prop], row);\n\t\t\t\t\t\t} else if(acx.isArray(spec[prop])) {\n\t\t\t\t\t\t\tif(spec[prop].length) {\n\t\t\t\t\t\t\t\targuments.callee(path.concat(prop), spec[prop][0], row)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tvar dpath = path.concat(prop).join(\".\");\n\t\t\t\t\t\t\tif(metadata.paths[dpath]) {\n\t\t\t\t\t\t\t\tvar field_name = metadata.paths[dpath].field_name;\n\t\t\t\t\t\t\t\tif(! columns.contains(field_name)) {\n\t\t\t\t\t\t\t\t\tcolumns.push(field_name);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\trow[field_name] = (spec[prop] === null ? \"null\" : spec[prop] ).toString();\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// TODO: field not in metadata index\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\treturn row;\n\t\t\t\t})([ hit._index, hit._type ], hit._source, {});\n\t\t\t\tmetaColumns.forEach(function(n) { row[n] = hit[n]; });\n\t\t\t\trow._source = hit;\n\t\t\t\tif (typeof hit._parent!= \"undefined\") {\n\t\t\t\t\t(function(prefix, path, spec, row) {\n\t\t\t\t\tfor(var prop in spec) {\n\t\t\t\t\t\tif(acx.isObject(spec[prop])) {\n\t\t\t\t\t\t\targuments.callee(prefix, path.concat(prop), spec[prop], row);\n\t\t\t\t\t\t} else if(acx.isArray(spec[prop])) {\n\t\t\t\t\t\t\tif(spec[prop].length) {\n\t\t\t\t\t\t\t\targuments.callee(prefix, path.concat(prop), spec[prop][0], row)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tvar dpath = path.concat(prop).join(\".\");\n\t\t\t\t\t\t\tif(metadata.paths[dpath]) {\n\t\t\t\t\t\t\t\tvar field_name = metadata.paths[dpath].field_name;\n\t\t\t\t\t\t\t\tvar column_name = prefix+\".\"+field_name;\n\t\t\t\t\t\t\t\tif(! columns.contains(column_name)) {\n\t\t\t\t\t\t\t\t\tcolumns.push(column_name);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\trow[column_name] = (spec[prop] === null ? \"null\" : spec[prop] ).toString();\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// TODO: field not in metadata index\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\t})(hit._parent._type,[hit._parent._index, hit._parent._type], hit._parent._source, row);\n\t\t\t\t}\n\t\t\t\treturn row;\n\t\t\t}, this);\n\t\t}\n\t});\n\n})( this.app );\n"
  },
  {
    "path": "src/app/data/resultDataSourceInterface.js",
    "content": "(function( app ) {\n\n\tvar data = app.ns(\"data\");\n\n\tdata.ResultDataSourceInterface = data.DataSourceInterface.extend({\n\t\tresults: function(res) {\n\t\t\tthis._getSummary(res);\n\t\t\tthis._getMeta(res);\n\t\t\tthis._getData(res);\n\t\t\tthis.sort = {};\n\t\t\tthis.fire(\"data\", this);\n\t\t},\n\t\t_getData: function(res) {\n\t\t\tvar columns = this.columns = [];\n\t\t\tthis.data = res.hits.hits.map(function(hit) {\n\t\t\t\tvar row = (function(path, spec, row) {\n\t\t\t\t\tfor(var prop in spec) {\n\t\t\t\t\t\tif(acx.isObject(spec[prop])) {\n\t\t\t\t\t\t\targuments.callee(path.concat(prop), spec[prop], row);\n\t\t\t\t\t\t} else if(acx.isArray(spec[prop])) {\n\t\t\t\t\t\t\tif(spec[prop].length) {\n\t\t\t\t\t\t\t\targuments.callee(path.concat(prop), spec[prop][0], row)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tvar dpath = path.concat(prop).join(\".\");\n\t\t\t\t\t\t\tif(! columns.contains(dpath)) {\n\t\t\t\t\t\t\t\tcolumns.push(dpath);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\trow[dpath] = (spec[prop] || \"null\").toString();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn row;\n\t\t\t\t})([ hit._type ], hit, {});\n\t\t\t\trow._source = hit;\n\t\t\t\treturn row;\n\t\t\t}, this);\n\t\t}\n\t});\n\n})( this.app );\n"
  },
  {
    "path": "src/app/lang/en_strings.js",
    "content": "i18n.setKeys({\n\t\"General.Elasticsearch\": \"Elasticsearch\",\n\t\"General.LoadingAggs\": \"Loading Aggregations...\",\n\t\"General.Searching\": \"Searching...\",\n\t\"General.Search\": \"Search\",\n\t\"General.Help\": \"Help\",\n\t\"General.HelpGlyph\": \"?\",\n\t\"General.CloseGlyph\": \"X\",\n\t\"General.RefreshResults\": \"Refresh\",\n\t\"General.ManualRefresh\": \"Manual Refresh\",\n\t\"General.RefreshQuickly\": \"Refresh quickly\",\n\t\"General.Refresh5seconds\": \"Refresh every 5 seconds\",\n\t\"General.Refresh1minute\": \"Refresh every minute\",\n\t\"AliasForm.AliasName\": \"Alias Name\",\n\t\"AliasForm.NewAliasForIndex\": \"New Alias for {0}\",\n\t\"AliasForm.DeleteAliasMessage\": \"type ''{0}'' to delete {1}. There is no undo\",\n\t\"AnyRequest.DisplayOptions\" : \"Display Options\",\n\t\"AnyRequest.AsGraph\" : \"Graph Results\",\n\t\"AnyRequest.AsJson\" : \"Show Raw JSON\",\n\t\"AnyRequest.AsTable\" : \"Show Search Results Table\",\n\t\"AnyRequest.History\" : \"History\",\n\t\"AnyRequest.RepeatRequest\" : \"Repeat Request\",\n\t\"AnyRequest.RepeatRequestSelect\" : \"Repeat request every \",\n\t\"AnyRequest.Transformer\" : \"Result Transformer\",\n\t\"AnyRequest.Pretty\": \"Pretty\",\n\t\"AnyRequest.Query\" : \"Query\",\n\t\"AnyRequest.Request\": \"Request\",\n\t\"AnyRequest.Requesting\": \"Requesting...\",\n\t\"AnyRequest.ValidateJSON\": \"Validate JSON\",\n\t\"Browser.Title\": \"Browser\",\n\t\"Browser.ResultSourcePanelTitle\": \"Result Source\",\n\t\"Command.DELETE\": \"DELETE\",\n\t\"Command.SHUTDOWN\": \"SHUTDOWN\",\n\t\"Command.DeleteAliasMessage\": \"Delete Alias?\",\n\t\"ClusterOverView.IndexName\": \"Index Name\",\n\t\"ClusterOverview.NumShards\": \"Number of Shards\",\n\t\"ClusterOverview.NumReplicas\": \"Number of Replicas\",\n\t\"ClusterOverview.NewIndex\": \"New Index\",\n\t\"IndexActionsMenu.Title\": \"Actions\",\n\t\"IndexActionsMenu.NewAlias\": \"New Alias...\",\n\t\"IndexActionsMenu.Refresh\": \"Refresh\",\n\t\"IndexActionsMenu.Flush\": \"Flush\",\n\t\"IndexActionsMenu.Optimize\": \"Optimize...\",\n\t\"IndexActionsMenu.ForceMerge\": \"ForceMerge...\",\n\t\"IndexActionsMenu.Snapshot\": \"Gateway Snapshot\",\n\t\"IndexActionsMenu.Analyser\": \"Test Analyser\",\n\t\"IndexActionsMenu.Open\": \"Open\",\n\t\"IndexActionsMenu.Close\": \"Close\",\n\t\"IndexActionsMenu.Delete\": \"Delete...\",\n\t\"IndexInfoMenu.Title\": \"Info\",\n\t\"IndexInfoMenu.Status\": \"Index Status\",\n\t\"IndexInfoMenu.Metadata\": \"Index Metadata\",\n\t\"IndexCommand.TextToAnalyze\": \"Text to Analyse\",\n\t\"IndexCommand.AnalyzerToUse\": \"Name of Analyzer (built-in or customized)\",\n\t\"IndexCommand.ShutdownMessage\": \"type ''{0}'' to shutdown {1}. Node can NOT be restarted from this interface\",\n\t\"IndexOverview.PageTitle\": \"Indices Overview\",\n\t\"IndexSelector.NameWithDocs\": \"{0} ({1} docs)\",\n\t\"IndexSelector.SearchIndexForDocs\": \"Search {0} for documents where:\",\n\t\"FilterBrowser.OutputType\": \"Output Results: {0}\",\n\t\"FilterBrowser.OutputSize\": \"Number of Results: {0}\",\n\t\"Header.ClusterHealth\": \"cluster health: {0} ({1} of {2})\",\n\t\"Header.ClusterNotConnected\": \"cluster health: not connected\",\n\t\"Header.Connect\": \"Connect\",\n\t\"Nav.AnyRequest\": \"Any Request\",\n\t\"Nav.Browser\": \"Browser\",\n\t\"Nav.ClusterHealth\": \"Cluster Health\",\n\t\"Nav.ClusterState\": \"Cluster State\",\n\t\"Nav.ClusterNodes\": \"Nodes Info\",\n\t\"Nav.Info\": \"Info\",\n\t\"Nav.NodeStats\": \"Nodes Stats\",\n\t\"Nav.Overview\": \"Overview\",\n\t\"Nav.Indices\": \"Indices\",\n\t\"Nav.Plugins\": \"Plugins\",\n\t\"Nav.Status\": \"Indices Stats\",\n\t\"Nav.Templates\": \"Templates\",\n\t\"Nav.StructuredQuery\": \"Structured Query\",\n\t\"NodeActionsMenu.Title\": \"Actions\",\n\t\"NodeActionsMenu.Shutdown\": \"Shutdown...\",\n\t\"NodeInfoMenu.Title\": \"Info\",\n\t\"NodeInfoMenu.ClusterNodeInfo\": \"Cluster Node Info\",\n\t\"NodeInfoMenu.NodeStats\": \"Node Stats\",\n\t\"NodeType.Client\": \"Client Node\",\n\t\"NodeType.Coord\": \"Coordinator\",\n\t\"NodeType.Master\": \"Master Node\",\n\t\"NodeType.Tribe\": \"Tribe Node\",\n\t\"NodeType.Worker\": \"Worker Node\",\n\t\"NodeType.Unassigned\": \"Unassigned\",\n\t\"OptimizeForm.OptimizeIndex\": \"Optimize {0}\",\n\t\"OptimizeForm.MaxSegments\": \"Maximum # Of Segments\",\n\t\"OptimizeForm.ExpungeDeletes\": \"Only Expunge Deletes\",\n\t\"OptimizeForm.FlushAfter\": \"Flush After Optimize\",\n\t\"OptimizeForm.WaitForMerge\": \"Wait For Merge\",\n\t\"ForceMergeForm.ForceMergeIndex\": \"ForceMerge {0}\",\n\t\"ForceMergeForm.MaxSegments\": \"Maximum # Of Segments\",\n\t\"ForceMergeForm.ExpungeDeletes\": \"Only Expunge Deletes\",\n\t\"ForceMergeForm.FlushAfter\": \"Flush After ForceMerge\",\n\t\"Overview.PageTitle\" : \"Cluster Overview\",\n\t\"Output.JSON\": \"JSON\",\n\t\"Output.Table\": \"Table\",\n\t\"Output.CSV\": \"CSV\",\n\t\"Output.ShowSource\": \"Show query source\",\n\t\"Preference.SortCluster\": \"Sort Cluster\",\n\t\"Sort.ByName\": \"By Name\",\n\t\"Sort.ByAddress\": \"By Address\",\n\t\"Sort.ByType\": \"By Type\",\n\t\"Preference.SortIndices\": \"Sort Indices\",\n\t\"SortIndices.Descending\": \"Descending\",\n\t\"SortIndices.Ascending\": \"Ascending\",\n\t\"Preference.ViewAliases\": \"View Aliases\",\n\t\"ViewAliases.Grouped\": \"Grouped\",\n\t\"ViewAliases.List\": \"List\",\n\t\"ViewAliases.None\": \"None\",\n\t\"Overview.IndexFilter\": \"Index Filter\",\n\t\"TableResults.Summary\": \"Searched {0} of {1} shards. {2} hits. {3} seconds\",\n\t\"QueryFilter.AllIndices\": \"All Indices\",\n\t\"QueryFilter.AnyValue\": \"any\",\n\t\"QueryFilter-Header-Indices\": \"Indices\",\n\t\"QueryFilter-Header-Types\": \"Types\",\n\t\"QueryFilter-Header-Fields\": \"Fields\",\n\t\"QueryFilter.DateRangeHint.from\": \"From : {0}\",\n\t\"QueryFilter.DateRangeHint.to\": \"  To : {0}\",\n\t\"Query.FailAndUndo\": \"Query Failed. Undoing last changes\",\n\t\"StructuredQuery.ShowRawJson\": \"Show Raw JSON\"\n});\n\ni18n.setKeys({\n\t\"AnyRequest.TransformerHelp\" : \"\\\n\t\t<p>The Result Transformer can be used to post process the raw json results from a request into a more useful format.</p>\\\n\t\t<p>The transformer should contain the body of a javascript function. The return value from the function becomes the new value passed to the json printer</p>\\\n\t\t<p>Example:<br>\\\n\t\t  <code>return root.hits.hits[0];</code> would traverse a result set to show just the first match<br>\\\n\t\t  <code>return Object.keys(root.nodes).reduce(function(tot, node) { return tot + root.nodes[node].os.mem.used_in_bytes; }, 0);</code> would return the total memory used across an entire cluster<br></p>\\\n\t\t<p>The following functions are available and can be useful processing arrays and objects<br>\\\n\t\t<ul>\\\n\t\t\t<li><i>Object.keys</i>(object) := array</li>\\\n\t\t\t<li>array.<i>forEach</i>(function(prop, index))</li>\\\n\t\t\t<li>array.<i>map</i>(function(prop, index)) := array</li>\\\n\t\t\t<li>array.<i>reduce</i>(function(accumulator, prop, index), initial_value) := final_value</li>\\\n\t\t</ul>\\\n\t\t<p>When Repeat Request is running, an extra parameter called prev is passed to the transformation function. This allows comparisons, and cumulative graphing</p>\\\n\t\t<p>Example:<br>\\\n\t\t<code>var la = [ root.nodes[Object.keys(root.nodes)[0]].os.load_average[0] ]; return prev ? la.concat(prev) : la;</code> would return the load average on the first cluster node over the last minute\\\n\t\tThis could be fed into the Graph to produce a load graph for the node\\\n\t\t\"\n});\n\ni18n.setKeys({\n\t\"AnyRequest.DisplayOptionsHelp\" : \"\\\n\t\t<p>Raw Json: shows complete results of the query and transformation in raw JSON format </p>\\\n\t\t<p>Graph Results: To produce a graph of your results, use the result transformer to produce an array of values</p>\\\n\t\t<p>Search Results Table: If your query is a search, you can display the results of the search in a table.</p>\\\n\t\t\"\n});\n\ni18n.setKeys({\n\t\"QueryFilter.DateRangeHelp\" : \"\\\n\t\t<p>Date fields accept a natural language query to produce a From and To date that form a range that the results are queried over.</p>\\\n\t\t<p>The following formats are supported:</p>\\\n\t\t<ul>\\\n\t\t\t<li><b>Keywords / Key Phrases</b><br>\\\n\t\t\t\t<code>now<br> today<br> tomorrow<br> yesterday<br> last / this / next + week / month / year</code><br>\\\n\t\t\t\tsearches for dates matching the keyword. <code>last year</code> would search all of last year.</li>\\\n\t\t\t<li><b>Ranges</b><br>\\\n\t\t\t\t<code>1000 secs<br> 5mins<br> 1day<br> 2days<br> 80d<br> 9 months<br> 2yrs</code> (spaces optional, many synonyms for range qualifiers)<br>\\\n\t\t\t\tCreate a search range centered on <code>now</code> extending into the past and future by the amount specified.</li>\\\n\t\t\t<li><b>DateTime and Partial DateTime</b><br>\\\n\t\t\t\t<code>2011<br> 2011-01<br> 2011-01-18<br> 2011-01-18 12<br> 2011-01-18 12:32<br> 2011-01-18 12:32:45</code><br>\\\n\t\t\t\tthese formats specify a specific date range. <code>2011</code> would search the whole of 2011, while <code>2011-01-18 12:32:45</code> would only search for results in that 1 second range</li>\\\n\t\t\t<li><b>Time and Time Partials</b><br>\\\n\t\t\t\t<code>12<br> 12:32<br> 12:32:45</code><br>\\\n\t\t\t\tthese formats search for a particular time during the current day. <code>12:32</code> would search that minute during today</li>\\\n\t\t\t<li><b>Date Ranges</b><br>\\\n\t\t\t\t<code>2010 -&gt; 2011<br> last week -&gt; next week<br> 2011-05 -&gt;<br> &lt; now</code><br>\\\n\t\t\t\tA Date Range is created by specifying two dates in any format (Keyword / DateTime / Time) separated by &lt; or -&gt; (both do the same thing). If either end of the date range is missing, it is the same as having no constraint in that direction.</li>\\\n\t\t\t<li><b>Date Range using Offset</b><br>\\\n\t\t\t\t<code>2010 -> 1yr<br> 3mins < now</code>\\\n\t\t\t\tSearches the specified date including the range in the direction specified.</li>\\\n\t\t\t<li><b>Anchored Ranges</b><br>\\\n\t\t\t\t<code>2010-05-13 05:13 <> 10m<br> now <> 1yr<br> lastweek <> 1month</code><br>\\\n\t\t\t\tSimilar to above except the range is extend in both directions from the anchor date</li>\\\n\t\t</ul>\\\n\t\"\n});\n"
  },
  {
    "path": "src/app/lang/fr_strings.js",
    "content": "i18n.setKeys({\n//\t\"General.Elasticsearch\": \"Elasticsearch\",\n\t\"General.LoadingAggs\" : \"Chargement des facettes...\",\n\t\"General.Searching\": \"Recherche en cours...\",\n\t\"General.Search\": \"Recherche\",\n\t\"General.Help\": \"Aide\",\n//\t\"General.HelpGlyph\": \"?\",\n//\t\"General.CloseGlyph\": \"X\",\n\t\"General.RefreshResults\": \"Rafraîchir\",\n\t\"General.ManualRefresh\": \"Rafraîchissement manuel\",\n\t\"General.RefreshQuickly\": \"Rafraîchissement rapide\",\n\t\"General.Refresh5seconds\": \"Rafraîchissement toutes les 5 secondes\",\n\t\"General.Refresh1minute\": \"Rafraîchissement toutes les minutes\",\n\t\"AliasForm.AliasName\": \"Alias\",\n\t\"AliasForm.NewAliasForIndex\": \"Nouvel Alias pour {0}\",\n\t\"AliasForm.DeleteAliasMessage\": \"Entrez ''{0}'' pour effacer {1}. Attention, action irréversible.\",\n\t\"AnyRequest.DisplayOptions\" : \"Options d'affichage\",\n\t\"AnyRequest.AsGraph\" : \"En graphe\",\n\t\"AnyRequest.AsJson\" : \"En JSON brut\",\n\t\"AnyRequest.AsTable\" : \"En tableau\",\n\t\"AnyRequest.History\" : \"Historique\",\n\t\"AnyRequest.RepeatRequest\" : \"Répétition automatique de la requête\",\n\t\"AnyRequest.RepeatRequestSelect\" : \"Répéter la requête toutes les \",\n\t\"AnyRequest.Transformer\" : \"Transformation des résultats\",\n//\t\"AnyRequest.Pretty\": \"Pretty\",\n\t\"AnyRequest.Query\" : \"Recherche\",\n\t\"AnyRequest.Request\": \"Requête\",\n\t\"AnyRequest.Requesting\": \"Requête en cours...\",\n\t\"AnyRequest.ValidateJSON\": \"Valider le JSON\",\n\t\"Browser.Title\": \"Navigateur\",\n\t\"Browser.ResultSourcePanelTitle\": \"Résultat au format JSON\",\n\t\"Command.DELETE\": \"SUPPRIMER\",\n\t\"Command.SHUTDOWN\": \"ETEINDRE\",\n\t\"Command.DeleteAliasMessage\": \"Supprimer l'Alias?\",\n\t\"ClusterOverView.IndexName\": \"Index\",\n\t\"ClusterOverview.NumShards\": \"Nombre de shards\",\n\t\"ClusterOverview.NumReplicas\": \"Nombre de replica\",\n\t\"ClusterOverview.NewIndex\": \"Nouvel Index\",\n//\t\"IndexActionsMenu.Title\": \"Actions\",\n\t\"IndexActionsMenu.NewAlias\": \"Nouvel Alias...\",\n\t\"IndexActionsMenu.Refresh\": \"Rafraîchir\",\n\t\"IndexActionsMenu.Flush\": \"Flusher\",\n\t\"IndexActionsMenu.Optimize\": \"Optimiser...\",\n\t\"IndexActionsMenu.ForceMerge\": \"ForceMerge...\",\n\t\"IndexActionsMenu.Snapshot\": \"Dupliquer l'index (Snapshot)\",\n\t\"IndexActionsMenu.Analyser\": \"Tester un analyseur\",\n\t\"IndexActionsMenu.Open\": \"Ouvrir\",\n\t\"IndexActionsMenu.Close\": \"Fermer\",\n\t\"IndexActionsMenu.Delete\": \"Effacer...\",\n//\t\"IndexInfoMenu.Title\": \"Info\",\n\t\"IndexInfoMenu.Status\": \"Etat de l'Index\",\n\t\"IndexInfoMenu.Metadata\": \"Métadonnées de l'Index\",\n\t\"IndexCommand.TextToAnalyze\": \"Texte à analyser\",\n\t\"IndexCommand.ShutdownMessage\": \"Entrez ''{0}'' pour éteindre {1}. Le noeud NE PEUT PAS être redémarré depuis cette interface.\",\n//\t\"IndexSelector.NameWithDocs\": \"{0} ({1} docs)\",\n\t\"IndexSelector.SearchIndexForDocs\": \"Chercher dans {0} les documents correspondant à\",\n\t\"FilterBrowser.OutputType\": \"Format d'affichage des résultats {0}\",\n\t\"FilterBrowser.OutputSize\": \"Nombre de Résultats: {0}\",\n\t\"Header.ClusterHealth\": \"Santé du cluster: {0} ({1} {2})\",\n\t\"Header.ClusterNotConnected\": \"Santé du cluster: non connecté\",\n\t\"Header.Connect\": \"Se connecter\",\n\t\"Nav.AnyRequest\": \"Autres requêtes\",\n\t\"Nav.StructuredQuery\": \"Requêtes structurées\",\n\t\"Nav.Browser\": \"Navigateur\",\n\t\"Nav.ClusterHealth\": \"Santé du cluster\",\n\t\"Nav.ClusterState\": \"Etat du cluster\",\n\t\"Nav.ClusterNodes\": \"Noeuds du cluster\",\n//\t\"Nav.Info\": \"Info\",\n\t\"Nav.NodeStats\": \"Statistiques sur les noeuds\",\n\t\"Nav.Overview\": \"Aperçu\",\n\t\"Nav.Indices\": \"Index\",\n\t\"Nav.Plugins\": \"Plugins\",\n\t\"Nav.Status\": \"Etat\",\n\t\"Nav.Templates\": \"Templates\",\n\t\"Nav.StructuredQuery\": \"Recherche Structurée\",\n//\t\"NodeActionsMenu.Title\": \"Actions\",\n\t\"NodeActionsMenu.Shutdown\": \"Eteindre...\",\n//\t\"NodeInfoMenu.Title\": \"Info\",\n\t\"NodeInfoMenu.ClusterNodeInfo\": \"Infos sur le noeud du cluster\",\n\t\"NodeInfoMenu.NodeStats\": \"Statistiques du noeud\",\n\t\"NodeType.Client\": \"Noeud Client\",\n\t\"NodeType.Coord\": \"Coordinateur\",\n\t\"NodeType.Master\": \"Noeud Master\",\n\t\"NodeType.Tribe\": \"Noeud Tribe\",\n\t\"NodeType.Worker\": \"Noeud Worker\",\n\t\"NodeType.Unassigned\": \"Non assigné\",\n\t\"OptimizeForm.OptimizeIndex\": \"Optimiser {0}\",\n\t\"OptimizeForm.MaxSegments\": \"Nombre maximum de segments\",\n\t\"OptimizeForm.ExpungeDeletes\": \"Seulement purger les suppressions\",\n\t\"OptimizeForm.FlushAfter\": \"Flusher après l'optimisation\",\n\t\"OptimizeForm.WaitForMerge\": \"Attendre la fin de la fusion\",\n\t\"ForceMergeForm.ForceMergeIndex\": \"ForceMerge {0}\",\n\t\"ForceMergeForm.MaxSegments\": \"Nombre maximum de segments\",\n\t\"ForceMergeForm.ExpungeDeletes\": \"Seulement purger les suppressions\",\n\t\"ForceMergeForm.FlushAfter\": \"Flusher après ForceMerge\",\n\t\"Overview.PageTitle\" : \"Aperçu du cluster\",\n//\t\"Output.JSON\": \"JSON\",\n\t\"Output.Table\": \"Tableau\",\n\t\"Output.ShowSource\": \"Voir la requête source\",\n    \"TableResults.Summary\": \"Recherche sur {0} des {1} shards. {2} résultats. {3} secondes\",\n\t\"QueryFilter.AllIndices\": \"Tous les index\",\n\t\"QueryFilter.AnyValue\": \"Tout\",\n\t\"QueryFilter-Header-Indices\": \"Index\",\n//\t\"QueryFilter-Header-Types\": \"Types\",\n\t\"QueryFilter-Header-Fields\": \"Champs\",\n\t\"QueryFilter.DateRangeHint.from\": \"De : {0}\",\n\t\"QueryFilter.DateRangeHint.to\": \"  A : {0}\",\n\t\"Query.FailAndUndo\": \"Requête en échec. Annulation des dernières modifications.\",\n\t\"StructuredQuery.ShowRawJson\": \"Voir le JSON brut\"\n});\n\ni18n.setKeys({\n\t\"AnyRequest.TransformerHelp\" : \"\\\n\t\t<p>Le transformateur de résultats peut être utilisé pour modifier a posteriori les résultats JSON bruts dans un format plus utile.</p>\\\n\t\t<p>Le transformateur devrait contenir le corps d'une fonction javascript. La valeur de retour de la fonction devient la nouvelle valeur qui sera passée à l'afficheur des documents JSON.</p>\\\n\t\t<p>Exemple:<br>\\\n\t\t  <code>return root.hits.hits[0];</code> ne renverra que le premier élément de l'ensemble des résultats.<br>\\\n\t\t  <code>return Object.keys(root.nodes).reduce(function(tot, node) { return tot + root.nodes[node].os.mem.used_in_bytes; }, 0);</code> retournera la mémoire totale utilisée dans l'ensemble du cluster.<br></p>\\\n\t\t<p>Les fonctions suivantes sont disponibles et peuvent vous être utiles pour travailler sur les tableaux et les objets:<br>\\\n\t\t<ul>\\\n\t\t\t<li><i>Object.keys</i>(object) := array</li>\\\n\t\t\t<li>array.<i>forEach</i>(function(prop, index))</li>\\\n\t\t\t<li>array.<i>map</i>(function(prop, index)) := array</li>\\\n\t\t\t<li>array.<i>reduce</i>(function(accumulator, prop, index), initial_value) := final_value</li>\\\n\t\t</ul>\\\n\t\t<p>Lorsque vous activez la répétition automatique de la requête, un paramètre supplémentaire nommé prev est passé à la fonction de transformation. Cela permet les comparaisons et les graphes cumulatifs.</p>\\\n\t\t<p>Exemple:<br>\\\n\t\t<code>var la = [ root.nodes[Object.keys(root.nodes)[0]].os.load_average[0] ]; return prev ? la.concat(prev) : la;</code> retournera la charge moyenne du premier noeud du cluster pour la dernière minute écoulée.\\\n\t\tCela peut alimenter ensuite le graphe pour produire un graphe de charge du noeud.\\\n\t\t\"\n});\n\ni18n.setKeys({\n\t\"AnyRequest.DisplayOptionsHelp\" : \"\\\n\t\t<p>En JSON brut: affiche les résultats complets de la recherche éventuellement transformée au format JSON brut.</p>\\\n\t\t<p>En graphe: pour fabriquer un graphe de vos résultats, utilsez la transformation de résultats pour générer un tableau de valeurs.</p>\\\n\t\t<p>En tableau: si votre requête est une recherche, vous pouvez alors afficher les résultats dans un tableau.</p>\\\n\t\t\"\n});\n\ni18n.setKeys({\n\t\"QueryFilter.DateRangeHelp\" : \"\\\n\t\t<p>Les champs Date acceptent une requête en langage naturel pour produire un écart de date (from/to) correspondant.</p>\\\n\t\t<p>Les formats suivants sont acceptés :</p>\\\n\t\t<ul>\\\n\t\t\t<li><b>Mots clés</b><br>\\\n\t\t\t\t<code>now<br> today<br> tomorrow<br> yesterday<br> last / this / next + week / month / year</code><br>\\\n\t\t\t\tCherchera pour des dates correspondant au mot clé. <code>last year</code> cherchera sur toute l'année précédente.</li>\\\n\t\t\t<li><b>Ecarts</b><br>\\\n\t\t\t\t<code>1000 secs<br> 5mins<br> 1day<br> 2days<br> 80d<br> 9 months<br> 2yrs</code> (les espaces sont optionnels et il existe beaucoup de synonymes pour qualifier les écarts)<br>\\\n\t\t\t\tCréé un écart de date basé sur l'heure courante (maintenant) avec plus ou moins l'écart indiqué.</li>\\\n\t\t\t<li><b>Dates et Dates partielles</b><br>\\\n\t\t\t\t<code>2011<br> 2011-01<br> 2011-01-18<br> 2011-01-18 12<br> 2011-01-18 12:32<br> 2011-01-18 12:32:45</code><br>\\\n\t\t\t\tCes formats indiquent un écart de date spécifique. <code>2011</code> cherchera sur toute l'année 2011, alors que <code>2011-01-18 12:32:45</code> ne cherchera que pour la date précise à la seconde près.</li>\\\n\t\t\t<li><b>Heures et heures partielles</b><br>\\\n\t\t\t\t<code>12<br> 12:32<br> 12:32:45</code><br>\\\n\t\t\t\tCes formats indiquent un espace de temps pour la date du jour. <code>12:32</code> cherchera les éléments d'aujourd'hui à cette minute précise.</li>\\\n\t\t\t<li><b>Ecart de Date</b><br>\\\n\t\t\t\t<code>2010 -&gt; 2011<br> last week -&gt; next week<br> 2011-05 -&gt;<br> &lt; now</code><br>\\\n\t\t\t\tUn écart de date est créé en spécifiant deux dates dans n'importe lequel des formats précédents (Mot clé / Dates / Heures) séparées par &lt; ou -&gt; (les deux produisent le même effet). Si la date de fin n'est pas indiquée, alors il n'y aura aucune contrainte de fin.</li>\\\n\t\t\t<li><b>Ecart de date avec décalage</b><br>\\\n\t\t\t\t<code>2010 -> 1yr<br> 3mins < now</code>\\\n\t\t\t\tCherche en incluant un décalage de la date dans la direction indiquée.</li>\\\n\t\t\t<li><b>Ecart de date avec bornes</b><br>\\\n\t\t\t\t<code>2010-05-13 05:13 <> 10m<br> now <> 1yr<br> lastweek <> 1month</code><br>\\\n\t\t\t\tSimilaire à ci-dessus excepté que le décalage est appliqué dans les deux sens à partir de la date indiquée.</li>\\\n\t\t</ul>\\\n\t\"\n});\n"
  },
  {
    "path": "src/app/lang/ja_strings.js",
    "content": "i18n.setKeys({\n//\t\"General.Elasticsearch\": \"Elasticsearch\",\n\t\"General.LoadingAggs\": \"Aggregations ロード中...\",\n\t\"General.Searching\": \"検索中...\",\n\t\"General.Search\": \"Search\",\n\t\"General.Help\": \"ヘルプ\",\n//\t\"General.HelpGlyph\": \"?\",\n//\t\"General.CloseGlyph\": \"X\",\n\t\"General.RefreshResults\": \"リフレッシュ\",\n\t\"General.ManualRefresh\": \"マニュアルモード\",\n\t\"General.RefreshQuickly\": \"クイックモード\",\n\t\"General.Refresh5seconds\": \"5秒毎にリフレッシュ\",\n\t\"General.Refresh1minute\": \"1分毎にリフレッシュ\",\n\t\"AliasForm.AliasName\": \"エイリアス名\",\n\t\"AliasForm.NewAliasForIndex\": \"{0} の新しいエイリアス\",\n\t\"AliasForm.DeleteAliasMessage\": \"インデックス ''{1}'' を削除するために ''{0}'' とタイプして下さい. この操作は undo できません.\",\n\t\"AnyRequest.DisplayOptions\" : \"表示オプション\",\n\t\"AnyRequest.AsGraph\" : \"グラフの表示\",\n\t\"AnyRequest.AsJson\" : \"生の JSON を表示\",\n\t\"AnyRequest.AsTable\" : \"テーブルの表示\",\n\t\"AnyRequest.History\" : \"履歴\",\n\t\"AnyRequest.RepeatRequest\" : \"繰り返しリクエストを投げる\",\n\t\"AnyRequest.RepeatRequestSelect\" : \"次の間隔でリクエストを繰り返す\",\n\t\"AnyRequest.Transformer\" : \"Result Transformer\",\n//\t\"AnyRequest.Pretty\": \"Pretty\",\n\t\"AnyRequest.Query\" : \"Query\",\n\t\"AnyRequest.Request\": \"Request\",\n\t\"AnyRequest.Requesting\": \"検索中...\",\n\t\"AnyRequest.ValidateJSON\": \"Validate JSON\",\n\t\"Browser.Title\": \"Browser\",\n\t\"Browser.ResultSourcePanelTitle\": \"Result Source\",\n\t\"Command.DELETE\": \"DELETE\",\n\t\"Command.SHUTDOWN\": \"SHUTDOWN\",\n\t\"Command.DeleteAliasMessage\": \"エイリアスを削除しますか?\",\n\t\"ClusterOverView.IndexName\": \"Index名\",\n\t\"ClusterOverview.NumShards\": \"Number of Shards\",\n\t\"ClusterOverview.NumReplicas\": \"Number of Replicas\",\n\t\"ClusterOverview.NewIndex\": \"インデックスの作成\",\n//\t\"IndexActionsMenu.Title\": \"Actions\",\n\t\"IndexActionsMenu.NewAlias\": \"新しいエイリアス...\",\n\t\"IndexActionsMenu.Refresh\": \"Refresh\",\n\t\"IndexActionsMenu.Flush\": \"Flush\",\n\t\"IndexActionsMenu.Optimize\": \"Optimize...\",\n\t\"IndexActionsMenu.ForceMerge\": \"ForceMerge...\",\n\t\"IndexActionsMenu.Snapshot\": \"Gateway Snapshot\",\n\t\"IndexActionsMenu.Analyser\": \"Analyserテスト\",\n//\t\"IndexActionsMenu.Open\": \"Open\",\n//\t\"IndexActionsMenu.Close\": \"Close\",\n//\t\"IndexActionsMenu.Delete\": \"Delete...\",\n//\t\"IndexInfoMenu.Title\": \"Info\",\n//\t\"IndexInfoMenu.Status\": \"Index Status\",\n//\t\"IndexInfoMenu.Metadata\": \"Index Metadata\",\n\t\"IndexCommand.TextToAnalyze\": \"Analyse するテキストを入力\",\n\t\"IndexCommand.ShutdownMessage\": \" {1} をシャットダウンするために ''{0}'' と入力して下さい. このインターフェースからはリスタートはできません.\",\n\t\"IndexOverview.PageTitle\": \"インデックスのOverview\",\n//\t\"IndexSelector.NameWithDocs\": \"{0} ({1} docs)\",\n\t\"IndexSelector.SearchIndexForDocs\": \"Search {0} for documents where:\",\n\t\"FilterBrowser.OutputType\": \"結果の出力形式: {0} \",\n\t\"FilterBrowser.OutputSize\": \"結果の取得サイズ: {0} \",\n\t\"Header.ClusterHealth\": \"cluster health: {0} ({1} of {2})\",\n\t\"Header.ClusterNotConnected\": \"cluster health: not connected\",\n\t\"Header.Connect\": \"接続\",\n\t\"Nav.AnyRequest\": \"Any Request\",\n\t\"Nav.Browser\": \"Browser\",\n\t\"Nav.ClusterHealth\": \"Cluster Health\",\n\t\"Nav.ClusterState\": \"Cluster State\",\n\t\"Nav.ClusterNodes\": \"Nodes Info\",\n//\t\"Nav.Info\": \"Info\",\n\t\"Nav.NodeStats\": \"Nodes Stats\",\n\t\"Nav.Overview\": \"Overview\",\n\t\"Nav.Indices\": \"Indices\",\n\t\"Nav.Plugins\": \"Plugins\",\n\t\"Nav.Status\": \"Indices Stats\",\n\t\"Nav.Templates\": \"Templates\",\n\t\"Nav.StructuredQuery\": \"Structured Query\",\n//\t\"NodeActionsMenu.Title\": \"Actions\",\n\t\"NodeActionsMenu.Shutdown\": \"シャットダウン...\",\n//\t\"NodeInfoMenu.Title\": \"Info\",\n\t\"NodeInfoMenu.ClusterNodeInfo\": \"Cluster Node Info\",\n//\t\"NodeInfoMenu.NodeStats\": \"Node Stats\",\n\t\"NodeType.Client\": \"Client Node\",\n\t\"NodeType.Coord\": \"Coordinator\",\n\t\"NodeType.Master\": \"Master Node\",\n\t\"NodeType.Tribe\": \"Tribe Node\",\n\t\"NodeType.Worker\": \"Worker Node\",\n\t\"NodeType.Unassigned\": \"Unassigned\",\n\t\"OptimizeForm.OptimizeIndex\": \"Optimize {0}\",\n\t\"OptimizeForm.MaxSegments\": \"Maximum # Of Segments\",\n\t\"OptimizeForm.ExpungeDeletes\": \"Only Expunge Deletes\",\n\t\"OptimizeForm.FlushAfter\": \"Flush After Optimize\",\n\t\"OptimizeForm.WaitForMerge\": \"Wait For Merge\",\n\t\"ForceMergeForm.ForceMergeIndex\": \"ForceMerge {0}\",\n\t\"ForceMergeForm.MaxSegments\": \"Maximum # Of Segments\",\n\t\"ForceMergeForm.ExpungeDeletes\": \"Only Expunge Deletes\",\n\t\"ForceMergeForm.FlushAfter\": \"Flush After ForceMerge\",\n\t\"ForceMergeForm.WaitForMerge\": \"Wait For Merge\",\n\t\"Overview.PageTitle\" : \"クラスタのOverview\",\n//\t\"Output.JSON\": \"JSON\",\n\t\"Output.Table\": \"表\",\n//\t\"Output.CSV\": \"CSV\",\n\t\"Output.ShowSource\": \"Query の source を表示\",\n\t\"Preference.SortCluster\": \"ノードのソート\",\n\t\"Sort.ByName\": \"名前順\",\n\t\"Sort.ByAddress\": \"アドレス順\",\n\t\"Sort.ByType\": \"タイプ順\",\n\t\"Preference.SortIndices\": \"インデックスのソート\",\n\t\"SortIndices.Descending\": \"降順(desc)\",\n\t\"SortIndices.Ascending\": \"昇順(asc)\",\n\t\"Preference.ViewAliases\": \"エイリアスの表示方法\",\n\t\"ViewAliases.Grouped\": \"標準\",\n\t\"ViewAliases.List\": \"リスト形式\",\n\t\"ViewAliases.None\": \"表示しない\",\n\t\"Overview.IndexFilter\": \"インデックスの絞り込み\",\n\t\"TableResults.Summary\": \"検索結果: {0} / {1} シャード. {2} ヒット. {3} 秒\",\n\t\"QueryFilter.AllIndices\": \"全インデックス\",\n\t\"QueryFilter.AnyValue\": \"any\",\n\t\"QueryFilter-Header-Indices\": \"Indices\",\n//\t\"QueryFilter-Header-Types\": \"Types\",\n\t\"QueryFilter-Header-Fields\": \"Fields\",\n\t\"QueryFilter.DateRangeHint.from\": \"From : {0}\",\n\t\"QueryFilter.DateRangeHint.to\": \"  To : {0}\",\n\t\"Query.FailAndUndo\": \"Query Failed. Undoing last changes\",\n\t\"StructuredQuery.ShowRawJson\": \"生の JSON を表示する\"\n});\n\ni18n.setKeys({\n\t\"AnyRequest.TransformerHelp\" : \"\\\n\t\t<p>Result Transformer は、ESから返ってきた JSON をより使いやすい形式に変換することができます.</p>\\\n\t\t<p>transformer には javascript の function の中身を記述します. 戻り値の新しい JSON が画面出力されます.</p>\\\n\t\t<p>例:<br>\\\n\t\t  <code>return root.hits.hits[0];</code> 検索結果の最初のドキュメントだけを表示するように JSON をトラバースする例<br>\\\n\t\t  <code>return Object.keys(root.nodes).reduce(function(tot, node) { return tot + root.nodes[node].os.mem.used_in_bytes; }, 0);</code> クラスタ全体でのトータル使用メモリを返す例<br></p>\\\n\t\t<p>以下の関数は、配列やオブジェクトを扱うのに便利です<br>\\\n\t\t<ul>\\\n\t\t\t<li><i>Object.keys</i>(object) := array</li>\\\n\t\t\t<li>array.<i>forEach</i>(function(prop, index))</li>\\\n\t\t\t<li>array.<i>map</i>(function(prop, index)) := array</li>\\\n\t\t\t<li>array.<i>reduce</i>(function(accumulator, prop, index), initial_value) := final_value</li>\\\n\t\t</ul>\\\n\t\t<p>繰り返しリクエストを投げた時, prev 引数に前の戻り値が入ります. 比較や、累積グラフの作成などに利用できます.</p>\\\n\t\t<p>例:<br>\\\n\t\t<code>var la = [ root.nodes[Object.keys(root.nodes)[0]].os.load_average[0] ]; return prev ? la.concat(prev) : la;</code> 最初のノードの load_average を配列で返します.\\\n\t\tこの配列をグラフの入力値に用いることで load_average の遷移をグラフとして視覚化することができます.\\\n\t\t\"\n});\n\ni18n.setKeys({\n\t\"AnyRequest.DisplayOptionsHelp\" : \"\\\n\t\t<p>生の JSON の表示: 検索結果を生の JSON で表示します </p>\\\n\t\t<p>グラフの表示: 検索結果をグラフで表示します. Result Transformer を使って、配列の値に変換する必要があります</p>\\\n\t\t<p>表の表示: 検索クエリの場合には、結果を表形式で表示できます</p>\\\n\t\t\"\n});\n\n//i18n.setKeys({\n//\t\"QueryFilter.DateRangeHelp\" : \"\\\n//\t\t<p>Date fields accept a natural language query to produce a From and To date that form a range that the results are queried over.</p>\\\n//\t\t<p>The following formats are supported:</p>\\\n//\t\t<ul>\\\n//\t\t\t<li><b>Keywords / Key Phrases</b><br>\\\n//\t\t\t\t<code>now<br> today<br> tomorrow<br> yesterday<br> last / this / next + week / month / year</code><br>\\\n//\t\t\t\tsearches for dates matching the keyword. <code>last year</code> would search all of last year.</li>\\\n//\t\t\t<li><b>Ranges</b><br>\\\n//\t\t\t\t<code>1000 secs<br> 5mins<br> 1day<br> 2days<br> 80d<br> 9 months<br> 2yrs</code> (spaces optional, many synonyms for range qualifiers)<br>\\\n//\t\t\t\tCreate a search range centered on <code>now</code> extending into the past and future by the amount specified.</li>\\\n//\t\t\t<li><b>DateTime and Partial DateTime</b><br>\\\n//\t\t\t\t<code>2011<br> 2011-01<br> 2011-01-18<br> 2011-01-18 12<br> 2011-01-18 12:32<br> 2011-01-18 12:32:45</code><br>\\\n//\t\t\t\tthese formats specify a specific date range. <code>2011</code> would search the whole of 2011, while <code>2011-01-18 12:32:45</code> would only search for results in that 1 second range</li>\\\n//\t\t\t<li><b>Time and Time Partials</b><br>\\\n//\t\t\t\t<code>12<br> 12:32<br> 12:32:45</code><br>\\\n//\t\t\t\tthese formats search for a particular time during the current day. <code>12:32</code> would search that minute during today</li>\\\n//\t\t\t<li><b>Date Ranges</b><br>\\\n//\t\t\t\t<code>2010 -&gt; 2011<br> last week -&gt; next week<br> 2011-05 -&gt;<br> &lt; now</code><br>\\\n//\t\t\t\tA Date Range is created by specifying two dates in any format (Keyword / DateTime / Time) separated by &lt; or -&gt; (both do the same thing). If either end of the date range is missing, it is the same as having no constraint in that direction.</li>\\\n//\t\t\t<li><b>Date Range using Offset</b><br>\\\n//\t\t\t\t<code>2010 -> 1yr<br> 3mins < now</code>\\\n//\t\t\t\tSearches the specified date including the range in the direction specified.</li>\\\n//\t\t\t<li><b>Anchored Ranges</b><br>\\\n//\t\t\t\t<code>2010-05-13 05:13 <> 10m<br> now <> 1yr<br> lastweek <> 1month</code><br>\\\n//\t\t\t\tSimilar to above except the range is extend in both directions from the anchor date</li>\\\n//\t\t</ul>\\\n//\t\"\n//});\n"
  },
  {
    "path": "src/app/lang/pt_strings.js",
    "content": "i18n.setKeys({\n\t\"General.Elasticsearch\": \"Elasticsearch\",\n\t\"General.LoadingAggs\": \"Carregando Facetas...\",\n\t\"General.Searching\": \"Buscando...\",\n\t\"General.Search\": \"Busca\",\n\t\"General.Help\": \"Ajuda\",\n\t\"General.HelpGlyph\": \"?\",\n\t\"General.CloseGlyph\": \"X\",\n\t\"General.RefreshResults\": \"Atualizar\",\n\t\"General.ManualRefresh\": \"Atualização Manual\",\n\t\"General.RefreshQuickly\": \"Atualização rápida\",\n\t\"General.Refresh5seconds\": \"Atualização a cada 5 segundos\",\n\t\"General.Refresh1minute\": \"Atualização a cada minuto\",\n\t\"AliasForm.AliasName\": \"Apelido\",\n\t\"AliasForm.NewAliasForIndex\": \"Novo apelido para {0}\",\n\t\"AliasForm.DeleteAliasMessage\": \"digite ''{0}'' para deletar {1}. Não há como voltar atrás\",\n\t\"AnyRequest.DisplayOptions\" : \"Mostrar Opções\",\n\t\"AnyRequest.AsGraph\" : \"Mostrar como gráfico\",\n\t\"AnyRequest.AsJson\" : \"Mostrar JSON bruto\",\n\t\"AnyRequest.AsTable\" : \"Mostrar tabela de resultados da consulta\",\n\t\"AnyRequest.History\" : \"Histórico\",\n\t\"AnyRequest.RepeatRequest\" : \"Refazer requisição\",\n\t\"AnyRequest.RepeatRequestSelect\" : \"Repetir requisição a cada \",\n\t\"AnyRequest.Transformer\" : \"Transformador de resultado\",\n\t\"AnyRequest.Pretty\": \"Amigável\",\n\t\"AnyRequest.Query\" : \"Consulta\",\n\t\"AnyRequest.Request\": \"Requisição\",\n\t\"AnyRequest.Requesting\": \"Realizando requisição...\",\n\t\"AnyRequest.ValidateJSON\": \"Validar JSON\",\n\t\"Browser.Title\": \"Navegador\",\n\t\"Browser.ResultSourcePanelTitle\": \"Resultado\",\n\t\"Command.DELETE\": \"DELETAR\",\n\t\"Command.SHUTDOWN\": \"DESLIGAR\",\n\t\"Command.DeleteAliasMessage\": \"Remover apelido?\",\n\t\"ClusterOverView.IndexName\": \"Nome do índice\",\n\t\"ClusterOverview.NumShards\": \"Número de Shards\",\n\t\"ClusterOverview.NumReplicas\": \"Número de Réplicas\",\n\t\"ClusterOverview.NewIndex\": \"Novo índice\",\n\t\"IndexActionsMenu.Title\": \"Ações\",\n\t\"IndexActionsMenu.NewAlias\": \"Novo apelido...\",\n\t\"IndexActionsMenu.Refresh\": \"Atualizar\",\n\t\"IndexActionsMenu.Flush\": \"Flush\",\n\t\"IndexActionsMenu.Optimize\": \"Otimizar...\",\n\t\"IndexActionsMenu.ForceMerge\": \"ForceMerge...\",\n\t\"IndexActionsMenu.Snapshot\": \"Snapshot do Gateway\",\n\t\"IndexActionsMenu.Analyser\": \"Analizador de teste\",\n\t\"IndexActionsMenu.Open\": \"Abrir\",\n\t\"IndexActionsMenu.Close\": \"Fechar\",\n\t\"IndexActionsMenu.Delete\": \"Deletar...\",\n\t\"IndexInfoMenu.Title\": \"Info\",\n\t\"IndexInfoMenu.Status\": \"Status do índice\",\n\t\"IndexInfoMenu.Metadata\": \"Metadados do índice\",\n\t\"IndexCommand.TextToAnalyze\": \"Texto para analizar\",\n\t\"IndexCommand.ShutdownMessage\": \"digite ''{0}'' para desligar {1}. Nó NÃO PODE ser reiniciado à partir dessa interface\",\n\t\"IndexOverview.PageTitle\": \"Visão geral dos índices\",\n\t\"IndexSelector.NameWithDocs\": \"{0} ({1} documentoss)\",\n\t\"IndexSelector.SearchIndexForDocs\": \"Busca {0} por documentos onde:\",\n\t\"FilterBrowser.OutputType\": \"Resultados: {0}\",\n\t\"FilterBrowser.OutputSize\": \"Número de Resultados: {0}\",\n\t\"Header.ClusterHealth\": \"saúde do cluster: {0} ({1} {2})\",\n\t\"Header.ClusterNotConnected\": \"saúde do cluster: não conectado\",\n\t\"Header.Connect\": \"Conectar\",\n\t\"Nav.AnyRequest\": \"Qualquer requisição\",\n\t\"Nav.Browser\": \"Navegador\",\n\t\"Nav.ClusterHealth\": \"Saúde do Cluster\",\n\t\"Nav.ClusterState\": \"Estado do Cluster\",\n\t\"Nav.ClusterNodes\": \"Nós do Cluster\",\n\t\"Nav.Info\": \"Informações\",\n\t\"Nav.NodeStats\": \"Estatísticas do nó\",\n\t\"Nav.Overview\": \"Visão Geral\",\n\t\"Nav.Indices\": \"Índices\",\n\t\"Nav.Plugins\": \"Plugins\",\n\t\"Nav.Status\": \"Status\",\n\t\"Nav.Templates\": \"Modelos\",\n\t\"Nav.StructuredQuery\": \"Consulta Estruturada\",\n\t\"NodeActionsMenu.Title\": \"Ações\",\n\t\"NodeActionsMenu.Shutdown\": \"Desligar...\",\n\t\"NodeInfoMenu.Title\": \"Informações\",\n\t\"NodeInfoMenu.ClusterNodeInfo\": \"Informações do Nó do Cluster\",\n\t\"NodeInfoMenu.NodeStats\": \"Estatísticas do Nó\",\n\t\"NodeType.Client\": \"Nó cliente\",\n\t\"NodeType.Coord\": \"Coordenador\",\n\t\"NodeType.Master\": \"Nó mestre\",\n\t\"NodeType.Tribe\": \"Nó tribo\",\n\t\"NodeType.Worker\": \"Nó trabalhador\",\n\t\"NodeType.Unassigned\": \"Não atribuido\",\n\t\"OptimizeForm.OptimizeIndex\": \"Otimizar {0}\",\n\t\"OptimizeForm.MaxSegments\": \"# Máximo De Segmentos\",\n\t\"OptimizeForm.ExpungeDeletes\": \"Apenas Expurgar Exclusões\",\n\t\"OptimizeForm.FlushAfter\": \"Flush após Otimizar\",\n\t\"OptimizeForm.WaitForMerge\": \"Esperar Por Merge\",\n\t\"ForceMergeForm.ForceMergeIndex\": \"ForceMerge {0}\",\n\t\"ForceMergeForm.MaxSegments\": \"# Máximo De Segmentos\",\n\t\"ForceMergeForm.ExpungeDeletes\": \"Apenas Expurgar Exclusões\",\n\t\"ForceMergeForm.FlushAfter\": \"Flush após ForceMerge\",\n\t\"Overview.PageTitle\": \"Visão geral do Cluster\",\n\t\"Output.JSON\": \"JSON\",\n\t\"Output.Table\": \"Tabela\",\n\t\"Output.CSV\": \"CSV\",\n\t\"Output.ShowSource\": \"Mostrar consulta original\",\n\t\"Preference.SortCluster\": \"Ordenar Cluster\",\n\t\"Sort.ByName\": \"Por nome\",\n\t\"Sort.ByAddress\": \"Por endereço\",\n\t\"Sort.ByType\": \"Por tipo\",\n\t\"Preference.ViewAliases\": \"Ver Alias\",\n\t\"ViewAliases.Grouped\": \"Agrupado\",\n\t\"ViewAliases.List\": \"Lista\",\n\t\"ViewAliases.None\": \"Nenhum\",\n\t\"Overview.IndexFilter\": \"Filtar Índice\",\n\t\"TableResults.Summary\": \"Buscado {0} de {1} shards. {2} resultados. {3} segundos\",\n\t\"QueryFilter.AllIndices\": \"Todos os Índices\",\n\t\"QueryFilter.AnyValue\": \"qualquer\",\n\t\"QueryFilter-Header-Indices\": \"Índices\",\n\t\"QueryFilter-Header-Types\": \"Tipos\",\n\t\"QueryFilter-Header-Fields\": \"Campos\",\n\t\"QueryFilter.DateRangeHint.from\": \"De : {0}\",\n\t\"QueryFilter.DateRangeHint.to\": \"  A : {0}\",\n\t\"Query.FailAndUndo\": \"Consulta falhou. Desfazendo últimas alterações\",\n\t\"StructuredQuery.ShowRawJson\": \"Mostrar JSON bruto\"\n});\n\ni18n.setKeys({\n\t\"AnyRequest.TransformerHelp\" : \"\\\n\t\t<p>O Transformador de Resultados pode ser usado para transformar os resultados de uma consulta de json bruto para um formato mais útil.</p>\\\n\t\t<p>O transformador deve possuir o corpo de uma função javascript. O retorno da função se torna o novo valor passado para o json printer</p>\\\n\t\t<p>Exemplo:<br>\\\n\t\t  <code>return root.hits.hits[0];</code> irá alterar a resposta para mostrar apenas o primeiro resultado<br>\\\n\t\t  <code>return Object.keys(root.nodes).reduce(function(tot, node) { return tot + root.nodes[node].os.mem.used_in_bytes; }, 0);</code> irá retornar o total de memória utilizada pelo cluster<br></p>\\\n\t\t<p>As seguintes funções estão disponíveis e podem ser úteis no processamento de vetores e objetos<br>\\\n\t\t<ul>\\\n\t\t\t<li><i>Object.keys</i>(object) := array</li>\\\n\t\t\t<li>array.<i>forEach</i>(function(prop, index))</li>\\\n\t\t\t<li>array.<i>map</i>(function(prop, index)) := array</li>\\\n\t\t\t<li>array.<i>reduce</i>(function(accumulator, prop, index), initial_value) := final_value</li>\\\n\t\t</ul>\\\n\t\t<p>Durante a execução da opção Refazer Requisição, um parâmetro extra chamado prev é passado para a função de transformação. Isso permite fazer comparações e marcações cumulativas</p>\\\n\t\t<p>Exemplo:<br>\\\n\t\t<code>var la = [ root.nodes[Object.keys(root.nodes)[0]].os.load_average[0] ]; return prev ? la.concat(prev) : la;</code> irá retornar a carga média no primeiro nó do cluster no último minuto\\\n\t\tEssa informação pode ser inserida no Gráfico para fazer um gráfico de carga do nó\\\n\t\t\"\n});\n\ni18n.setKeys({\n\t\"AnyRequest.DisplayOptionsHelp\" : \"\\\n\t\t<p>Json Bruto: Exibe o resultado completo da consulta e da transformação no formato de JSON bruto</p>\\\n\t\t<p>Gráfico de Resultados: Para gerar um gráfico com seus resultados, utilize o tranformador de resultados para produzir um vetor de valores</p>\\\n\t\t<p>Tabela de Resultados da Consulta: Se sua consulta for uma busca, você pode exibir seus resultados no formato de uma tabela.</p>\\\n\t\t\"\n});\n\ni18n.setKeys({\n\t\"QueryFilter.DateRangeHelp\" : \"\\\n\t\t<p>Campos do tipo Data aceitam consultas em linguagem natural (em inglês) para produzir um <i>From</i> e um <i>To</i> de modo a formar um intervalo dentro do qual os resultados são filtrados.</p>\\\n\t\t<p>Os seguintes formatos são suportados:</p>\\\n\t\t<ul>\\\n\t\t\t<li><b>Palavras-chave</b><br>\\\n\t\t\t\t<code>now<br> today<br> tomorrow<br> yesterday<br> last / this / next + week / month / year</code><br>\\\n\t\t\t\tbuscam por datas de acordo com a palavra-chave. <code>last year</code> irá buscar tudo do último ano.</li>\\\n\t\t\t<li><b>Intervalos</b><br>\\\n\t\t\t\t<code>1000 secs<br> 5mins<br> 1day<br> 2days<br> 80d<br> 9 months<br> 2yrs</code> (espaços são opcionais, diversos sinônimos para qualificadores de intervalo)<br>\\\n\t\t\t\tCria um intervalo de busca a partir de agora (<code>now</code>), extendendo este intervalo no passado e no futuro de acordo com intervalo especificado.</li>\\\n\t\t\t<li><b>Data/Hora (<i>DateTime</i>) e Data/Hora parcial</b><br>\\\n\t\t\t\t<code>2011<br> 2011-01<br> 2011-01-18<br> 2011-01-18 12<br> 2011-01-18 12:32<br> 2011-01-18 12:32:45</code><br>\\\n\t\t\t\tesses formatos especificam um intervalo especifico. <code>2011</code> irá buscar todo o ano de 2011, enquanto <code>2011-01-18 12:32:45</code> irá buscar apenas por resultados dentro deste intervalo de 1 segundo</li>\\\n\t\t\t<li><b>Tempo (<i>Time</i>) e Tempo parcial</b><br>\\\n\t\t\t\t<code>12<br> 12:32<br> 12:32:45</code><br>\\\n\t\t\t\tesses formatos buscam por um horário específico no dia atual. <code>12:32</code> irá buscar este minuto específico do dia</li>\\\n\t\t\t<li><b>Intervalos de Data</b><br>\\\n\t\t\t\t<code>2010 -&gt; 2011<br> last week -&gt; next week<br> 2011-05 -&gt;<br> &lt; now</code><br>\\\n\t\t\t\tUm intervalo de data é criado especificando-se duas datas em qualquer formato (Palavras-chave, Data/Hora ou Tempo) separados por &lt; ou -&gt; (ambos fazem a mesma coisa). Se a data de início ou fim do intervalo não for especificada é a mesma coisa que não impor limites na busca nesta direção.</li>\\\n\t\t\t<li><b>Intervalo de Data com Deslocamento</b><br>\\\n\t\t\t\t<code>2010 -> 1yr<br> 3mins < now</code>\\\n\t\t\t\tBusca a data especificada incluindo o intervalo na direção determinada pelo deslocamento</li>\\\n\t\t\t<li><b>Intervalos Bidirecionais</b><br>\\\n\t\t\t\t<code>2010-05-13 05:13 <> 10m<br> now <> 1yr<br> lastweek <> 1month</code><br>\\\n\t\t\t\tIdêntico ao exemplo anterior porém o intervalo é extendido em ambas as direções a partir da data especificada</li>\\\n\t\t</ul>\\\n\t\"\n});\n"
  },
  {
    "path": "src/app/lang/tr_strings.js",
    "content": "i18n.setKeys({\r\n\t\"General.Elasticsearch\": \"Elasticsearch\",\r\n\t\"General.LoadingAggs\": \"Gruplar Yükleniyor...\",\r\n\t\"General.Searching\": \"Aranıyor...\",\r\n\t\"General.Search\": \"Ara\",\r\n\t\"General.Help\": \"Yardım\",\r\n\t\"General.HelpGlyph\": \"?\",\r\n\t\"General.CloseGlyph\": \"X\",\r\n\t\"General.RefreshResults\": \"Yenile\",\r\n\t\"General.ManualRefresh\": \"Manuel Yenileme\",\r\n\t\"General.RefreshQuickly\": \"Hızlı yenile\",\r\n\t\"General.Refresh5seconds\": \"5 saniyede bir yenile\",\r\n\t\"General.Refresh1minute\": \"Her dakika yenile\",\r\n\t\"AliasForm.AliasName\": \"Alternatif İsim\",\r\n\t\"AliasForm.NewAliasForIndex\": \"{0} için yeni alternatif isim\",\r\n\t\"AliasForm.DeleteAliasMessage\": \"{1} silmek için ''{0}'' . Geriye dönüş yoktur.\",\r\n\t\"AnyRequest.DisplayOptions\" : \"Seçenekleri Göster\",\r\n\t\"AnyRequest.AsGraph\" : \"Sonuçları Çizdir\",\r\n\t\"AnyRequest.AsJson\" : \"JSON formatında göster\",\r\n\t\"AnyRequest.AsTable\" : \"Arama sonuçlarını tablo halinde göster\",\r\n\t\"AnyRequest.History\" : \"Geçmiş\",\r\n\t\"AnyRequest.RepeatRequest\" : \"İsteği Tekrarla\",\r\n\t\"AnyRequest.RepeatRequestSelect\" : \"İsteği sürekli tekrarla \",\r\n\t\"AnyRequest.Transformer\" : \"Sonuç Dönüştürücü\",\r\n\t\"AnyRequest.Pretty\": \"Düzenli\",\r\n\t\"AnyRequest.Query\" : \"Sorgu\",\r\n\t\"AnyRequest.Request\": \"Gönder\",\r\n\t\"AnyRequest.Requesting\": \"İsteniyor...\",\r\n\t\"AnyRequest.ValidateJSON\": \"JSON Doğrula\",\r\n\t\"Browser.Title\": \"Browser\",\r\n\t\"Browser.ResultSourcePanelTitle\": \"Sonuç Kaynağı\",\r\n\t\"Command.DELETE\": \"SİL\",\r\n\t\"Command.SHUTDOWN\": \"KAPA\",\r\n\t\"Command.DeleteAliasMessage\": \"Alternatif ismi sil?\",\r\n\t\"ClusterOverView.IndexName\": \"Indeks İsmi\",\r\n\t\"ClusterOverview.NumShards\": \"Sektör Sayısı\",\r\n\t\"ClusterOverview.NumReplicas\": \"Yedek Sayısı\",\r\n\t\"ClusterOverview.NewIndex\": \"Yeni Indeks\",\r\n\t\"IndexActionsMenu.Title\": \"İşlemler\",\r\n\t\"IndexActionsMenu.NewAlias\": \"Yeni Alternatif İsim...\",\r\n\t\"IndexActionsMenu.Refresh\": \"Yenile\",\r\n\t\"IndexActionsMenu.Flush\": \"Boşalt\",\r\n\t\"IndexActionsMenu.Optimize\": \"Optimize et...\",\r\n\t\"IndexActionsMenu.ForceMerge\": \"ForceMerge et...\",\r\n\t\"IndexActionsMenu.Snapshot\": \"Gateway Snapshot (Kopya Al)\",\r\n\t\"IndexActionsMenu.Analyser\": \"Analizi test et\",\r\n\t\"IndexActionsMenu.Open\": \"Aç\",\r\n\t\"IndexActionsMenu.Close\": \"Kapa\",\r\n\t\"IndexActionsMenu.Delete\": \"Sil...\",\r\n\t\"IndexInfoMenu.Title\": \"Bilgi\",\r\n\t\"IndexInfoMenu.Status\": \"Indeks Durumu\",\r\n\t\"IndexInfoMenu.Metadata\": \"Indeks Metaveri\",\r\n\t\"IndexCommand.TextToAnalyze\": \"Analiz edilecek metin\",\r\n\t\"IndexCommand.ShutdownMessage\": \"{1} kapatmak için ''{0}'' yazın . Nod bu arayüzden tekrar BAŞLATILAMAZ\",\r\n\t\"IndexOverview.PageTitle\": \"Indeksler Genel Bakış\",\r\n\t\"IndexSelector.NameWithDocs\": \"{0} ({1} döküman)\",\r\n\t\"IndexSelector.SearchIndexForDocs\": \"{0} indeksinde ara:\",\r\n\t\"FilterBrowser.OutputType\": \"Sonuç Formatı: {0}\",\r\n\t\"FilterBrowser.OutputSize\": \"Sonuç Sayısı: {0}\",\r\n\t\"Header.ClusterHealth\": \"Küme Durumu: {0} ({1} de {2})\",\r\n\t\"Header.ClusterNotConnected\": \"Küme Durumu: Bağlı Değil\",\r\n\t\"Header.Connect\": \"Bağlan\",\r\n\t\"Nav.AnyRequest\": \"Özel Sorgu\",\r\n\t\"Nav.Browser\": \"Görüntüle\",\r\n\t\"Nav.ClusterHealth\": \"Küme Durumu\",\r\n\t\"Nav.ClusterState\": \"Küme Statüsü\",\r\n\t\"Nav.ClusterNodes\": \"Nod Bilgileri\",\r\n\t\"Nav.Info\": \"Bilgi\",\r\n\t\"Nav.NodeStats\": \"Nod İstatistikleri\",\r\n\t\"Nav.Overview\": \"Genel Bakış\",\r\n\t\"Nav.Indices\": \"Indeksler\",\r\n\t\"Nav.Plugins\": \"Eklentiler\",\r\n\t\"Nav.Status\": \"Indeks İstatistikleri\",\r\n\t\"Nav.Templates\": \"Şablonlar\",\r\n\t\"Nav.StructuredQuery\": \"Yapılandırılmış Sorgu\",\r\n\t\"NodeActionsMenu.Title\": \"İşlemler\",\r\n\t\"NodeActionsMenu.Shutdown\": \"Kapat...\",\r\n\t\"NodeInfoMenu.Title\": \"Bilgi\",\r\n\t\"NodeInfoMenu.ClusterNodeInfo\": \"Küme Nod Bilgileri\",\r\n\t\"NodeInfoMenu.NodeStats\": \"Nod İstatistikleri\",\r\n\t\"NodeType.Client\": \"Client Nod\",\r\n\t\"NodeType.Coord\": \"Coordinator\",\r\n\t\"NodeType.Master\": \"Master Nod\",\r\n\t\"NodeType.Tribe\": \"Tribe Nod\",\r\n\t\"NodeType.Worker\": \"Worker Nod\",\r\n\t\"NodeType.Unassigned\": \"Sahipsiz\",\r\n\t\"OptimizeForm.OptimizeIndex\": \"{0} Optimize Et\",\r\n\t\"OptimizeForm.MaxSegments\": \"Maksimum Segment Sayısı\",\r\n\t\"OptimizeForm.ExpungeDeletes\": \"Silme İşlemi Artıklarını Temizle\",\r\n\t\"OptimizeForm.FlushAfter\": \"Optimize Ettikten Sonra Boşalt\",\r\n\t\"OptimizeForm.WaitForMerge\": \"Birleştirme İçin Bekle\",\r\n\t\"ForceMergeForm.ForceMergeIndex\": \"{0} ForceMerge Et\",\r\n\t\"ForceMergeForm.MaxSegments\": \"Maksimum Segment Sayısı\",\r\n\t\"ForceMergeForm.ExpungeDeletes\": \"Silme İşlemi Artıklarını Temizle\",\r\n\t\"ForceMergeForm.FlushAfter\": \"ForceMerge Ettikten Sonra Boşalt\",\r\n\t\"ForceMergeForm.WaitForMerge\": \"Birleştirme İçin Bekle\",\r\n\t\"Overview.PageTitle\" : \"Kümeler Genelbakış\",\r\n\t\"Output.JSON\": \"JSON\",\r\n\t\"Output.Table\": \"Tablo\",\r\n\t\"Output.CSV\": \"CSV\",\r\n\t\"Output.ShowSource\": \"Sorgu kaynağını göster\",\r\n\t\"Preference.SortCluster\": \"Kümeyi Sırala\",\r\n\t\"Sort.ByName\": \"İsme göre\",\r\n\t\"Sort.ByAddress\": \"Adrese göre\",\r\n\t\"Sort.ByType\": \"Tipe göre\",\r\n\t\"Preference.SortIndices\": \"Indeksleri sırala\",\r\n\t\"SortIndices.Descending\": \"Azalan\",\r\n\t\"SortIndices.Ascending\": \"Artan\",\r\n\t\"Preference.ViewAliases\": \"Alternatif isimleri görüntüle\",\r\n\t\"ViewAliases.Grouped\": \"Gruplanmış\",\r\n\t\"ViewAliases.List\": \"Liste\",\r\n\t\"ViewAliases.None\": \"Karışık\",\r\n\t\"Overview.IndexFilter\": \"Indeks Filtresi\",\r\n\t\"TableResults.Summary\": \"{0} parçanın {1} tanesi arandı. {2} sonuç. {3} saniye\",\r\n\t\"QueryFilter.AllIndices\": \"Tüm Indeksler\",\r\n\t\"QueryFilter.AnyValue\": \"herhangi\",\r\n\t\"QueryFilter-Header-Indices\": \"Indeksler\",\r\n\t\"QueryFilter-Header-Types\": \"Tipler\",\r\n\t\"QueryFilter-Header-Fields\": \"Alanlar\",\r\n\t\"QueryFilter.DateRangeHint.from\": \"{0}'dan\",\r\n\t\"QueryFilter.DateRangeHint.to\": \"  {0}'a\",\r\n\t\"Query.FailAndUndo\": \"Sorgu Başarısız. Son değişiklikler geri alınıyor.\",\r\n\t\"StructuredQuery.ShowRawJson\": \"Formatsız JSON göster\"\r\n});\r\n\r\ni18n.setKeys({\r\n\t\"AnyRequest.TransformerHelp\" : \"\\\r\n\t\t<p>Sonuç Dönüştürücü sorgudan dönen JSON sonuçlarını işleyip daha kullanışlı bir formata dönüştürmek için kullanılabilir.</p>\\\r\n\t\t<p>Dönüştürücü içierisinde javascript fonksiyonu tanımlanmalıdır. Bu fonksiyondan dönen yeni sonuç çıktı kısmına yazdırılır.</p>\\\r\n\t\t<p>Örnek:<br>\\\r\n\t\t  <code>return root.hits.hits[0];</code> sonucu dolaşarak ilk eşleşmeyi göster<br>\\\r\n\t\t  <code>return Object.keys(root.nodes).reduce(function(tot, node) { return tot + root.nodes[node].os.mem.used_in_bytes; }, 0);</code> tüm kümede kullanılan toplam belleği gösterir<br></p>\\\r\n\t\t<p>Aşağıdaki fonksiyonlar dizi ve objelerin işlenmesinde yardımcı olması için kullanılabilir<br>\\\r\n\t\t<ul>\\\r\n\t\t\t<li><i>Object.keys</i>(object) := array</li>\\\r\n\t\t\t<li>array.<i>forEach</i>(function(prop, index))</li>\\\r\n\t\t\t<li>array.<i>map</i>(function(prop, index)) := array</li>\\\r\n\t\t\t<li>array.<i>reduce</i>(function(accumulator, prop, index), initial_value) := final_value</li>\\\r\n\t\t</ul>\\\r\n\t\t<p>Sorgu tekrarlama çalışırken, prev isimli ekstra bir parametre dönüştürücü fonksiyonuna verilir. Bu sayede karşılaştırmalar ve toplu grafik gösterimleri yapılabilir.</p>\\\r\n\t\t<p>Örnek:<br>\\\r\n\t\t<code>var la = [ root.nodes[Object.keys(root.nodes)[0]].os.load_average[0] ]; return prev ? la.concat(prev) : la;</code> önceki dakika boyunca kümede bulunan ilk nod üzerindeki averaj yükü verir.\\\r\n\t\tBu sonuç nod için yük grafiği yaratılmasında kullanılabilir.\\\r\n\t\t\"\r\n});\r\n\r\ni18n.setKeys({\r\n\t\"AnyRequest.DisplayOptionsHelp\" : \"\\\r\n\t\t<p>Sade Json: Sorgunun tüm sonuçlarını ve (yapıldıysa) dönüştürüldükten sonraki halini sade JSON formatında gösterir </p>\\\r\n\t\t<p>Sonuçları Çizdir: Sonuçları grafiksel olarak görüntülemek için sonuç dörücüyü kullanarak değerleri dizi haline getirin.</p>\\\r\n\t\t<p>Arama Sonuçları Tablosu: Eğer sorgunuz bir arama ise, sonuçları bir tabloda görüntüleyebilirsiniz.</p>\\\r\n\t\t\"\r\n});\r\n\r\ni18n.setKeys({\r\n\t\"QueryFilter.DateRangeHelp\" : \"\\\r\n\t\t<p>Tarih alanları ana dile yakın kelimeler kullanarak iki tarih aralığında sorgu yapılabilmesini sağlar.</p>\\\r\n\t\t<p>Aşağıdaki tanımlar kullanılabilir:</p>\\\r\n\t\t<ul>\\\r\n\t\t\t<li><b>Anahtar Kelimeler</b><br>\\\r\n\t\t\t\t<code>now<br> today<br> tomorrow<br> yesterday<br> last / this / next + week / month / year</code><br>\\\r\n\t\t\t\tkelimeleri eşleşen tarihleri verir. Örneğin <code>last year</code> geçen yıl tarihli bütün verileri döndürür.</li>\\\r\n\t\t\t<li><b>Aralıklar</b><br>\\\r\n\t\t\t\t<code>1000 secs<br> 5mins<br> 1day<br> 2days<br> 80d<br> 9 months<br> 2yrs</code> (boşluklar isteğe bağlıdır, ayni kelime için farklı yazım şekilleri kullanılabilir)<br>\\\r\n\t\t\t\tŞu anki tarihi (<code>now</code>) baz alarak geçmiş veya ileriki bir tarih aralığındaki kayıtları verir.</li>\\\r\n\t\t\t<li><b>Tarih ve Kısmi Tarihler</b><br>\\\r\n\t\t\t\t<code>2011<br> 2011-01<br> 2011-01-18<br> 2011-01-18 12<br> 2011-01-18 12:32<br> 2011-01-18 12:32:45</code><br>\\\r\n\t\t\t\tbu formatlar spesifik bir tarihi tanımlarlar. <code>2011</code> tüm 2011 yılını ararken, <code>2011-01-18 12:32:45</code> şeklinde bir sorgu sadece o saniyedeki sonuçları verir.</li>\\\r\n\t\t\t<li><b>Zaman ve Kısmi Zamanlar</b><br>\\\r\n\t\t\t\t<code>12<br> 12:32<br> 12:32:45</code><br>\\\r\n\t\t\t\tbu formatlar gün içerisinde spesifik bir zamanı tanımlarlar. Örneğin <code>12:32</code> sadece bu saat ve dakikadaki kayıtları verir.</li>\\\r\n\t\t\t<li><b>Tarih Aralıkları</b><br>\\\r\n\t\t\t\t<code>2010 -&gt; 2011<br> last week -&gt; next week<br> 2011-05 -&gt;<br> &lt; now</code><br>\\\r\n\t\t\t\tTarih aralıkları yukarda belirtilen herhangi bir formatı &lt; or -&gt;  ile ayırarak yapılabilir. Eğer aralığın bir tarafı eksikse, sorgu ucu açıkmış gibi davranır.</li>\\\r\n\t\t\t<li><b>Ofsetli Tarih Aralığı</b><br>\\\r\n\t\t\t\t<code>2010 -> 1yr<br> 3mins < now</code>\\\r\n\t\t\t\tVerilen yöndeki tarih aralığına bakar.</li>\\\r\n\t\t\t<li><b>Çakılı Aralıklar</b><br>\\\r\n\t\t\t\t<code>2010-05-13 05:13 <> 10m<br> now <> 1yr<br> lastweek <> 1month</code><br>\\\r\n\t\t\t\tYukarıdakiyle ayni fakat belirtilen tarihten her iki yöne de bakılır.</li>\\\r\n\t\t</ul>\\\r\n\t\"\r\n});\r\n"
  },
  {
    "path": "src/app/lang/vi_strings.js",
    "content": "i18n.setKeys({\n\t\"General.Elasticsearch\": \"Elasticsearch\",\n\t\"General.LoadingAggs\": \"Tổng hợp dữ liệu...\",\n\t\"General.Searching\": \"Đang tìm kiếm...\",\n\t\"General.Search\": \"Tìm kiếm\",\n\t\"General.Help\": \"Trợ giúp\",\n\t\"General.HelpGlyph\": \"?\",\n\t\"General.CloseGlyph\": \"X\",\n\t\"General.RefreshResults\": \"Refresh\",\n\t\"General.ManualRefresh\": \"Refresh\",\n\t\"General.RefreshQuickly\": \"Refresh nhanh\",\n\t\"General.Refresh5seconds\": \"Refresh sau 5 giây\",\n\t\"General.Refresh1minute\": \"Refresh sau 1 phút\",\n\t\"AliasForm.AliasName\": \"Alias\",\n\t\"AliasForm.NewAliasForIndex\": \"Alias mới cho {0}\",\n\t\"AliasForm.DeleteAliasMessage\": \"type ''{0}'' xóa {1}. Hành động này không thể hoàn tác.\",\n\t\"AnyRequest.DisplayOptions\" : \"Hiển thị\",\n\t\"AnyRequest.AsGraph\" : \"Hiển thị cây\",\n\t\"AnyRequest.AsJson\" : \"Hiển thị Json thô\",\n\t\"AnyRequest.AsTable\" : \"Hiển thị kết quả dạng bảng\",\n\t\"AnyRequest.History\" : \"Lịch sử\",\n\t\"AnyRequest.RepeatRequest\" : \"Lặp lại request\",\n\t\"AnyRequest.RepeatRequestSelect\" : \"Lặp lại request sau \",\n\t\"AnyRequest.Transformer\" : \"Truy vấn kết quả\",\n\t\"AnyRequest.Pretty\": \"Gọn\",\n\t\"AnyRequest.Query\" : \"Câu truy vấn\",\n\t\"AnyRequest.Request\": \"Request\",\n\t\"AnyRequest.Requesting\": \"Đang yêu cầu...\",\n\t\"AnyRequest.ValidateJSON\": \"Kiểm tra JSON\",\n\t\"Browser.Title\": \"Trình\",\n\t\"Browser.ResultSourcePanelTitle\": \"Kết quả\",\n\t\"Command.DELETE\": \"XÓA\",\n\t\"Command.SHUTDOWN\": \"TẮT\",\n\t\"Command.DeleteAliasMessage\": \"Xóa alias?\",\n\t\"ClusterOverView.IndexName\": \"Tên Index\",\n\t\"ClusterOverview.NumShards\": \"Số lượng Shards (tập con)\",\n\t\"ClusterOverview.NumReplicas\": \"Số lượng Replicas (nhân bản)\",\n\t\"ClusterOverview.NewIndex\": \"Index Mới\",\n\t\"IndexActionsMenu.Title\": \"Hành động\",\n\t\"IndexActionsMenu.NewAlias\": \"Alias mới...\",\n\t\"IndexActionsMenu.Refresh\": \"Refresh\",\n\t\"IndexActionsMenu.Flush\": \"Flush\",\n\t\"IndexActionsMenu.Optimize\": \"Tối ưu hóa...\",\n\t\"IndexActionsMenu.ForceMerge\": \"Bắt buộc xác nhập...\",\n\t\"IndexActionsMenu.Snapshot\": \"Gateway Snapshot\",\n\t\"IndexActionsMenu.Analyser\": \"Kiểm tra Analyser\",\n\t\"IndexActionsMenu.Open\": \"Mở\",\n\t\"IndexActionsMenu.Close\": \"Đóng\",\n\t\"IndexActionsMenu.Delete\": \"Xóa...\",\n\t\"IndexInfoMenu.Title\": \"Thông tin\",\n\t\"IndexInfoMenu.Status\": \"Trạng thái Index\",\n\t\"IndexInfoMenu.Metadata\": \"Index Metadata\",\n\t\"IndexCommand.TextToAnalyze\": \"Điền text để Analyse\",\n\t\"IndexCommand.ShutdownMessage\": \"loại ''{0}'' tắt {1}. Node không thể được restart ở đây\",\n\t\"IndexOverview.PageTitle\": \"Tóm tắt các index\",\n\t\"IndexSelector.NameWithDocs\": \"{0} ({1} docs)\",\n\t\"IndexSelector.SearchIndexForDocs\": \"Tìm kiếm {0} mà:\",\n\t\"FilterBrowser.OutputType\": \"Kết quả trả về: {0}\",\n\t\"FilterBrowser.OutputSize\": \"Số lượng kết quả: {0}\",\n\t\"Header.ClusterHealth\": \"Trạng thái cluster: {0} ({1} trong {2})\",\n\t\"Header.ClusterNotConnected\": \"Trạng thái cluster: không có kết nối\",\n\t\"Header.Connect\": \"Kết nối\",\n\t\"Nav.AnyRequest\": \"Gửi request\",\n\t\"Nav.Browser\": \"Trình\",\n\t\"Nav.ClusterHealth\": \"Trạng thái cluster\",\n\t\"Nav.ClusterState\": \"Tình trạng cluster\",\n\t\"Nav.ClusterNodes\": \"Thông tin các node\",\n\t\"Nav.Info\": \"Thông tin\",\n\t\"Nav.NodeStats\": \"Thông số các Nodes \",\n\t\"Nav.Overview\": \"Tóm tắt\",\n\t\"Nav.Indices\": \"Các index\",\n\t\"Nav.Plugins\": \"Plugins\",\n\t\"Nav.Status\": \"Thông số các index\",\n\t\"Nav.Templates\": \"Templates\",\n\t\"Nav.StructuredQuery\": \"Câu truy vấn\",\n\t\"NodeActionsMenu.Title\": \"Hành động\",\n\t\"NodeActionsMenu.Shutdown\": \"Tắt...\",\n\t\"NodeInfoMenu.Title\": \"Thông tin\",\n\t\"NodeInfoMenu.ClusterNodeInfo\": \"Thông tin Cluster node\",\n\t\"NodeInfoMenu.NodeStats\": \"Thông số Node\",\n\t\"NodeType.Client\": \"Client Node\",\n\t\"NodeType.Coord\": \"Coordinator\",\n\t\"NodeType.Master\": \"Master Node\",\n\t\"NodeType.Tribe\": \"Tribe Node\",\n\t\"NodeType.Worker\": \"Worker Node\",\n\t\"NodeType.Unassigned\": \"Chưa được gán\",\n\t\"OptimizeForm.OptimizeIndex\": \"Tối ưu hóa {0}\",\n\t\"OptimizeForm.MaxSegments\": \"Lượng Segments Max\",\n\t\"OptimizeForm.ExpungeDeletes\": \"Chỉ xóa\",\n\t\"OptimizeForm.FlushAfter\": \"Flush Sau Khi Optimize\",\n\t\"OptimizeForm.WaitForMerge\": \"Chờ Merge\",\n\t\"ForceMergeForm.ForceMergeIndex\": \"Bắt buộc merge {0}\",\n\t\"ForceMergeForm.MaxSegments\": \"Lượng Segments Max\",\n\t\"ForceMergeForm.ExpungeDeletes\": \"Chỉ xóa\",\n\t\"ForceMergeForm.FlushAfter\": \"Flush Sau Khi bắt buộc Merge\",\n\t\"Overview.PageTitle\" : \"Tóm tắt Cluster\",\n\t\"Output.JSON\": \"JSON\",\n\t\"Output.Table\": \"Bảng\",\n\t\"Output.CSV\": \"CSV\",\n\t\"Output.ShowSource\": \"Hiện câu truy vấn\",\n\t\"Preference.SortCluster\": \"Sắp xếp Cluster\",\n\t\"Sort.ByName\": \"Theo Tên\",\n\t\"Sort.ByAddress\": \"Theo Địa Chỉ\",\n\t\"Sort.ByType\": \"Theo Type\",\n\t\"Preference.SortIndices\": \"Sắp xếp các index\",\n\t\"SortIndices.Descending\": \"Giảm dần\",\n\t\"SortIndices.Ascending\": \"Tăng dần\",\n\t\"Preference.ViewAliases\": \"Xem Aliases\",\n\t\"ViewAliases.Grouped\": \"Nhóm\",\n\t\"ViewAliases.List\": \"List\",\n\t\"ViewAliases.None\": \"None\",\n\t\"Overview.IndexFilter\": \"Lọc Index\",\n\t\"TableResults.Summary\": \"Tìm {0} trong {1} shards. {2} kết quả. {3} giây\",\n\t\"QueryFilter.AllIndices\": \"Tất cả index\",\n\t\"QueryFilter.AnyValue\": \"bất kì\",\n\t\"QueryFilter-Header-Indices\": \"Các index\",\n\t\"QueryFilter-Header-Types\": \"Types\",\n\t\"QueryFilter-Header-Fields\": \"Trường\",\n\t\"QueryFilter.DateRangeHint.from\": \"Từ : {0}\",\n\t\"QueryFilter.DateRangeHint.to\": \"  Tới : {0}\",\n\t\"Query.FailAndUndo\": \"Truy vấn thất bại. Hoàn tác thay đổi gần nhất\",\n\t\"StructuredQuery.ShowRawJson\": \"Hiện JSON\"\n});\n\ni18n.setKeys({\n\t\"AnyRequest.TransformerHelp\" : \"\\\n\t\t<p>Chức năng này thay đổi kết quả thô json trả về dưới dạng format hữu dụng hơn.</p>\\\n\t\t<p>Chức năng cần phần body của một hàm javascript. Kết quả trả về từ hàm sẽ là giá trị mới gán cho hàm in json</p>\\\n\t\t<p>Ví dụ:<br>\\\n\t\t  <code>return root.hits.hits[0];</code> sẽ trả về kết quả đầu tiên trong chuỗi kết quả trả về<br>\\\n\t\t  <code>return Object.keys(root.nodes).reduce(function(tot, node) { return tot + root.nodes[node].os.mem.used_in_bytes; }, 0);</code> sẽ trả về tổng lượng bộ nhớ được dùng ở toàn cluster<br></p>\\\n\t\t<p>Các hàm có sẵn sau sẽ có ích khi làm việc với mảng và objects<br>\\\n\t\t<ul>\\\n\t\t\t<li><i>Object.keys</i>(object) := array</li>\\\n\t\t\t<li>array.<i>forEach</i>(function(prop, index))</li>\\\n\t\t\t<li>array.<i>map</i>(function(prop, index)) := array</li>\\\n\t\t\t<li>array.<i>reduce</i>(function(accumulator, prop, index), initial_value) := final_value</li>\\\n\t\t</ul>\\\n\t\t<p>Khi chạy Lặp lại Request, một biến extra tên prev được gửi tới hàm transformation. Nó cho phép thực hiện các thao tá so sánh và hiện biểu đồ.</p>\\\n\t\t<p>Ví dụ:<br>\\\n\t\t<code>var la = [ root.nodes[Object.keys(root.nodes)[0]].os.load_average[0] ]; return prev ? la.concat(prev) : la;</code> sẽ trả về load tải trung bình ở node đầu tiên trong cluster ở phút gần nhất\\\n\t\tKết quả có thể được cho vào Biểu đồ để hiện lượng tải của node\\\n\t\t\"\n});\n\ni18n.setKeys({\n\t\"AnyRequest.DisplayOptionsHelp\" : \"\\\n\t\t<p>Json Thô: hiện toàn bộ kết quả câu truy vấn dưới dạng json thô</p>\\\n\t\t<p>Graph: Hiển thị kết quả dưới dạng cây, dùng chức năng transformer để lấy các mảng từ kết quả</p>\\\n\t\t<p>Bảng kết quả: Nếu câu truy vấn là tìm kiếm thì có thể hiển thị dữ liệu ở dạng bảng.</p>\\\n\t\t\"\n});\n\ni18n.setKeys({\n\t\"QueryFilter.DateRangeHelp\" : \"\\\n\t\t<p>Các trường Date chấp nhận thời gian bằng chữ để tạo ra giá trị From và To để tạo ra khoảng thời gian của các kết quả mong muốn.</p>\\\n\t\t<p>Các định dạng sau được hỗ trợ:</p>\\\n\t\t<ul>\\\n\t\t\t<li><b>Keywords / Các cụm từ</b><br>\\\n\t\t\t\t<code>now (hiện nay)<br> today (trong hôm nay)<br> tomorrow (trong ngày mai)<br> yesterday (hôm qua)<br> last (cuối) / this (hiện tại) / next (tiếp theo) + week (tuần) / month (tháng) / year (năm)</code><br>\\\n\t\t\t\tsẽ tìm kết quả có thời gian dựa trên keyword. <code>last year</code> sẽ tìm kết quả trong năm ngoái.</li>\\\n\t\t\t<li><b>Ranges</b><br>\\\n\t\t\t\t<code>1000 secs<br> 5mins<br> 1day<br> 2days<br> 80d<br> 9 months<br> 2yrs</code> (dấu cách là không bắt buộc, có nhiều từ đồng nghĩa cho mục này)<br>\\\n\t\t\t\tTạo ra khoảng thời gian tìm kiếm dựa vào <code>now</code> kéo về quá khứ và tương lai để tìm ra range thích hợp.</li>\\\n\t\t\t<li><b>DateTime và Partial DateTime</b><br>\\\n\t\t\t\t<code>2011<br> 2011-01<br> 2011-01-18<br> 2011-01-18 12<br> 2011-01-18 12:32<br> 2011-01-18 12:32:45</code><br>\\\n\t\t\t\tcác định dạng này chỉ định cụ thể ngày tháng. <code>2011</code> sẽ tìm cả năm 2011, còn <code>2011-01-18 12:32:45</code> sẽ chỉ tìm trong thời gian cụ thể này thôi</li>\\\n\t\t\t<li><b>Time và Time Partials</b><br>\\\n\t\t\t\t<code>12<br> 12:32<br> 12:32:45</code><br>\\\n\t\t\t\tđịnh dạng này tìm kiếm trong khoảng thời gian trong ngày. <code>12:32</code> sẽ tìm trong giờ này thôi</li>\\\n\t\t\t<li><b>Date Ranges</b><br>\\\n\t\t\t\t<code>2010 -&gt; 2011<br> last week -&gt; next week<br> 2011-05 -&gt;<br> &lt; now</code><br>\\\n\t\t\t\tDate range được tạo ra bằng cách chỉ định hai ngày cụ thể (Keyword / DateTime / Time) cách nhau bởi kí tự &lt; hoặc -&gt; (cả hai như nhau). Nếu thiếu 1 ngày, thì sẽ coi như là không có giới hạn ngày.</li>\\\n\t\t\t<li><b>Date Range dùng Offset</b><br>\\\n\t\t\t\t<code>2010 -> 1yr<br> 3mins < now</code>\\\n\t\t\t\tTìm kiếm theo khoảng thời gian cộng thêm phần offset.</li>\\\n\t\t\t<li><b>Anchored Ranges</b><br>\\\n\t\t\t\t<code>2010-05-13 05:13 <> 10m<br> now <> 1yr<br> lastweek <> 1month</code><br>\\\n\t\t\t\tHoạt động giống như format ở trên nhưng khác là offset sẽ tính lùi và tiến so với thời gian được set.</li>\\\n\t\t</ul>\\\n\t\"\n});\n"
  },
  {
    "path": "src/app/lang/zh-TW_strings.js",
    "content": "i18n.setKeys({\n\t\"General.Elasticsearch\": \"Elasticsearch\",\n\t\"General.LoadingAggs\": \"讀取聚合查詢...\",\n\t\"General.Searching\": \"搜尋中...\",\n\t\"General.Search\": \"搜尋\",\n\t\"General.Help\": \"幫助\",\n\t\"General.HelpGlyph\": \"?\",\n\t\"General.CloseGlyph\": \"X\",\n\t\"General.RefreshResults\": \"更新\",\n\t\"General.ManualRefresh\": \"手動更新\",\n\t\"General.RefreshQuickly\": \"快速更新\",\n\t\"General.Refresh5seconds\": \"每5秒更新\",\n\t\"General.Refresh1minute\": \"每1分鐘更新\",\n\t\"AliasForm.AliasName\": \"别名\",\n\t\"AliasForm.NewAliasForIndex\": \"為 {0} 建立新别名\",\n\t\"AliasForm.DeleteAliasMessage\": \"輸入 ''{0}''  删除 {1}. 此操作無法恢復\",\n\t\"AnyRequest.DisplayOptions\" : \"顯示選項\",\n\t\"AnyRequest.AsGraph\" : \"圖形視圖\",\n\t\"AnyRequest.AsJson\" : \"原始 JSON\",\n\t\"AnyRequest.AsTable\" : \"表格視圖\",\n\t\"AnyRequest.History\" : \"歷史記錄\",\n\t\"AnyRequest.RepeatRequest\" : \"重複請求\",\n\t\"AnyRequest.RepeatRequestSelect\" : \"重複周期 \",\n\t\"AnyRequest.Transformer\" : \"結果轉換器\",\n\t\"AnyRequest.Pretty\": \"易讀\",\n\t\"AnyRequest.Query\" : \"查詢\",\n\t\"AnyRequest.Request\": \"送出\",\n\t\"AnyRequest.Requesting\": \"請求中...\",\n\t\"AnyRequest.ValidateJSON\": \"驗證 JSON\",\n\t\"Browser.Title\": \"資料瀏覽\",\n\t\"Browser.ResultSourcePanelTitle\": \"原始資料\",\n\t\"Command.DELETE\": \"删除\",\n\t\"Command.SHUTDOWN\": \"關閉\",\n\t\"Command.DeleteAliasMessage\": \"删除别名？\",\n\t\"ClusterOverView.IndexName\": \"索引名稱\",\n\t\"ClusterOverview.NumShards\": \"分片數\",\n\t\"ClusterOverview.NumReplicas\": \"副本數\",\n\t\"ClusterOverview.NewIndex\": \"新建索引\",\n\t\"IndexActionsMenu.Title\": \"動作\",\n\t\"IndexActionsMenu.NewAlias\": \"新建别名...\",\n\t\"IndexActionsMenu.Refresh\": \"更新\",\n\t\"IndexActionsMenu.Flush\": \"Flush更新\",\n\t\"IndexActionsMenu.Optimize\": \"最佳化...\",\n\t\"IndexActionsMenu.ForceMerge\": \"強制合併...\",\n\t\"IndexActionsMenu.Snapshot\": \"网关快照\",\n\t\"IndexActionsMenu.Analyser\": \"測試分析器\",\n\t\"IndexActionsMenu.Open\": \"開啟\",\n\t\"IndexActionsMenu.Close\": \"關閉\",\n\t\"IndexActionsMenu.Delete\": \"删除...\",\n\t\"IndexInfoMenu.Title\": \"訊息\",\n\t\"IndexInfoMenu.Status\": \"索引狀態\",\n\t\"IndexInfoMenu.Metadata\": \"索引訊息\",\n\t\"IndexCommand.TextToAnalyze\": \"文本分析\",\n\t\"IndexCommand.ShutdownMessage\": \"輸入 ''{0}'' 以關閉 {1} 節點. 關閉的節點無法從此界面重新啟動\",\n\t\"IndexOverview.PageTitle\": \"索引總覽\",\n\t\"IndexSelector.NameWithDocs\": \"{0} ({1} 個文件)\",\n\t\"IndexSelector.SearchIndexForDocs\": \"搜尋 {0} 的文件，查詢條件:\",\n\t\"FilterBrowser.OutputType\": \"返回格式: {0}\",\n\t\"FilterBrowser.OutputSize\": \"顯示數量: {0}\",\n\t\"Header.ClusterHealth\": \"叢集健康值: {0} ({1} of {2})\",\n\t\"Header.ClusterNotConnected\": \"叢集健康值: 未連接\",\n\t\"Header.Connect\": \"連接\",\n\t\"Nav.AnyRequest\": \"複合查詢\",\n\t\"Nav.Browser\": \"資料瀏覽\",\n\t\"Nav.ClusterHealth\": \"叢集健康值\",\n\t\"Nav.ClusterState\": \"群集狀態\",\n\t\"Nav.ClusterNodes\": \"叢集節點\",\n\t\"Nav.Info\": \"訊息\",\n\t\"Nav.NodeStats\": \"節點狀態\",\n\t\"Nav.Overview\": \"總覽\",\n\t\"Nav.Indices\": \"索引\",\n\t\"Nav.Plugins\": \"套件\",\n\t\"Nav.Status\": \"狀態\",\n\t\"Nav.Templates\": \"樣版\",\n\t\"Nav.StructuredQuery\": \"基本查詢\",\n\t\"NodeActionsMenu.Title\": \"動作\",\n\t\"NodeActionsMenu.Shutdown\": \"關閉節點...\",\n\t\"NodeInfoMenu.Title\": \"訊息\",\n\t\"NodeInfoMenu.ClusterNodeInfo\": \"叢集節點訊息\",\n\t\"NodeInfoMenu.NodeStats\": \"節點狀態\",\n\t\"NodeType.Client\": \"節點客户端\",\n\t\"NodeType.Coord\": \"協調器\",\n\t\"NodeType.Master\": \"主節點\",\n\t\"NodeType.Tribe\": \"分支節點\",\n\t\"NodeType.Worker\": \"工作節點\",\n\t\"NodeType.Unassigned\": \"未分配\",\n\t\"OptimizeForm.OptimizeIndex\": \"最佳化 {0}\",\n\t\"OptimizeForm.MaxSegments\": \"最大索引段數\",\n\t\"OptimizeForm.ExpungeDeletes\": \"只删除被標記為删除的\",\n\t\"OptimizeForm.FlushAfter\": \"最佳化後更新\",\n\t\"OptimizeForm.WaitForMerge\": \"等待合併\",\n\t\"ForceMergeForm.ForceMergeIndex\": \"強制合併 {0}\",\n\t\"ForceMergeForm.MaxSegments\": \"最大索引段數\",\n\t\"ForceMergeForm.ExpungeDeletes\": \"只删除被標記為删除的\",\n\t\"ForceMergeForm.FlushAfter\": \"強制合併後更新\",\n\t\"Overview.PageTitle\" : \"叢集總覽\",\n\t\"Output.JSON\": \"JSON\",\n\t\"Output.Table\": \"Table\",\n\t\"Output.CSV\": \"CSV\",\n\t\"Output.ShowSource\": \"顯示查詢語句\",\n\t\"Preference.SortCluster\": \"叢集排序\",\n\t\"Sort.ByName\": \"按名稱\",\n\t\"Sort.ByAddress\": \"按地址\",\n\t\"Sort.ByType\": \"按類型\",\n\t\"TableResults.Summary\": \"查詢 {1} 個分片中用的 {0} 個. {2} 命中. 耗時 {3} 秒\",\n\t\"QueryFilter.AllIndices\": \"所有索引\",\n\t\"QueryFilter.AnyValue\": \"任意\",\n\t\"QueryFilter-Header-Indices\": \"索引\",\n\t\"QueryFilter-Header-Types\": \"類型\",\n\t\"QueryFilter-Header-Fields\": \"欄位\",\n\t\"QueryFilter.DateRangeHint.from\": \"從 : {0}\",\n\t\"QueryFilter.DateRangeHint.to\": \"  到 : {0}\",\n\t\"Query.FailAndUndo\": \"查詢失敗. 撤銷最近的更改\",\n\t\"StructuredQuery.ShowRawJson\": \"顯示原始 JSON\"\n});\n\ni18n.setKeys({\n\t\"AnyRequest.TransformerHelp\" : \"\\\n\t\t<p>結果轉換器用於返回結果原始 JSON 的後續處理, 將結果轉換為更有用的格式.</p>\\\n\t\t<p>轉換器應當包含 JavaScript 函數內容. 函數的返回值將傳遞给 JSON 分析器</p>\\\n\t\t<p>Example:<br>\\\n\t\t  <code>return root.hits.hits[0];</code><br>\\\n\t\t  遍歷結果並只顯示第一個元素<br>\\\n\t\t  <code>return Object.keys(root.nodes).reduce(function(tot, node) { return tot + root.nodes[node].os.mem.used_in_bytes; }, 0);</code><br>\\\n\t\t  將返回整個叢集使用的總記憶體<br></p>\\\n\t\t<p>以下函數可以方便的處理陣列與物件<br>\\\n\t\t<ul>\\\n\t\t\t<li><i>Object.keys</i>(object) := array</li>\\\n\t\t\t<li>array.<i>forEach</i>(function(prop, index))</li>\\\n\t\t\t<li>array.<i>map</i>(function(prop, index)) := array</li>\\\n\t\t\t<li>array.<i>reduce</i>(function(accumulator, prop, index), initial_value) := final_value</li>\\\n\t\t</ul>\\\n\t\t<p>當啟用重複請求時, prev 參數將會傳遞给轉換器函數. 這將用於比較並累加圖形</p>\\\n\t\t<p>Example:<br>\\\n\t\t<code>var la = [ root.nodes[Object.keys(root.nodes)[0]].os.load_average[0] ]; return prev ? la.concat(prev) : la;</code><br>\\\n\t\t將返回第一個叢集節點最近一分鐘内的平均負載\\\n\t\t將會把結果送入圖表以產生一個負載曲線圖\\\n\t\t\"\n});\n\ni18n.setKeys({\n\t\"AnyRequest.DisplayOptionsHelp\" : \"\\\n\t\t<p>原始 JSON: 將完整的查詢結果轉換為原始 JSON 格式 </p>\\\n\t\t<p>圖形視圖: 將查詢結果圖形化, 將查詢結果轉換為陣列值的形式</p>\\\n\t\t<p>表格視圖: 如果查詢是一個搜尋, 可以將搜尋結果以表格形式顯示.</p>\\\n\t\t\"\n});\n\ni18n.setKeys({\n\t\"QueryFilter.DateRangeHelp\" : \"\\\n\t\t<p>Date 欄位接受日期範圍的形式查詢.</p>\\\n\t\t<p>以下格式被支援:</p>\\\n\t\t<ul>\\\n\t\t\t<li><b>關鍵詞 / 關鍵短語</b><br>\\\n\t\t\t\t<code>now<br> today<br> tomorrow<br> yesterday<br> last / this / next + week / month / year</code><br>\\\n\t\t\t\t搜尋關鍵字匹配的日期. <code>last year</code> 將搜尋過去全年.</li>\\\n\t\t\t<li><b>範圍</b><br>\\\n\t\t\t\t<code>1000 secs<br> 5mins<br> 1day<br> 2days<br> 80d<br> 9 months<br> 2yrs</code> (空格可選, 同等於多個範圍修飾詞)<br>\\\n\t\t\t\t建立一個指定時間範圍的搜尋, 將圍繞<code>现在</code> 並延伸至過去與未來時間段.</li>\\\n\t\t\t<li><b>DateTime 與 DateTime局部</b><br>\\\n\t\t\t\t<code>2011<br> 2011-01<br> 2011-01-18<br> 2011-01-18 12<br> 2011-01-18 12:32<br> 2011-01-18 12:32:45</code><br>\\\n\t\t\t\t指定一個特定的日期範圍. <code>2011</code>會搜尋整個 2011年, 而 <code>2011-01-18 12:32:45</code> 將只搜尋1秒範圍内</li>\\\n\t\t\t<li><b>Time 與 Time局部</b><br>\\\n\t\t\t\t<code>12<br> 12:32<br> 12:32:45</code><br>\\\n\t\t\t\t這些格式只搜尋當天的特定時間. <code>12:32</code> 將搜尋當天的那一分鐘</li>\\\n\t\t\t<li><b>日期範圍</b><br>\\\n\t\t\t\t<code>2010 -&gt; 2011<br> last week -&gt; next week<br> 2011-05 -&gt;<br> &lt; now</code><br>\\\n\t\t\t\t日期範圍是將兩個日期格式串 (日期關鍵字 / DateTime / Time) 用  &lt; 或 -&gt; (效果相同) 分隔. 如果缺少任意一端，那麼在這個方向上時間將沒有限制.</li>\\\n\t\t\t<li><b>偏移日期範圍</b><br>\\\n\t\t\t\t<code>2010 -> 1yr<br> 3mins < now</code>\\\n\t\t\t\t搜尋包括指定方向上偏移的日期.</li>\\\n\t\t\t<li><b>錨定範圍</b><br>\\\n\t\t\t\t<code>2010-05-13 05:13 <> 10m<br> now <> 1yr<br> lastweek <> 1month</code><br>\\\n\t\t\t\t類似於上面的便宜日期，在兩個方向上將錨定的日期延長</li>\\\n\t\t</ul>\\\n\t\"\n});\n"
  },
  {
    "path": "src/app/lang/zh_strings.js",
    "content": "i18n.setKeys({\n\t\"General.Elasticsearch\": \"Elasticsearch\",\n\t\"General.LoadingAggs\": \"加载聚合查询...\",\n\t\"General.Searching\": \"搜索中...\",\n\t\"General.Search\": \"搜索\",\n\t\"General.Help\": \"帮助\",\n\t\"General.HelpGlyph\": \"?\",\n\t\"General.CloseGlyph\": \"X\",\n\t\"General.RefreshResults\": \"刷新\",\n\t\"General.ManualRefresh\": \"手动刷新\",\n\t\"General.RefreshQuickly\": \"快速刷新\",\n\t\"General.Refresh5seconds\": \"每5秒刷新\",\n\t\"General.Refresh1minute\": \"每1分钟刷新\",\n\t\"AliasForm.AliasName\": \"别名\",\n\t\"AliasForm.NewAliasForIndex\": \"为 {0} 创建新别名\",\n\t\"AliasForm.DeleteAliasMessage\": \"输入 ''{0}''  删除 {1}. 此操作无法恢复\",\n\t\"AnyRequest.DisplayOptions\" : \"显示选项\",\n\t\"AnyRequest.AsGraph\" : \"图形视图\",\n\t\"AnyRequest.AsJson\" : \"原始 JSON\",\n\t\"AnyRequest.AsTable\" : \"表格视图\",\n\t\"AnyRequest.History\" : \"历史记录\",\n\t\"AnyRequest.RepeatRequest\" : \"重复请求\",\n\t\"AnyRequest.RepeatRequestSelect\" : \"重复周期 \",\n\t\"AnyRequest.Transformer\" : \"结果转换器\",\n\t\"AnyRequest.Pretty\": \"易读\",\n\t\"AnyRequest.Query\" : \"查询\",\n\t\"AnyRequest.Request\": \"提交请求\",\n\t\"AnyRequest.Requesting\": \"请求中...\",\n\t\"AnyRequest.ValidateJSON\": \"验证 JSON\",\n\t\"Browser.Title\": \"数据浏览\",\n\t\"Browser.ResultSourcePanelTitle\": \"原始数据\",\n\t\"Command.DELETE\": \"删除\",\n\t\"Command.SHUTDOWN\": \"关闭\",\n\t\"Command.DeleteAliasMessage\": \"删除别名?\",\n\t\"ClusterOverView.IndexName\": \"索引名称\",\n\t\"ClusterOverview.NumShards\": \"分片数\",\n\t\"ClusterOverview.NumReplicas\": \"副本数\",\n\t\"ClusterOverview.NewIndex\": \"新建索引\",\n\t\"IndexActionsMenu.Title\": \"动作\",\n\t\"IndexActionsMenu.NewAlias\": \"新建别名...\",\n\t\"IndexActionsMenu.Refresh\": \"刷新\",\n\t\"IndexActionsMenu.Flush\": \"Flush刷新\",\n\t\"IndexActionsMenu.Optimize\": \"优化...\",\n\t\"IndexActionsMenu.ForceMerge\": \"ForceMerge...\",\n\t\"IndexActionsMenu.Snapshot\": \"网关快照\",\n\t\"IndexActionsMenu.Analyser\": \"测试分析器\",\n\t\"IndexActionsMenu.Open\": \"开启\",\n\t\"IndexActionsMenu.Close\": \"关闭\",\n\t\"IndexActionsMenu.Delete\": \"删除...\",\n\t\"IndexInfoMenu.Title\": \"信息\",\n\t\"IndexInfoMenu.Status\": \"索引状态\",\n\t\"IndexInfoMenu.Metadata\": \"索引信息\",\n\t\"IndexCommand.TextToAnalyze\": \"文本分析\",\n\t\"IndexCommand.ShutdownMessage\": \"输入 ''{0}'' 以关闭 {1} 节点. 关闭的节点无法从此界面重新启动\",\n\t\"IndexOverview.PageTitle\": \"索引概览\",\n\t\"IndexSelector.NameWithDocs\": \"{0} ({1} 个文档)\",\n\t\"IndexSelector.SearchIndexForDocs\": \"搜索 {0} 的文档， 查询条件:\",\n\t\"FilterBrowser.OutputType\": \"返回格式: {0}\",\n\t\"FilterBrowser.OutputSize\": \"显示数量: {0}\",\n\t\"Header.ClusterHealth\": \"集群健康值: {0} ({1} of {2})\",\n\t\"Header.ClusterNotConnected\": \"集群健康值: 未连接\",\n\t\"Header.Connect\": \"连接\",\n\t\"Nav.AnyRequest\": \"复合查询\",\n\t\"Nav.Browser\": \"数据浏览\",\n\t\"Nav.ClusterHealth\": \"集群健康值\",\n\t\"Nav.ClusterState\": \"群集状态\",\n\t\"Nav.ClusterNodes\": \"集群节点\",\n\t\"Nav.Info\": \"信息\",\n\t\"Nav.NodeStats\": \"节点状态\",\n\t\"Nav.Overview\": \"概览\",\n\t\"Nav.Indices\": \"索引\",\n\t\"Nav.Plugins\": \"插件\",\n\t\"Nav.Status\": \"状态\",\n\t\"Nav.Templates\": \"模板\",\n\t\"Nav.StructuredQuery\": \"基本查询\",\n\t\"NodeActionsMenu.Title\": \"动作\",\n\t\"NodeActionsMenu.Shutdown\": \"关停...\",\n\t\"NodeInfoMenu.Title\": \"信息\",\n\t\"NodeInfoMenu.ClusterNodeInfo\": \"集群节点信息\",\n\t\"NodeInfoMenu.NodeStats\": \"节点状态\",\n\t\"NodeType.Client\": \"节点客户端\",\n\t\"NodeType.Coord\": \"协调器\",\n\t\"NodeType.Master\": \"主节点\",\n\t\"NodeType.Tribe\": \"分支结点\",\n\t\"NodeType.Worker\": \"工作节点\",\n\t\"NodeType.Unassigned\": \"未分配\",\n\t\"OptimizeForm.OptimizeIndex\": \"优化 {0}\",\n\t\"OptimizeForm.MaxSegments\": \"最大索引段数\",\n\t\"OptimizeForm.ExpungeDeletes\": \"只删除被标记为删除的\",\n\t\"OptimizeForm.FlushAfter\": \"优化后刷新\",\n\t\"OptimizeForm.WaitForMerge\": \"等待合并\",\n\t\"ForceMergeForm.ForceMergeIndex\": \"ForceMerge {0}\",\n\t\"ForceMergeForm.MaxSegments\": \"最大索引段数\",\n\t\"ForceMergeForm.ExpungeDeletes\": \"只删除被标记为删除的\",\n\t\"ForceMergeForm.FlushAfter\": \"ForceMerge后刷新\",\n\t\"Overview.PageTitle\" : \"集群概览\",\n\t\"Output.JSON\": \"JSON\",\n\t\"Output.Table\": \"Table\",\n\t\"Output.CSV\": \"CSV\",\n\t\"Output.ShowSource\": \"显示查询语句\",\n\t\"Preference.SortCluster\": \"集群排序\",\n\t\"Sort.ByName\": \"按名称\",\n\t\"Sort.ByAddress\": \"按地址\",\n\t\"Sort.ByType\": \"按类型\",\n\t\"TableResults.Summary\": \"查询 {1} 个分片中用的 {0} 个. {2} 命中. 耗时 {3} 秒\",\n\t\"QueryFilter.AllIndices\": \"所有索引\",\n\t\"QueryFilter.AnyValue\": \"任意\",\n\t\"QueryFilter-Header-Indices\": \"索引\",\n\t\"QueryFilter-Header-Types\": \"类型\",\n\t\"QueryFilter-Header-Fields\": \"字段\",\n\t\"QueryFilter.DateRangeHint.from\": \"从 : {0}\",\n\t\"QueryFilter.DateRangeHint.to\": \"  到 : {0}\",\n\t\"Query.FailAndUndo\": \"查询失败. 撤消最近的更改\",\n\t\"StructuredQuery.ShowRawJson\": \"显示原始 JSON\"\n});\n\ni18n.setKeys({\n\t\"AnyRequest.TransformerHelp\" : \"\\\n\t\t<p>结果转换器用于返回结果原始JSON的后续处理, 将结果转换为更有用的格式.</p>\\\n\t\t<p>转换器应当包含javascript函数体. 函数的返回值将传递给json分析器</p>\\\n\t\t<p>Example:<br>\\\n\t\t  <code>return root.hits.hits[0];</code><br>\\\n\t\t  遍历结果并只显示第一个元素<br>\\\n\t\t  <code>return Object.keys(root.nodes).reduce(function(tot, node) { return tot + root.nodes[node].os.mem.used_in_bytes; }, 0);</code><br>\\\n\t\t  将返回整个集群使用的总内存<br></p>\\\n\t\t<p>以下函数可以方便的处理数组与对象<br>\\\n\t\t<ul>\\\n\t\t\t<li><i>Object.keys</i>(object) := array</li>\\\n\t\t\t<li>array.<i>forEach</i>(function(prop, index))</li>\\\n\t\t\t<li>array.<i>map</i>(function(prop, index)) := array</li>\\\n\t\t\t<li>array.<i>reduce</i>(function(accumulator, prop, index), initial_value) := final_value</li>\\\n\t\t</ul>\\\n\t\t<p>当启用重复请求时, prev 参数将会传递给转换器函数. 这将用于比较并累加图形</p>\\\n\t\t<p>Example:<br>\\\n\t\t<code>var la = [ root.nodes[Object.keys(root.nodes)[0]].os.load_average[0] ]; return prev ? la.concat(prev) : la;</code><br>\\\n\t\t将返回第一个集群节点最近一分钟内的平均负载\\\n\t\t将会把结果送人图表以产生一个负载曲线图\\\n\t\t\"\n});\n\ni18n.setKeys({\n\t\"AnyRequest.DisplayOptionsHelp\" : \"\\\n\t\t<p>原始 Json: 将完整的查询结果转换为原始JSON格式 </p>\\\n\t\t<p>图形视图: 将查询结果图形化, 将查询结果转换为数组值的形式</p>\\\n\t\t<p>表格视图: 如果查询是一个搜索, 可以将搜索结果以表格形式显示.</p>\\\n\t\t\"\n});\n\ni18n.setKeys({\n\t\"QueryFilter.DateRangeHelp\" : \"\\\n\t\t<p>Date 字段接受日期范围的形式查询.</p>\\\n\t\t<p>一下格式被支持:</p>\\\n\t\t<ul>\\\n\t\t\t<li><b>关键词 / 关键短语</b><br>\\\n\t\t\t\t<code>now<br> today<br> tomorrow<br> yesterday<br> last / this / next + week / month / year</code><br>\\\n\t\t\t\t搜索关键字匹配的日期. <code>last year</code> 将搜索过去全年.</li>\\\n\t\t\t<li><b>范围</b><br>\\\n\t\t\t\t<code>1000 secs<br> 5mins<br> 1day<br> 2days<br> 80d<br> 9 months<br> 2yrs</code> (空格可选, 同等于多个范围修饰词)<br>\\\n\t\t\t\t创建一个指定时间范围的搜索, 将围绕<code>现在</code> 并延伸至过去与未来时间段.</li>\\\n\t\t\t<li><b>DateTime 与 DateTime局部</b><br>\\\n\t\t\t\t<code>2011<br> 2011-01<br> 2011-01-18<br> 2011-01-18 12<br> 2011-01-18 12:32<br> 2011-01-18 12:32:45</code><br>\\\n\t\t\t\t指定一个特定的日期范围. <code>2011</code>会搜索整个 2011年, 而 <code>2011-01-18 12:32:45</code> 将只搜索1秒范围内</li>\\\n\t\t\t<li><b>Time 与 Time局部</b><br>\\\n\t\t\t\t<code>12<br> 12:32<br> 12:32:45</code><br>\\\n\t\t\t\t这些格式只搜索当天的特定时间. <code>12:32</code> 将搜索当天的那一分钟</li>\\\n\t\t\t<li><b>日期范围</b><br>\\\n\t\t\t\t<code>2010 -&gt; 2011<br> last week -&gt; next week<br> 2011-05 -&gt;<br> &lt; now</code><br>\\\n\t\t\t\t日期范围是将两个日期格式串 (日期关键字 / DateTime / Time) 用  &lt; 或 -&gt; (效果相同) 分隔. 如果缺少任意一端，那么在这个方向上时间将没有限制.</li>\\\n\t\t\t<li><b>偏移日期范围</b><br>\\\n\t\t\t\t<code>2010 -> 1yr<br> 3mins < now</code>\\\n\t\t\t\t搜索包括指定方向上偏移的日期.</li>\\\n\t\t\t<li><b>锚定范围</b><br>\\\n\t\t\t\t<code>2010-05-13 05:13 <> 10m<br> now <> 1yr<br> lastweek <> 1month</code><br>\\\n\t\t\t\t类似于上面的便宜日期，在两个方向上将锚定的日期延长</li>\\\n\t\t</ul>\\\n\t\"\n});\n"
  },
  {
    "path": "src/app/services/cluster/cluster.js",
    "content": "(function( $, app ) {\n\n\tvar services = app.ns(\"services\");\n\tvar ux = app.ns(\"ux\");\n\n\tfunction parse_version( v ) {\n\t\treturn v.match(/^(\\d+)\\.(\\d+)\\.(\\d+)/).slice(1,4).map( function(d) { return parseInt(d || 0, 10); } );\n\t}\n\n\tservices.Cluster = ux.Class.extend({\n\t\tdefaults: {\n\t\t\tbase_uri: null\n\t\t},\n\t\tinit: function() {\n\t\t\tthis.base_uri = this.config.base_uri;\n\t\t},\n\t\tsetVersion: function( v ) {\n\t\t\tthis.version = v;\n\t\t\tthis._version_parts = parse_version( v );\n\t\t},\n\t\tversionAtLeast: function( v ) {\n\t\t\tvar testVersion = parse_version( v );\n\t\t\tfor( var i = 0; i < 3; i++ ) {\n\t\t\t\tif( testVersion[i] !== this._version_parts[i] ) {\n\t\t\t\t\treturn testVersion[i] < this._version_parts[i];\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\t\trequest: function( params ) {\n\t\t\treturn $.ajax( $.extend({\n\t\t\t\turl: this.base_uri + params.path,\n\t\t\t\tcontentType: \"application/json\",\n\t\t\t\tdataType: \"json\",\n\t\t\t\terror: function(xhr, type, message) {\n\t\t\t\t\tif(\"console\" in window) {\n\t\t\t\t\t\tconsole.log({ \"XHR Error\": type, \"message\": message });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},  params) );\n\t\t},\n\t\t\"get\": function(path, success, error) { return this.request( { type: \"GET\", path: path, success: success, error: error } ); },\n\t\t\"post\": function(path, data, success, error) { return this.request( { type: \"POST\", path: path, data: data, success: success, error: error } ); },\n\t\t\"put\": function(path, data, success, error) { return this.request( { type: \"PUT\", path: path, data: data, success: success, error: error } ); },\n\t\t\"delete\": function(path, data, success, error) { return this.request( { type: \"DELETE\", path: path, data: data, success: success, error: error } ); }\n\t});\n\n})( this.jQuery, this.app );\n"
  },
  {
    "path": "src/app/services/cluster/clusterSpec.js",
    "content": "describe(\"app.services.Cluster\", function() {\n\n\tvar Cluster = window.app.services.Cluster;\n\tvar test = window.test;\n\n\tvar cluster;\n\n\tbeforeEach( function() {\n\t\tcluster = new Cluster({ base_uri: \"http://localhost:9200/\" });\n\t});\n\n\tdescribe( \"when it is initialised\", function() {\n\n\t\tit(\"should have a localhost base_uri\", function() {\n\t\t\texpect( cluster.base_uri ).toBe( \"http://localhost:9200/\" );\n\t\t});\n\n\t\tit(\"should have no version\", function() {\n\t\t\texpect( cluster.version ).toBe( undefined );\n\t\t});\n\n\t});\n\n\tdescribe( \"setVersion()\", function() {\n\n\t\tit(\"have a version\", function() {\n\t\t\tcluster.setVersion( \"1.12.3-5\" );\n\t\t\texpect( cluster.version ).toBe( \"1.12.3-5\" );\n\t\t});\n\n\t});\n\n\tdescribe(\"versionAtLeast()\", function() {\n\t\tvar vs = [ \"0.0.3\", \"0.13.5\", \"0.90.3\", \"1.0.0\", \"1.1.0\", \"1.2.3\", \"1.12.4.rc2\", \"13.0.0\" ];\n\n\t\tit(\"should return true for versions that are less than or equal to the current version\", function() {\n\t\t\tcluster.setVersion(\"1.12.5\");\n\t\t\texpect( cluster.versionAtLeast(\"1.12.5\" ) ).toBe( true );\n\t\t\texpect( cluster.versionAtLeast(\"1.12.5rc2\" ) ).toBe( true );\n\t\t\texpect( cluster.versionAtLeast(\"1.12.5-6\" ) ).toBe( true );\n\t\t\texpect( cluster.versionAtLeast(\"1.12.5-6.beta7\" ) ).toBe( true );\n\t\t\texpect( cluster.versionAtLeast(\"1.12.4\" ) ).toBe( true );\n\t\t\texpect( cluster.versionAtLeast(\"0.12.4\" ) ).toBe( true );\n\t\t\texpect( cluster.versionAtLeast(\"1.1.8\" ) ).toBe( true );\n\n\t\t\tfor( var i = 0; i < vs.length - 1; i++ ) {\n\t\t\t\tcluster.setVersion( vs[i+1] );\n\t\t\t\texpect( cluster.versionAtLeast( vs[i] ) ).toBe( true );\n\t\t\t}\n\t\t});\n\n\t\tit(\"should return false for versions that are greater than the current version\", function() {\n\t\t\tcluster.setVersion(\"1.12.5\");\n\t\t\texpect( cluster.versionAtLeast(\"1.12.6\" ) ).toBe( false );\n\t\t\texpect( cluster.versionAtLeast(\"1.13.4\" ) ).toBe( false );\n\t\t\texpect( cluster.versionAtLeast(\"2.0.0\" ) ).toBe( false );\n\n\t\t\tfor( var i = 0; i < vs.length - 1; i++ ) {\n\t\t\t\tcluster.setVersion( vs[i] );\n\t\t\t\texpect( cluster.versionAtLeast( vs[i+1] ) ).toBe( false );\n\t\t\t}\n\t\t});\n\t});\n\n});\n"
  },
  {
    "path": "src/app/services/clusterState/clusterState.js",
    "content": "\t(function( app ) {\n\n\tvar services = app.ns(\"services\");\n\tvar ux = app.ns(\"ux\");\n\n\tservices.ClusterState = ux.Observable.extend({\n\t\tdefaults: {\n\t\t\tcluster: null\n\t\t},\n\t\tinit: function() {\n\t\t\tthis._super();\n\t\t\tthis.cluster = this.config.cluster;\n\t\t\tthis.clusterState = null;\n\t\t\tthis.status = null;\n\t\t\tthis.nodeStats = null;\n\t\t\tthis.clusterNodes = null;\n\t\t},\n\t\trefresh: function() {\n\t\t\tvar self = this, clusterState, status, nodeStats, clusterNodes, clusterHealth;\n\t\t\tfunction updateModel() {\n\t\t\t\tif( clusterState && status && nodeStats && clusterNodes && clusterHealth ) {\n\t\t\t\t\tthis.clusterState = clusterState;\n\t\t\t\t\tthis.status = status;\n\t\t\t\t\tthis.nodeStats = nodeStats;\n\t\t\t\t\tthis.clusterNodes = clusterNodes;\n\t\t\t\t\tthis.clusterHealth = clusterHealth;\n\t\t\t\t\tthis.fire( \"data\", this );\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar _cluster = this.cluster;\n\t\t\t_cluster.get(\"_cluster/state\", function( data ) {\n\t\t\t\tclusterState = data;\n\t\t\t\tupdateModel.call( self );\n\t\t\t},function() {\n\t\t\t\t\n\t\t\t\t_cluster.get(\"_all\", function( data ) {\n\t\t\t\t\tclusterState = {routing_table:{indices:{}}, metadata:{indices:{}}};\n\t\t\t\t\t\n\t\t\t\t\tfor(var k in data) {\n\t\t\t\t\t\tclusterState[\"routing_table\"][\"indices\"][k] = {\"shards\":{\"1\":[{\n                            \"state\":\"UNASSIGNED\",\n                            \"primary\":false,\n                            \"node\":\"unknown\",\n                            \"relocating_node\":null,\n                            \"shard\":'?',\n                            \"index\":k\n                        }]}};\n\t\t\t\t\t\t\n\n\t\t\t\t\t\tclusterState[\"metadata\"][\"indices\"][k] = {};\n\t\t\t\t\t\tclusterState[\"metadata\"][\"indices\"][k][\"mappings\"] = data[k][\"mappings\"];\n\t\t\t\t\t\tclusterState[\"metadata\"][\"indices\"][k][\"aliases\"] = $.makeArray(Object.keys(data[k][\"aliases\"]));\n\t\t\t\t\t\tclusterState[\"metadata\"][\"indices\"][k][\"settings\"] = data[k][\"settings\"];\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\tupdateModel.call( self );\n\t\t\t\t});\n\t\t\t\t\n\t\t\t});\n\t\t\tthis.cluster.get(\"_stats\", function( data ) {\n\t\t\t\tstatus = data;\n\t\t\t\tupdateModel.call( self );\n\t\t\t});\n\t\t\tthis.cluster.get(\"_nodes/stats\", function( data ) {\n\t\t\t\tnodeStats = data;\n\t\t\t\tupdateModel.call( self );\n\t\t\t});\n\t\t\tthis.cluster.get(\"_nodes\", function( data ) {\n\t\t\t\tclusterNodes = data;\n\t\t\t\tupdateModel.call( self );\n\t\t\t});\n\t\t\tthis.cluster.get(\"_cluster/health\", function( data ) {\n\t\t\t\tclusterHealth = data;\n\t\t\t\tupdateModel.call( self );\n\t\t\t});\n\t\t},\n\t\t_clusterState_handler: function(state) {\n\t\t\tthis.clusterState = state;\n\t\t\tthis.redraw(\"clusterState\");\n\t\t},\n\t\t_status_handler: function(status) {\n\t\t\tthis.status = status;\n\t\t\tthis.redraw(\"status\");\n\t\t},\n\t\t_clusterNodeStats_handler: function(stats) {\n\t\t\tthis.nodeStats = stats;\n\t\t\tthis.redraw(\"nodeStats\");\n\t\t},\n\t\t_clusterNodes_handler: function(nodes) {\n\t\t\tthis.clusterNodes = nodes;\n\t\t\tthis.redraw(\"clusterNodes\");\n\t\t},\n\t\t_clusterHealth_handler: function(health) {\n\t\t\tthis.clusterHealth = health;\n\t\t\tthis.redraw(\"status\");\n\t\t}\n\t});\n\n})( this.app );\n"
  },
  {
    "path": "src/app/services/clusterState/clusterStateSpec.js",
    "content": "describe(\"app.services.ClusterState\", function() {\n\n\tvar ClusterState = window.app.services.ClusterState;\n\tvar test = window.test;\n\n\tvar c;\n\tvar dummyData = {};\n\tvar dataEventCallback;\n\n\tfunction expectAllDataToBeNull() {\n\t\texpect( c.clusterState ).toBe( null );\n\t\texpect( c.status ).toBe( null );\n\t\texpect( c.nodeStats ).toBe( null );\n\t\texpect( c.clusterNodes ).toBe( null );\n\t}\n\n\tbeforeEach( function() {\n\t\ttest.cb.use();\n\t\tdataEventCallback = jasmine.createSpy(\"onData\");\n\t\tc = new ClusterState({\n\t\t\tcluster: {\n\t\t\t\tget: test.cb.createSpy(\"get\", 1, [ dummyData ] )\n\t\t\t},\n\t\t\tonData: dataEventCallback\n\t\t});\n\t});\n\n\tdescribe( \"when it is initialised\", function() {\n\n\t\tit(\"should have null data\", function() {\n\t\t\texpectAllDataToBeNull();\n\t\t});\n\n\t});\n\n\tdescribe( \"when refresh is called\", function() {\n\n\t\tbeforeEach( function() {\n\t\t\tc.refresh();\n\t\t});\n\n\t\tit(\"should not not update models until all network requests have completed\", function() {\t\t\t\n\t\t\ttest.cb.execOne();\n\t\t\texpectAllDataToBeNull();\n\t\t\ttest.cb.execOne();\n\t\t\texpectAllDataToBeNull();\n\t\t\ttest.cb.execOne();\n\t\t\texpectAllDataToBeNull();\n\t\t\ttest.cb.execOne();\n\t\t\texpectAllDataToBeNull();\n\t\t\ttest.cb.execOne();\n\t\t\texpect( c.clusterState ).toBe( dummyData );\n\t\t\texpect( c.status ).toBe( dummyData );\n\t\t\texpect( c.nodeStats ).toBe( dummyData );\n\t\t\texpect( c.clusterNodes ).toBe( dummyData );\n\t\t});\n\n\t\tit(\"should fire a 'data' event when all data is ready\", function() {\n\t\t\ttest.cb.execAll();\n\t\t\texpect( dataEventCallback ).toHaveBeenCalledWith( c );\n\t\t});\n\t});\n\n});\n"
  },
  {
    "path": "src/app/services/preferences/preferenceSpec.js",
    "content": "describe(\"app.services.Preferences\", function(){\n\nvar Preferences = window.app.services.Preferences;\n\n\tvar prefs;\n\n\tbeforeEach( function() {\n\t\tspyOn(window.localStorage, \"getItem\").and.returnValue( '{\"foo\":true}' );\n\t\tspyOn(window.localStorage, \"setItem\");\n\t\tprefs = Preferences.instance();\n\t});\n\n\tit(\"should return a preference from localStorage\", function() {\n\t\texpect( prefs.get(\"foo\") ).toEqual( {foo:true} );\n\t});\n\n\tit(\"should set a preference in localStorage\", function() {\n\t\tprefs.set(\"foo\", { foo: false } );\n\t\texpect( window.localStorage.setItem ).toHaveBeenCalledWith('foo', '{\"foo\":false}');\n\t});\n\n\n});\n"
  },
  {
    "path": "src/app/services/preferences/preferences.js",
    "content": "(function( app ) {\n\t\n\tvar ux = app.ns(\"ux\");\n\tvar services = app.ns(\"services\");\n\n\tservices.Preferences = ux.Singleton.extend({\n\t\tinit: function() {\n\t\t\tthis._storage = window.localStorage;\n\t\t\tthis._setItem(\"__version\", 1 );\n\t\t},\n\t\tget: function( key ) {\n\t\t\treturn this._getItem( key );\n\t\t},\n\t\tset: function( key, val ) {\n\t\t\treturn this._setItem( key, val );\n\t\t},\n\t\t_getItem: function( key ) {\n\t\t\ttry {\n\t\t\t\treturn JSON.parse( this._storage.getItem( key ) );\n\t\t\t} catch(e) {\n\t\t\t\tconsole.warn( e );\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t},\n\t\t_setItem: function( key, val ) {\n\t\t\ttry {\n\t\t\t\treturn this._storage.setItem( key, JSON.stringify( val ) );\n\t\t\t} catch(e) {\n\t\t\t\tconsole.warn( e );\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t}\n\t});\n\n})( this.app );\n"
  },
  {
    "path": "src/app/ui/abstractField/abstractField.css",
    "content": ".require { color: #a00; }\n"
  },
  {
    "path": "src/app/ui/abstractField/abstractField.js",
    "content": "(function( $, app, joey ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.AbstractField = ui.AbstractWidget.extend({\n\n\t\tdefaults: {\n\t\t\tname : \"\",\t\t\t// (required) - name of the field\n\t\t\trequire: false,\t// validation requirements (false, true, regexp, function)\n\t\t\tvalue: \"\",\t\t\t// default value\n\t\t\tlabel: \"\"\t\t\t\t// human readable label of this field\n\t\t},\n\n\t\tinit: function(parent) {\n\t\t\tthis._super();\n\t\t\tthis.el = $.joey(this._main_template());\n\t\t\tthis.field = this.el.find(\"[name=\"+this.config.name+\"]\");\n\t\t\tthis.label = this.config.label;\n\t\t\tthis.require = this.config.require;\n\t\t\tthis.name = this.config.name;\n\t\t\tthis.val( this.config.value );\n\t\t\tthis.attach( parent );\n\t\t},\n\n\t\tval: function( val ) {\n\t\t\tif(val === undefined) {\n\t\t\t\treturn this.field.val();\n\t\t\t} else {\n\t\t\t\tthis.field.val( val );\n\t\t\t\treturn this;\n\t\t\t}\n\t\t},\n\n\t\tvalidate: function() {\n\t\t\tvar val = this.val(), req = this.require;\n\t\t\tif( req === false ) {\n\t\t\t\treturn true;\n\t\t\t} else if( req === true ) {\n\t\t\t\treturn val.length > 0;\n\t\t\t} else if( req.test && $.isFunction(req.test) ) {\n\t\t\t\treturn req.test( val );\n\t\t\t} else if( $.isFunction(req) ) {\n\t\t\t\treturn req( val, this );\n\t\t\t}\n\t\t}\n\n\t});\n\n})( this.jQuery, this.app, this.joey );\n"
  },
  {
    "path": "src/app/ui/abstractPanel/abstractPanel.css",
    "content": "#uiModal {\n\tbackground: black;\n}\n\n.uiPanel {\n\tbox-shadow: -1px 2.5px 4px -3px black, -1px -2.5px 4px -3px black, 3px 2.5px 4px -3px black, 3px -2.5px 4px -3px black;\n\tposition: absolute;\n\tbackground: #eee;\n\tborder: 1px solid #666;\n}\n\n.uiPanel-titleBar {\n\ttext-align: center;\n\tfont-weight: bold;\n\tpadding: 2px 0;\n\tbackground: rgba(223, 223, 223, 0.75);\n\tbackground: -moz-linear-gradient(top, rgba(223, 223, 223, 0.75), rgba(193, 193, 193, 0.75), rgba(223, 223, 223, 0.75));\n\tbackground: -webkit-linear-gradient(top, rgba(223, 223, 223, 0.75), rgba(193, 193, 193, 0.75), rgba(223, 223, 223, 0.75));\n\tborder-bottom: 1px solid #bbb;\n}\n\n.uiPanel-close {\n\tcursor: pointer;\n\tborder: 1px solid #aaa;\n\tbackground: #fff;\n\tcolor: #fff;\n\tfloat: left;\n\theight: 10px;\n\tleft: 3px;\n\tline-height: 9px;\n\tpadding: 1px 0;\n\tposition: relative;\n\ttext-shadow: 0 0 1px #000;\n\ttop: 0px;\n\twidth: 12px;\n}\n.uiPanel-close:hover {\n\tbackground: #eee;\n}\n\n.uiPanel-body {\n\toverflow: auto;\n}\n"
  },
  {
    "path": "src/app/ui/abstractPanel/abstractPanel.js",
    "content": "(function( $, app ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.AbstractPanel = ui.AbstractWidget.extend({\n\t\tdefaults: {\n\t\t\tbody: null,            // initial content of the body\n\t\t\tmodal: true,           // create a modal panel - creates a div that blocks interaction with page\n\t\t\theight: 'auto',        // panel height\n\t\t\twidth: 400,            // panel width (in pixels)\n\t\t\topen: false,           // show the panel when it is created\n\t\t\tparent: 'BODY',        // node that panel is attached to\n\t\t\tautoRemove: false      // remove the panel from the dom and destroy it when the widget is closed\n\t\t},\n\t\tshared: {  // shared data for all instances of ui.Panel and decendants\n\t\t\tstack: [], // array of all open panels\n\t\t\tmodal: $( { tag: \"DIV\", id: \"uiModal\", css: { opacity: 0.2, position: \"absolute\", top: \"0px\", left: \"0px\" } } )\n\t\t},\n\t\tinit: function() {\n\t\t\tthis._super();\n\t\t},\n\t\topen: function( ev ) {\n\t\t\tthis.el\n\t\t\t\t.css( { visibility: \"hidden\" } )\n\t\t\t\t.appendTo( this.config.parent )\n\t\t\t\t.css( this._getPosition( ev ) )\n\t\t\t\t.css( { zIndex: (this.shared.stack.length ? (+this.shared.stack[this.shared.stack.length - 1].el.css(\"zIndex\") + 10) : 100) } )\n\t\t\t\t.css( { visibility: \"visible\", display: \"block\" } );\n\t\t\tthis.shared.stack.remove(this);\n\t\t\tthis.shared.stack.push(this);\n\t\t\tthis._setModal();\n\t\t\t$(document).bind(\"keyup\", this._close_handler );\n\t\t\tthis.fire(\"open\", { source: this, event: ev } );\n\t\t\treturn this;\n\t\t},\n\t\tclose: function() {\n\t\t\tvar index = this.shared.stack.indexOf(this);\n\t\t\tif(index !== -1) {\n\t\t\t\tthis.shared.stack.splice(index, 1);\n\t\t\t\tthis.el.css( { left: \"-2999px\" } ); // move the dialog to the left rather than hiding to prevent ie6 rendering artifacts\n\t\t\t\tthis._setModal();\n\t\t\t\tthis.fire(\"close\", this );\n\t\t\t\tif(this.config.autoRemove) {\n\t\t\t\t\tthis.remove();\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn this;\n\t\t},\n\t\t// close the panel and remove it from the dom, destroying it (you can not reuse the panel after calling remove)\n\t\tremove: function() {\n\t\t\tthis.close();\n\t\t\t$(document).unbind(\"keyup\", this._close_handler );\n\t\t\tthis._super();\n\t\t},\n\t\t// starting at the top of the stack, find the first panel that wants a modal and put it just underneath, otherwise remove the modal\n\t\t_setModal: function() {\n\t\t\tfor(var stackPtr = this.shared.stack.length - 1; stackPtr >= 0; stackPtr--) {\n\t\t\t\tif(this.shared.stack[stackPtr].config.modal) {\n\t\t\t\t\tthis.shared.modal\n\t\t\t\t\t\t.appendTo( document.body )\n\t\t\t\t\t\t.css( { zIndex: this.shared.stack[stackPtr].el.css(\"zIndex\") - 5 } )\n\t\t\t\t\t\t.css( $(document).vSize().asSize() );\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.shared.modal.remove(); // no panels that want a modal were found\n\t\t},\n\t\t_getPosition: function() {\n\t\t\treturn $(window).vSize()                        // get the current viewport size\n\t\t\t\t.sub(this.el.vSize())                         // subtract the size of the panel\n\t\t\t\t.mod(function(s) { return s / 2; })           // divide by 2 (to center it)\n\t\t\t\t.add($(document).vScroll())                   // add the current scroll offset\n\t\t\t\t.mod(function(s) { return Math.max(5, s); })  // make sure the panel is not off the edge of the window\n\t\t\t\t.asOffset();                                  // and return it as a {top, left} object\n\t\t},\n\t\t_close_handler: function( ev ) {\n\t\t\tif( ev.type === \"keyup\" && ev.keyCode !== 27) { return; } // press esc key to close\n\t\t\t$(document).unbind(\"keyup\", this._close_handler);\n\t\t\tthis.close( ev );\n\t\t}\n\t});\n\n})( this.jQuery, this.app );\n"
  },
  {
    "path": "src/app/ui/abstractWidget/abstractWidget.js",
    "content": "(function( $, joey, app ) {\n\n\tvar ui = app.ns(\"ui\");\n\tvar ux = app.ns(\"ux\");\n\n\tui.AbstractWidget = ux.Observable.extend({\n\t\tdefaults : {\n\t\t\tid: null     // the id of the widget\n\t\t},\n\n\t\tel: null,       // this is the jquery wrapped dom element(s) that is the root of the widget\n\n\t\tinit: function() {\n\t\t\tthis._super();\n\t\t\tfor(var prop in this) {       // automatically bind all the event handlers\n\t\t\t\tif(prop.contains(\"_handler\")) {\n\t\t\t\t\tthis[prop] = this[prop].bind(this);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\tid: function(suffix) {\n\t\t\treturn this.config.id ? (this.config.id + (suffix ? \"-\" + suffix : \"\")) : undefined;\n\t\t},\n\n\t\tattach: function( parent, method ) {\n\t\t\tif( parent ) {\n\t\t\t\tthis.el[ method || \"appendTo\"]( parent );\n\t\t\t}\n\t\t\tthis.fire(\"attached\", this );\n\t\t\treturn this;\n\t\t},\n\n\t\tremove: function() {\n\t\t\tif ( this.el !== null ) { this.el.remove(); }\n\t\t\tthis.fire(\"removed\", this );\n\t\t\tthis.removeAllObservers();\n\t\t\tthis.el = null;\n\t\t\treturn this;\n\t\t}\n\t});\n\n\tjoey.plugins.push( function( obj ) {\n\t\tif( obj instanceof ui.AbstractWidget ) {\n\t\t\treturn obj.el[0];\n\t\t}\n\t});\n\n})( this.jQuery, this.joey, this.app );\n"
  },
  {
    "path": "src/app/ui/anyRequest/anyRequest.css",
    "content": ".uiAnyRequest-request {\n\tfloat: left;\n\twidth: 350px;\n\tpadding: 5px;\n\tbackground: #d8e7ff;\n\tbackground: -moz-linear-gradient(left, #d8e7ff, #e8f1ff);\n\tbackground: -webkit-linear-gradient(left, #d8e7ff, #e8f1ff);\n}\n\n.uiAnyRequest-request INPUT[type=text],\n.uiAnyRequest-request TEXTAREA {\n\twidth: 340px;\n}\n\n.anyRequest INPUT[name=path] {\n\twidth: 259px;\n}\n\n.uiAnyRequest-out {\n\tmargin-left: 365px;\n}\n\n.uiAnyRequest-out P {\n\tmargin-top: 0;\n}\n\n.uiAnyRequest-jsonErr {\n\tcolor: red;\n}\n\n.uiAnyRequest-history {\n\tmargin: 0;\n\tpadding: 0;\n\tlist-style: none;\n\tmax-height: 100px;\n\toverflow-x: hidden;\n\toverflow-y: auto;\n}\n"
  },
  {
    "path": "src/app/ui/anyRequest/anyRequest.js",
    "content": "(function( $, app, i18n, raphael ) {\n\n\tvar ui = app.ns(\"ui\");\n\tvar ut = app.ns(\"ut\");\n\tvar services = app.ns(\"services\");\n\n\tui.AnyRequest = ui.Page.extend({\n\t\tdefaults: {\n\t\t\tcluster: null,       // (required) instanceof app.services.Cluster\n\t\t\tpath: \"_search\",     // default uri to send a request to\n\t\t\tquery: { query: { match_all: { }}},\n\t\t\ttransform: \"  return root;\" // default transformer function (does nothing)\n\t\t},\n\t\tinit: function(parent) {\n\t\t\tthis._super();\n\t\t\tthis.prefs = services.Preferences.instance();\n\t\t\tthis.history = this.prefs.get(\"anyRequest-history\") || [ { type: \"POST\", path: this.config.path, query : JSON.stringify(this.config.query), transform: this.config.transform } ];\n\t\t\tthis.el = $.joey(this._main_template());\n\t\t\tthis.base_uriEl = this.el.find(\"INPUT[name=base_uri]\");\n\t\t\tthis.pathEl = this.el.find(\"INPUT[name=path]\");\n\t\t\tthis.typeEl = this.el.find(\"SELECT[name=method]\");\n\t\t\tthis.dataEl = this.el.find(\"TEXTAREA[name=body]\");\n\t\t\tthis.prettyEl = this.el.find(\"INPUT[name=pretty]\");\n\t\t\tthis.transformEl = this.el.find(\"TEXTAREA[name=transform]\");\n\t\t\tthis.asGraphEl = this.el.find(\"INPUT[name=asGraph]\");\n\t\t\tthis.asTableEl = this.el.find(\"INPUT[name=asTable]\");\n\t\t\tthis.asJsonEl = this.el.find(\"INPUT[name=asJson]\");\n\t\t\tthis.cronEl = this.el.find(\"SELECT[name=cron]\");\n\t\t\tthis.outEl = this.el.find(\"DIV.uiAnyRequest-out\");\n\t\t\tthis.errEl = this.el.find(\"DIV.uiAnyRequest-jsonErr\");\n\t\t\tthis.typeEl.val(\"GET\");\n\t\t\tthis.attach(parent);\n\t\t\tthis.setHistoryItem(this.history[this.history.length - 1]);\n\t\t},\n\t\tsetHistoryItem: function(item) {\n\t\t\tthis.pathEl.val(item.path);\n\t\t\tthis.typeEl.val(item.type);\n\t\t\tthis.dataEl.val(item.query);\n\t\t\tthis.transformEl.val(item.transform);\n\t\t},\n\t\t_request_handler: function( ev ) {\n\t\t\tif(! this._validateJson_handler()) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tvar path = this.pathEl.val(),\n\t\t\t\t\ttype = this.typeEl.val(),\n\t\t\t\t\tquery = JSON.stringify(JSON.parse(this.dataEl.val())),\n\t\t\t\t\ttransform = this.transformEl.val(),\n\t\t\t\t\tbase_uri = this.base_uriEl.val();\n\t\t\tif( ev ) { // if the user click request\n\t\t\t\tif(this.timer) {\n\t\t\t\t\twindow.clearTimeout(this.timer); // stop any cron jobs\n\t\t\t\t}\n\t\t\t\tdelete this.prevData; // remove data from previous cron runs\n\t\t\t\tthis.outEl.text(i18n.text(\"AnyRequest.Requesting\"));\n\t\t\t\tif( ! /\\/$/.test( base_uri )) {\n\t\t\t\t\tbase_uri += \"/\";\n\t\t\t\t\tthis.base_uriEl.val( base_uri );\n\t\t\t\t}\n\t\t\t\tfor(var i = 0; i < this.history.length; i++) {\n\t\t\t\t\tif(this.history[i].path === path &&\n\t\t\t\t\t\tthis.history[i].type === type &&\n\t\t\t\t\t\tthis.history[i].query === query &&\n\t\t\t\t\t\tthis.history[i].transform === transform) {\n\t\t\t\t\t\tthis.history.splice(i, 1);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthis.history.push({\n\t\t\t\t\tpath: path,\n\t\t\t\t\ttype: type,\n\t\t\t\t\tquery: query,\n\t\t\t\t\ttransform: transform\n\t\t\t\t});\n\t\t\t\tthis.history.slice(250); // make sure history does not get too large\n\t\t\t\tthis.prefs.set( \"anyRequest-history\", this.history );\n\t\t\t\tthis.el.find(\"UL.uiAnyRequest-history\")\n\t\t\t\t\t.empty()\n\t\t\t\t\t.append($( { tag: \"UL\", children: this.history.map(this._historyItem_template, this) }).children())\n\t\t\t\t\t.children().find(\":last-child\").each(function(i, j) { j.scrollIntoView(false); }).end()\n\t\t\t\t\t.scrollLeft(0);\n\t\t\t}\n\t\t\tif (type === 'GET') { query = null; }\n\t\t\tthis.config.cluster.request({\n\t\t\t\turl: base_uri + path,\n\t\t\t\ttype: type,\n\t\t\t\tdata: query,\n\t\t\t\tsuccess: this._responseWriter_handler,\n\t\t\t\terror: this._responseError_handler\n\t\t\t});\n\t\t},\n\t\t_responseError_handler: function (response) {\n\t\t\tvar obj;\n\t\t\ttry {\n\t\t\t\tobj = JSON.parse(response.responseText);\n\t\t\t\tif (obj) {\n\t\t\t\t\tthis._responseWriter_handler(obj);\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t}\n\t\t},\n\t\t_responseWriter_handler: function(data) {\n\t\t\tthis.outEl.empty();\n\t\t\ttry {\n\t\t\t\tdata = (new Function(\"root\", \"prev\", this.transformEl.val()))(data, this.prevData)\n\t\t\t} catch(e) {\n\t\t\t\tthis.errEl.text(e.message);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif(this.asGraphEl.attr(\"checked\")) {\n\t\t\t\tvar w = this.outEl.width();\n\t\t\t\traphael(this.outEl[0], w - 10, 300)\n\t\t\t\t\t.g.barchart(10, 10, w - 20, 280, [data]);\n\t\t\t}\n\t\t\tif(this.asTableEl.attr(\"checked\")) {\n\t\t\t\ttry {\n\t\t\t\t\tvar store = new app.data.ResultDataSourceInterface();\n\t\t\t\t\tthis.outEl.append(new app.ui.ResultTable({\n\t\t\t\t\t\twidth: this.outEl.width() - 23,\n\t\t\t\t\t\tstore: store\n\t\t\t\t\t} ) );\n\t\t\t\t\tstore.results(data);\n\t\t\t\t} catch(e) {\n\t\t\t\t\tthis.errEl.text(\"Results Table Failed: \" + e.message);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(this.asJsonEl.attr(\"checked\")) {\n\t\t\t\tthis.outEl.append(new ui.JsonPretty({ obj: data }));\n\t\t\t}\n\t\t\tif(this.cronEl.val() > 0) {\n\t\t\t\tthis.timer = window.setTimeout(function(){\n\t\t\t\t\tthis._request_handler();\n\t\t\t\t}.bind(this), this.cronEl.val());\n\t\t\t}\n\t\t\tthis.prevData = data;\n\t\t},\n\t\t_validateJson_handler: function( ev ) {\n\t\t\t/* if the textarea is empty, we replace its value by an empty JSON object : \"{}\" and the request goes on as usual */\n\t\t\tvar jsonData = this.dataEl.val().trim();\n\t\t\tvar j;\n\t\t\tif(jsonData === \"\") {\n\t\t\t\tjsonData = \"{}\";\n\t\t\t\tthis.dataEl.val( jsonData );\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tj = JSON.parse(jsonData);\n\t\t\t} catch(e) {\n\t\t\t\tthis.errEl.text(e.message);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tthis.errEl.text(\"\");\n\t\t\tif(this.prettyEl.attr(\"checked\")) {\n\t\t\t\tthis.dataEl.val(JSON.stringify(j, null, \"  \"));\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\t\t_historyClick_handler: function( ev ) {\n\t\t\tvar item = $( ev.target ).closest( \"LI\" ).data( \"item\" );\n\t\t\tthis.setHistoryItem( item );\n\t\t},\n\t\t_main_template: function() {\n\t\t\treturn { tag: \"DIV\", cls: \"anyRequest\", children: [\n\t\t\t\t{ tag: \"DIV\", cls: \"uiAnyRequest-request\", children: [\n\t\t\t\t\tnew app.ui.SidebarSection({\n\t\t\t\t\t\topen: false,\n\t\t\t\t\t\ttitle: i18n.text(\"AnyRequest.History\"),\n\t\t\t\t\t\tbody: { tag: \"UL\", onclick: this._historyClick_handler, cls: \"uiAnyRequest-history\", children: this.history.map(this._historyItem_template, this)\t}\n\t\t\t\t\t}),\n\t\t\t\t\tnew app.ui.SidebarSection({\n\t\t\t\t\t\topen: true,\n\t\t\t\t\t\ttitle: i18n.text(\"AnyRequest.Query\"),\n\t\t\t\t\t\tbody: { tag: \"DIV\", children: [\n\t\t\t\t\t\t\t{ tag: \"INPUT\", type: \"text\", name: \"base_uri\", value: this.config.cluster.config.base_uri },\n\t\t\t\t\t\t\t{ tag: \"BR\" },\n\t\t\t\t\t\t\t{ tag: \"INPUT\", type: \"text\", name: \"path\", value: this.config.path },\n\t\t\t\t\t\t\t{ tag: \"SELECT\", name: \"method\", children: [\"POST\", \"GET\", \"PUT\", \"HEAD\", \"DELETE\"].map(ut.option_template) },\n\t\t\t\t\t\t\t{ tag: \"TEXTAREA\", name: \"body\", rows: 20, text: JSON.stringify(this.config.query) },\n\t\t\t\t\t\t\t{ tag: \"BUTTON\", css: { cssFloat: \"right\" }, type: \"button\", children: [ { tag: \"B\", text: i18n.text(\"AnyRequest.Request\") } ], onclick: this._request_handler },\n\t\t\t\t\t\t\t{ tag: \"BUTTON\", type: \"button\", text: i18n.text(\"AnyRequest.ValidateJSON\"), onclick: this._validateJson_handler },\n\t\t\t\t\t\t\t{ tag: \"LABEL\", children: [ { tag: \"INPUT\", type: \"checkbox\", name: \"pretty\" }, i18n.text(\"AnyRequest.Pretty\") ] },\n\t\t\t\t\t\t\t{ tag: \"DIV\", cls: \"uiAnyRequest-jsonErr\" }\n\t\t\t\t\t\t]}\n\t\t\t\t\t}),\n\t\t\t\t\tnew app.ui.SidebarSection({\n\t\t\t\t\t\ttitle: i18n.text(\"AnyRequest.Transformer\"),\n\t\t\t\t\t\thelp: \"AnyRequest.TransformerHelp\",\n\t\t\t\t\t\tbody: { tag: \"DIV\", children: [\n\t\t\t\t\t\t\t{ tag: \"CODE\", text: \"function(root, prev) {\" },\n\t\t\t\t\t\t\t{ tag: \"BR\" },\n\t\t\t\t\t\t\t{ tag: \"TEXTAREA\", name: \"transform\", rows: 5, text: this.config.transform },\n\t\t\t\t\t\t\t{ tag: \"BR\" },\n\t\t\t\t\t\t\t{ tag: \"CODE\", text: \"}\" }\n\t\t\t\t\t\t] }\n\t\t\t\t\t}),\n\t\t\t\t\tnew app.ui.SidebarSection({\n\t\t\t\t\t\ttitle: i18n.text(\"AnyRequest.RepeatRequest\"),\n\t\t\t\t\t\tbody: { tag: \"DIV\", children: [\n\t\t\t\t\t\t\ti18n.text(\"AnyRequest.RepeatRequestSelect\"), \" \",\n\t\t\t\t\t\t\t{ tag: \"SELECT\", name: \"cron\", children: [\n\t\t\t\t\t\t\t\t{ value: 0, text: \"do not repeat\" },\n\t\t\t\t\t\t\t\t{ value: 1000, text: \"second\" },\n\t\t\t\t\t\t\t\t{ value: 1000 * 2, text: \"2 seconds\" },\n\t\t\t\t\t\t\t\t{ value: 1000 * 5, text: \"5 seconds\" },\n\t\t\t\t\t\t\t\t{ value: 1000 * 20, text: \"20 seconds\" },\n\t\t\t\t\t\t\t\t{ value: 1000 * 60, text: \"minute\" },\n\t\t\t\t\t\t\t\t{ value: 1000 * 60 * 10, text: \"10 minutes\" },\n\t\t\t\t\t\t\t\t{ value: 1000 * 60 * 60, text: \"hour\" }\n\t\t\t\t\t\t\t].map(function(op) { return $.extend({ tag: \"OPTION\"}, op); }) }\n\t\t\t\t\t\t] }\n\t\t\t\t\t}),\n\t\t\t\t\tnew app.ui.SidebarSection({\n\t\t\t\t\t\ttitle: i18n.text(\"AnyRequest.DisplayOptions\"),\n\t\t\t\t\t\thelp: \"AnyRequest.DisplayOptionsHelp\",\n\t\t\t\t\t\tbody: { tag: \"DIV\", children: [\n\t\t\t\t\t\t\t{ tag: \"LABEL\", children: [ { tag: \"INPUT\", type: \"checkbox\", checked: true, name: \"asJson\" }, i18n.text(\"AnyRequest.AsJson\") ] },\n\t\t\t\t\t\t\t{ tag: \"BR\" },\n\t\t\t\t\t\t\t{ tag: \"LABEL\", children: [ { tag: \"INPUT\", type: \"checkbox\", name: \"asGraph\" }, i18n.text(\"AnyRequest.AsGraph\") ] },\n\t\t\t\t\t\t\t{ tag: \"BR\" },\n\t\t\t\t\t\t\t{ tag: \"LABEL\", children: [ { tag: \"INPUT\", type: \"checkbox\", name: \"asTable\" }, i18n.text(\"AnyRequest.AsTable\") ] }\n\t\t\t\t\t\t] }\n\t\t\t\t\t})\n\t\t\t\t] },\n\t\t\t\t{ tag: \"DIV\", cls: \"uiAnyRequest-out\" }\n\t\t\t] };\n\t\t},\n\t\t_historyItem_template: function(item) {\n\t\t\treturn { tag: \"LI\", cls: \"booble\", data: { item: item }, children: [\n\t\t\t\t{ tag: \"SPAN\", text: item.path },\n\t\t\t\t\" \",\n\t\t\t\t{ tag: \"EM\", text: item.query },\n\t\t\t\t\" \",\n\t\t\t\t{ tag: \"SPAN\", text: item.transform }\n\t\t\t] };\n\t\t}\n\t});\n\t\n})( this.jQuery, this.app, this.i18n, this.Raphael );\n"
  },
  {
    "path": "src/app/ui/browser/browser.css",
    "content": ".uiBrowser-filter {\n\tfloat: left;\n}\n\n.uiBrowser-table {\n\tmargin-left: 365px;\n}\n"
  },
  {
    "path": "src/app/ui/browser/browser.js",
    "content": "(function( $, app, i18n ){\n\n\tvar ui = app.ns(\"ui\");\n\tvar data = app.ns(\"data\");\n\n\tui.Browser = ui.Page.extend({\n\t\tdefaults: {\n\t\t\tcluster: null  // (required) instanceof app.services.Cluster\n\t\t},\n\t\tinit: function() {\n\t\t\tthis._super();\n\t\t\tthis.cluster = this.config.cluster;\n\t\t\tthis.query = new app.data.Query( { cluster: this.cluster } );\n\t\t\tthis._refreshButton = new ui.Button({\n\t\t\t\tlabel: i18n.text(\"General.RefreshResults\"),\n\t\t\t\tonclick: function( btn ) {\n\t\t\t\t\tthis.query.query();\n\t\t\t\t}.bind(this)\n\t\t\t});\n\t\t\tthis.el = $(this._main_template());\n\t\t\tnew data.MetaDataFactory({\n\t\t\t\tcluster: this.cluster,\n\t\t\t\tonReady: function(metadata) {\n\t\t\t\t\tthis.metadata = metadata;\n\t\t\t\t\tthis.store = new data.QueryDataSourceInterface( { metadata: metadata, query: this.query } );\n\t\t\t\t\tthis.queryFilter = new ui.QueryFilter({ metadata: metadata, query: this.query });\n\t\t\t\t\tthis.queryFilter.attach(this.el.find(\"> .uiBrowser-filter\") );\n\t\t\t\t\tthis.resultTable = new ui.ResultTable( {\n\t\t\t\t\t\tonHeaderClick: this._changeSort_handler,\n\t\t\t\t\t\tstore: this.store\n\t\t\t\t\t} );\n\t\t\t\t\tthis.resultTable.attach( this.el.find(\"> .uiBrowser-table\") );\n\t\t\t\t\tthis.updateResults();\n\t\t\t\t}.bind(this)\n\t\t\t});\n\t\t},\n\t\tupdateResults: function() {\n\t\t\tthis.query.query();\n\t\t},\n\t\t_changeSort_handler: function(table, wEv) {\n\t\t\tthis.query.setSort(wEv.column, wEv.dir === \"desc\");\n\t\t\tthis.query.setPage(1);\n\t\t\tthis.query.query();\n\t\t},\n\t\t_main_template: function() {\n\t\t\treturn { tag: \"DIV\", cls: \"uiBrowser\", children: [\n\t\t\t\tnew ui.Toolbar({\n\t\t\t\t\tlabel: i18n.text(\"Browser.Title\"),\n\t\t\t\t\tleft: [ ],\n\t\t\t\t\tright: [ this._refreshButton ]\n\t\t\t\t}),\n\t\t\t\t{ tag: \"DIV\", cls: \"uiBrowser-filter\" },\n\t\t\t\t{ tag: \"DIV\", cls: \"uiBrowser-table\" }\n\t\t\t] };\n\t\t}\n\t});\n\n})( this.jQuery, this.app, this.i18n );\n"
  },
  {
    "path": "src/app/ui/button/button.css",
    "content": ".uiButton {\n\tpadding: 0;\n\tborder: 0;\n\tmargin: 3px;\n\twidth: auto;\n\toverflow: visible;\n\tcursor: pointer;\n\tbackground: transparent;\n}\n\n.uiButton-content {\n\theight: 20px;\n\tborder: 1px solid #668dc6;\n\tborder-radius: 2px;\n\tbackground: #96c6eb;\n\tbackground: -moz-linear-gradient(top, #96c6eb, #5296c7);\n\tbackground: -webkit-linear-gradient(top, #96c6eb, #5296c7);\n\tcolor: white;\n\tfont-weight: bold;\n}\n\n.moz .uiButton-content { margin: 0 -2px; }\n\n.uiButton-label {\n\t\tpadding: 2px 6px;\n\t\twhite-space: nowrap;\n}\n.uiButton:hover .uiButton-content {\n\tbackground: #2777ba;\n\tbackground: -moz-linear-gradient(top, #6aaadf, #2777ba);\n\tbackground: -webkit-linear-gradient(top, #6aaadf, #2777ba);\n}\n.uiButton.active .uiButton-content,\n.uiButton:active .uiButton-content {\n\tbackground: #2575b7;\n\tbackground: -moz-linear-gradient(top, #2576b8, #2575b7);\n\tbackground: -webkit-linear-gradient(top, #2576b8, #2575b7);\n}\n.uiButton.disabled .uiButton-content,\n.uiButton.disabled:active .uiButton-content {\n\t\tborder-color: #c6c6c6;\n\t\tcolor: #999999;\n\t\tbackground: #ddd;\n\t\tbackground: -moz-linear-gradient(top, #ddd, #ddd);\n\t\tbackground: -webkit-linear-gradient(top, #ddd, #ddd);\n}\n\n.uiButton.disabled {\n\t\tcursor: default;\n}\n"
  },
  {
    "path": "src/app/ui/button/button.js",
    "content": "(function( $, joey, app ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.Button = ui.AbstractWidget.extend({\n\t\tdefaults : {\n\t\t\tlabel: \"\",                 // the label text\n\t\t\tdisabled: false,           // create a disabled button\n\t\t\tautoDisable: false         // automatically disable the button when clicked\n\t\t},\n\n\t\t_baseCls: \"uiButton\",\n\n\t\tinit: function(parent) {\n\t\t\tthis._super();\n\t\t\tthis.el = $.joey(this.button_template())\n\t\t\t\t.bind(\"click\", this.click_handler);\n\t\t\tthis.config.disabled && this.disable();\n\t\t\tthis.attach( parent );\n\t\t},\n\n\t\tclick_handler: function(jEv) {\n\t\t\tif(! this.disabled) {\n\t\t\t\tthis.fire(\"click\", jEv, this);\n\t\t\t\tthis.config.autoDisable && this.disable();\n\t\t\t}\n\t\t},\n\n\t\tenable: function() {\n\t\t\tthis.el.removeClass(\"disabled\");\n\t\t\tthis.disabled = false;\n\t\t\treturn this;\n\t\t},\n\n\t\tdisable: function(disable) {\n\t\t\tif(disable === false) {\n\t\t\t\t\treturn this.enable();\n\t\t\t}\n\t\t\tthis.el.addClass(\"disabled\");\n\t\t\tthis.disabled = true;\n\t\t\treturn this;\n\t\t},\n\n\t\tbutton_template: function() { return (\n\t\t\t{ tag: 'BUTTON', type: 'button', id: this.id(), cls: this._baseCls, children: [\n\t\t\t\t{ tag: 'DIV', cls: 'uiButton-content', children: [\n\t\t\t\t\t{ tag: 'DIV', cls: 'uiButton-label', text: this.config.label }\n\t\t\t\t] }\n\t\t\t] }\n\t\t); }\n\t});\n\n})( this.jQuery, this.joey, this.app );\n"
  },
  {
    "path": "src/app/ui/button/buttonDemo.js",
    "content": "$( function() {\n\n\tvar ui = window.app.ns(\"ui\");\n\n\twindow.builder = function() {\n\t\treturn new ui.Button({\tlabel: \"Default\" });\n\t}\t;\n\n});"
  },
  {
    "path": "src/app/ui/checkField/checkField.js",
    "content": "(function( app ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.CheckField = ui.AbstractField.extend({\n\t\t_main_template: function() { return (\n\t\t\t{ tag: \"DIV\", id: this.id(), cls: \"uiCheckField\", children: [\n\t\t\t\t{ tag: \"INPUT\", type: \"checkbox\", name: this.config.name, checked: !!this.config.value }\n\t\t\t] }\n\t\t); },\n\t\tvalidate: function() {\n\t\t\treturn this.val() || ( ! this.require );\n\t\t},\n\t\tval: function( val ) {\n\t\t\tif( val === undefined ) {\n\t\t\t\treturn !!this.field.attr( \"checked\" );\n\t\t\t} else {\n\t\t\t\tthis.field.attr( \"checked\", !!val );\n\t\t\t}\n\t\t}\n\t});\n\n})( this.app );\n\n\n"
  },
  {
    "path": "src/app/ui/checkField/checkFieldDemo.js",
    "content": "$( function() {\n\n\tvar ui = window.app.ns(\"ui\");\n\tvar ux = window.app.ns(\"ux\");\n\tvar ut = window.app.ns(\"ut\");\n\n\twindow.builder = function() {\n\t\tvar form = new ux.FieldCollection({\n\t\t\tfields: [\n\t\t\t\tnew ui.CheckField({\n\t\t\t\t\tlabel: \"default\",\n\t\t\t\t\tname: \"check_default\"\n\t\t\t\t}),\n\t\t\t\tnew ui.CheckField({\n\t\t\t\t\tlabel: \"checked\",\n\t\t\t\t\tname: \"check_true\",\n\t\t\t\t\tvalue: true\n\t\t\t\t}),\n\t\t\t\tnew ui.CheckField({\n\t\t\t\t\tlabel: \"unchecked\",\n\t\t\t\t\tname: \"check_false\",\n\t\t\t\t\tvalue: false\n\t\t\t\t}),\n\t\t\t\tnew ui.CheckField({\n\t\t\t\t\tlabel: \"required\",\n\t\t\t\t\tname: \"check_required\",\n\t\t\t\t\trequire: true\n\t\t\t\t})\n\t\t\t]\n\t\t});\n\n\t\treturn (\n\t\t\t{ tag: \"DIV\", children: form.fields.map( function( field ) {\n\t\t\t\treturn { tag: \"LABEL\", cls: \"uiPanelForm-field\", children: [\n\t\t\t\t\t{ tag: \"DIV\", cls: \"uiPanelForm-label\", children: [ field.label, ut.require_template(field) ] },\n\t\t\t\t\tfield\n\t\t\t\t]};\n\t\t\t}).concat( new ui.Button({\n\t\t\t\tlabel: \"Evaluate Form\",\n\t\t\t\tonclick: function() { console.log( \"valid=\" + form.validate(), form.getData() ); }\n\t\t\t})) }\n\t\t);\n\t};\n\n});"
  },
  {
    "path": "src/app/ui/checkField/checkFieldSpec.js",
    "content": "describe(\"app.ui.CheckField\", function() {\n\n\tvar CheckField = window.app.ui.CheckField;\n\n\tit(\"should have a label\", function() {\n\t\texpect( ( new CheckField({ label: \"foo\" }) ).label ).toBe( \"foo\" );\n\t});\n\n\tit(\"should have a name\", function() {\n\t\texpect( ( new CheckField({ name: \"foo\" }) ).name ).toBe( \"foo\" );\n\t});\n\n\tit(\"should have a val that is false when then field is not checked\", function() {\n\t\texpect( ( new CheckField({ name: \"foo\", value: false }) ).val() ).toBe( false );\n\t});\n\n\tit(\"should have a val that is true when the field is checked\", function() {\n\t\texpect( ( new CheckField({ name: \"foo\", value: true }) ).val() ).toBe( true );\n\t});\n\n\tit(\"should be valid if the field value is true\", function() {\n\t\texpect( ( new CheckField({ name: \"foo\", value: true }) ).validate() ).toBe( true );\n\t});\n\n\tit(\"should be valid if require is false\", function() {\n\t\texpect( ( new CheckField({ name: \"foo\", require: false, value: true }) ).validate() ).toBe( true );\n\t\texpect( ( new CheckField({ name: \"foo\", require: false, value: false }) ).validate() ).toBe( true );\n\t});\n\n\tit(\"should be invalid if require is true and value is false\", function() {\n\t\texpect( ( new CheckField({ name: \"foo\", require: true, value: false }) ).validate() ).toBe( false );\n\t});\n\n});"
  },
  {
    "path": "src/app/ui/clusterConnect/clusterConnect.css",
    "content": ".uiClusterConnect-uri {\n\twidth: 280px;\n}\n"
  },
  {
    "path": "src/app/ui/clusterConnect/clusterConnect.js",
    "content": "(function( $, app, i18n ) {\n\n\tvar ui = app.ns(\"ui\");\n\tvar services = app.ns(\"services\");\n\n\tui.ClusterConnect = ui.AbstractWidget.extend({\n\t\tdefaults: {\n\t\t\tcluster: null\n\t\t},\n\t\tinit: function() {\n\t\t\tthis._super();\n\t\t\tthis.prefs = services.Preferences.instance();\n\t\t\tthis.cluster = this.config.cluster;\n\t\t\tthis.el = $.joey(this._main_template());\n\t\t\tthis.cluster.get( \"\", this._node_handler );\n\t\t},\n\n\t\t_node_handler: function(data) {\n\t\t\tif(data) {\n\t\t\t\tthis.prefs.set(\"app-base_uri\", this.cluster.base_uri);\n\t\t\t\tif(data.version && data.version.number)\n\t\t\t\t\tthis.cluster.setVersion(data.version.number);\n\t\t\t}\n\t\t},\n\n\t\t_reconnect_handler: function() {\n\t\t\tvar base_uri = this.el.find(\".uiClusterConnect-uri\").val();\n\t\t\tvar url;\n\t\t\tif(base_uri.indexOf(\"?\") !== -1) {\n\t\t\t\turl = base_uri.substring(0, base_uri.indexOf(\"?\")-1);\n\t\t\t} else {\n\t\t\t\turl = base_uri;\n\t\t\t}\n\t\t\tvar argstr = base_uri.substring(base_uri.indexOf(\"?\")+1, base_uri.length);\n\t\t\tvar args = argstr.split(\"&\").reduce(function(r, p) {\n\t\t\t\tr[decodeURIComponent(p.split(\"=\")[0])] = decodeURIComponent(p.split(\"=\")[1]);\n\t\t\t\treturn r;\n\t\t\t}, {});\n\t\t\t$(\"body\").empty().append(new app.App(\"body\", { id: \"es\",\n\t\t\t\tbase_uri: url,\n\t\t\t \tauth_user : args[\"auth_user\"] || \"\",\n\t\t\t \tauth_password : args[\"auth_password\"] || \"\"\n\t\t\t}));\n\t\t},\n\n\t\t_main_template: function() {\n\t\t\treturn { tag: \"SPAN\", cls: \"uiClusterConnect\", children: [\n\t\t\t\t{ tag: \"INPUT\", type: \"text\", cls: \"uiClusterConnect-uri\", onkeyup: function( ev ) {\n\t\t\t\t\tif(ev.which === 13) {\n\t\t\t\t\t\tev.preventDefault();\n\t\t\t\t\t\tthis._reconnect_handler();\n\t\t\t\t\t}\n\t\t\t\t}.bind(this), id: this.id(\"baseUri\"), value: this.cluster.base_uri },\n\t\t\t\t{ tag: \"BUTTON\", type: \"button\", text: i18n.text(\"Header.Connect\"), onclick: this._reconnect_handler }\n\t\t\t]};\n\t\t}\n\t});\n\n})( this.jQuery, this.app, this.i18n );\n\n"
  },
  {
    "path": "src/app/ui/clusterConnect/clusterConnectSpec.js",
    "content": "describe(\"clusterConnect\", function() {\n\n\tvar ClusterConnect = window.app.ui.ClusterConnect;\n\n\tdescribe(\"when created\", function() {\n\n\t\tvar prefs, success_callback, cluster, clusterConnect;\n\n\t\tbeforeEach( function() {\n\t\t\tprefs = {\n\t\t\t\tset: jasmine.createSpy(\"set\")\n\t\t\t};\n\t\t\tspyOn( window.app.services.Preferences, \"instance\" ).and.callFake( function() {\n\t\t\t\treturn prefs;\n\t\t\t});\n\t\t\tcluster = {\n\t\t\t\tget: jasmine.createSpy(\"get\").and.callFake( function(uri, success) {\n\t\t\t\t\tsuccess_callback = success;\n\t\t\t\t})\n\t\t\t};\n\t\t\tclusterConnect = new ClusterConnect({\n\t\t\t\tbase_uri: \"http://localhost:9200\",\n\t\t\t\tcluster: cluster\n\t\t\t});\n\t\t});\n\n\t\tit(\"should test the connection to the cluster\", function() {\n\t\t\texpect( cluster.get ).toHaveBeenCalled();\n\t\t});\n\n\t\tit(\"should store successful connection in preferences\", function() {\n\t\t\tsuccess_callback(\"fakePayload\");\n\t\t\texpect( prefs.set ).toHaveBeenCalled();\n\t\t});\n\n\t});\n\n});\n"
  },
  {
    "path": "src/app/ui/clusterOverview/clusterOverview.css",
    "content": ""
  },
  {
    "path": "src/app/ui/clusterOverview/clusterOverview.js",
    "content": "(function( $, app, i18n ) {\n\n\tvar ui = app.ns(\"ui\");\n\tvar services = app.ns(\"services\");\n\n\t// ( master ) master = true, data = true \n\t// ( coordinator ) master = true, data = false\n\t// ( worker ) master = false, data = true;\n\t// ( client ) master = false, data = false;\n\t// http enabled ?\n\n\tfunction nodeSort_name(a, b) {\n\t\tif (!(a.cluster && b.cluster)) {\n\t\t\treturn 0;\n\t\t}\n\t\treturn a.cluster.name.toString().localeCompare( b.cluster.name.toString() );\n\t}\n\n\tfunction nodeSort_addr( a, b ) {\n\t\tif (!a.cluster.transport_address) {\n\t\t\treturn -1;\n\t\t}\n\t\tif (!b.cluster.transport_address) {\n\t\t\treturn 1;\n\t\t}\n\t\tif (!(a.cluster && b.cluster)) {\n\t\t\treturn 0;\n\t\t}\n\t\treturn a.cluster.transport_address.toString().localeCompare( b.cluster.transport_address.toString() );\n\t}\n\n\tfunction nodeSort_type( a, b ) {\n\t\tif (!(a.cluster && b.cluster)) {\n\t\t\treturn 0;\n\t\t}\n\t\tif( a.master_node ) {\n\t\t\treturn -1;\n\t\t} else if( b.master_node ) {\n\t\t\treturn 1;\n\t\t} else if( a.data_node && !b.data_node ) {\n\t\t\treturn -1;\n\t\t} else if( b.data_node && !a.data_node ) {\n\t\t\treturn 1;\n\t\t} else {\n\t\t\treturn a.cluster.name.toString().localeCompare( b.cluster.name.toString() );\n\t\t}\n\t}\n\n\tvar NODE_SORT_TYPES = {\n\t\t\"Sort.ByName\": nodeSort_name,\n\t\t\"Sort.ByAddress\": nodeSort_addr,\n\t\t\"Sort.ByType\": nodeSort_type\n\t};\n\n\tfunction nodeFilter_none( a ) {\n\t\treturn true;\n\t}\n\n\tfunction nodeFilter_clients( a ) {\n\t\treturn (a.master_node || a.data_node );\n\t}\n\n\n\tui.ClusterOverview = ui.Page.extend({\n\t\tdefaults: {\n\t\t\tcluster: null // (reqired) an instanceof app.services.Cluster\n\t\t},\n\t\tinit: function() {\n\t\t\tthis._super();\n\t\t\tthis.cluster = this.config.cluster;\n\t\t\tthis.prefs = services.Preferences.instance();\n\t\t\tthis._clusterState = this.config.clusterState;\n\t\t\tthis._clusterState.on(\"data\", this.draw_handler );\n\t\t\tthis._refreshButton = new ui.RefreshButton({\n\t\t\t\tonRefresh: this.refresh.bind(this),\n\t\t\t\tonChange: function( btn ) {\n\t\t\t\t\tif( btn.value === -1 ) {\n\t\t\t\t\t\tthis.draw_handler();\n\t\t\t\t\t}\n\t\t\t\t}.bind( this )\n\t\t\t});\n\t\t\tvar nodeSortPref = this.prefs.get(\"clusterOverview-nodeSort\") || Object.keys(NODE_SORT_TYPES)[0];\n\t\t\tthis._nodeSort = NODE_SORT_TYPES[ nodeSortPref ];\n\t\t\tthis._nodeSortMenu = new ui.MenuButton({\n\t\t\t\tlabel: i18n.text( \"Preference.SortCluster\" ),\n\t\t\t\tmenu: new ui.SelectMenuPanel({\n\t\t\t\t\tvalue: nodeSortPref,\n\t\t\t\t\titems: Object.keys( NODE_SORT_TYPES ).map( function( k ) {\n\t\t\t\t\t\treturn { text: i18n.text( k ), value: k };\n\t\t\t\t\t}),\n\t\t\t\t\tonSelect: function( panel, event ) {\n\t\t\t\t\t\tthis._nodeSort = NODE_SORT_TYPES[ event.value ];\n\t\t\t\t\t\tthis.prefs.set(\"clusterOverview-nodeSort\", event.value );\n\t\t\t\t\t\tthis.draw_handler();\n\t\t\t\t\t}.bind(this)\n\t\t\t\t})\n\t\t\t});\n\t\t\tthis._indicesSort = this.prefs.get( \"clusterOverview-indicesSort\") || \"desc\";\n\t\t\tthis._indicesSortMenu = new ui.MenuButton({\n\t\t\t\tlabel: i18n.text( \"Preference.SortIndices\" ),\n\t\t\t\tmenu: new ui.SelectMenuPanel({\n\t\t\t\t\tvalue: this._indicesSort,\n\t\t\t\t\titems: [\n\t\t\t\t\t\t{ value: \"desc\", text: i18n.text( \"SortIndices.Descending\" ) },\n\t\t\t\t\t\t{ value: \"asc\", text: i18n.text( \"SortIndices.Ascending\" ) } ],\n\t\t\t\t\tonSelect: function( panel, event ) {\n\t\t\t\t\t\tthis._indicesSort = event.value;\n\t\t\t\t\t\tthis.prefs.set( \"clusterOverview-indicesSort\", this._indicesSort );\n\t\t\t\t\t\tthis.draw_handler();\n\t\t\t\t\t}.bind(this)\n\t\t\t\t})\n\t\t\t});\n\t\t\tthis._aliasRenderer = this.prefs.get( \"clusterOverview-aliasRender\" ) || \"full\";\n\t\t\tthis._aliasMenu = new ui.MenuButton({\n\t\t\t\tlabel: i18n.text( \"Preference.ViewAliases\" ),\n\t\t\t\tmenu: new ui.SelectMenuPanel({\n\t\t\t\t\tvalue: this._aliasRenderer,\n\t\t\t\t\titems: [\n\t\t\t\t\t\t{ value: \"full\", text: i18n.text( \"ViewAliases.Grouped\" ) },\n\t\t\t\t\t\t{ value: \"list\", text: i18n.text( \"ViewAliases.List\" ) },\n\t\t\t\t\t\t{ value: \"none\", text: i18n.text( \"ViewAliases.None\" ) } ],\n\t\t\t\t\tonSelect: function( panel, event ) {\n\t\t\t\t\t\tthis._aliasRenderer = event.value;\n\t\t\t\t\t\tthis.prefs.set( \"clusterOverview-aliasRender\", this._aliasRenderer );\n\t\t\t\t\t\tthis.draw_handler();\n\t\t\t\t\t}.bind(this)\n\t\t\t\t})\n\t\t\t});\n\t\t\tthis._indexFilter = new ui.TextField({\n\t\t\t\tvalue: this.prefs.get(\"clusterOverview-indexFilter\"),\n\t\t\t\tplaceholder: i18n.text( \"Overview.IndexFilter\" ),\n\t\t\t\tonchange: function( indexFilter ) {\n\t\t\t\t\tthis.prefs.set(\"clusterOverview-indexFilter\", indexFilter.val() );\n\t\t\t\t\tthis.draw_handler();\n\t\t\t\t}.bind(this)\n\t\t\t});\n\t\t\tthis.el = $(this._main_template());\n\t\t\tthis.tablEl = this.el.find(\".uiClusterOverview-table\");\n\t\t\tthis.refresh();\n\t\t},\n\t\tremove: function() {\n\t\t\tthis._clusterState.removeObserver( \"data\", this.draw_handler );\n\t\t},\n\t\trefresh: function() {\n\t\t\tthis._refreshButton.disable();\n\t\t\tthis._clusterState.refresh();\n\t\t},\n\t\tdraw_handler: function() {\n\t\t\tvar data = this._clusterState;\n\t\t\tvar indexFilter;\n\t\t\ttry {\n\t\t\t\tvar indexFilterRe = new RegExp( this._indexFilter.val() );\n\t\t\t\tindexFilter = function(s) { return indexFilterRe.test(s); };\n\t\t\t} catch(e) {\n\t\t\t\tindexFilter = function() { return true; };\n\t\t\t}\n\t\t\tvar clusterState = data.clusterState;\n\t\t\tvar status = data.status;\n\t\t\tvar nodeStats = data.nodeStats;\n\t\t\tvar clusterNodes = data.clusterNodes;\n\t\t\tvar nodes = [];\n\t\t\tvar indices = [];\n\t\t\tvar cluster = {};\n\t\t\tvar nodeIndices = {};\n\t\t\tvar indexIndices = {}, indexIndicesIndex = 0;\n\t\t\tfunction newNode(n) {\n\t\t\t\treturn {\n\t\t\t\t\tname: n,\n\t\t\t\t\troutings: [],\n\t\t\t\t\tmaster_node: clusterState.master_node === n\n\t\t\t\t};\n\t\t\t}\n\t\t\tfunction newIndex(i) {\n\t\t\t\treturn {\n\t\t\t\t\tname: i,\n\t\t\t\t\treplicas: []\n\t\t\t\t};\n\t\t\t}\n\t\t\tfunction getIndexForNode(n) {\n\t\t\t\treturn nodeIndices[n] = (n in nodeIndices) ? nodeIndices[n] : nodes.push(newNode(n)) - 1;\n\t\t\t}\n\t\t\tfunction getIndexForIndex(routings, i) {\n\t\t\t\tvar index = indexIndices[i] = (i in indexIndices) ?\n\t\t\t\t\t\t(routings[indexIndices[i]] = routings[indexIndices[i]] || newIndex(i)) && indexIndices[i]\n\t\t\t\t\t\t: ( ( routings[indexIndicesIndex] = newIndex(i) )  && indexIndicesIndex++ );\n\t\t\t\tindices[index] = i;\n\t\t\t\treturn index;\n\t\t\t}\n\t\t\t$.each(clusterNodes.nodes, function(name, node) {\n\t\t\t\tgetIndexForNode(name);\n\t\t\t});\n\n\t\t\tvar indexNames = [];\n\t\t\t$.each(clusterState.routing_table.indices, function(name, index){\n\t\t\t\tindexNames.push(name);\n\t\t\t});\n\t\t\tindexNames.sort();\n\t\t\tif (this._indicesSort === \"desc\") indexNames.reverse();\n\t\t\tindexNames.filter( indexFilter ).forEach(function(name) {\n\t\t\t\tvar indexObject = clusterState.routing_table.indices[name];\n\t\t\t\t$.each(indexObject.shards, function(name, shard) {\n\t\t\t\t\tshard.forEach(function(replica){\n\t\t\t\t\t\tvar node = replica.node;\n\t\t\t\t\t\tif(node === null) { node = \"Unassigned\"; }\n\t\t\t\t\t\tvar index = replica.index;\n\t\t\t\t\t\tvar shard = replica.shard;\n\t\t\t\t\t\tvar routings = nodes[getIndexForNode(node)].routings;\n\t\t\t\t\t\tvar indexIndex = getIndexForIndex(routings, index);\n\t\t\t\t\t\tvar replicas = routings[indexIndex].replicas;\n\t\t\t\t\t\tif(node === \"Unassigned\" || !indexObject.shards[shard]) {\n\t\t\t\t\t\t\treplicas.push({ replica: replica });\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treplicas[shard] = {\n\t\t\t\t\t\t\t\treplica: replica,\n\t\t\t\t\t\t\t\tstatus: indexObject.shards[shard].filter(function(replica) {\n\t\t\t\t\t\t\t\t\treturn replica.node === node;\n\t\t\t\t\t\t\t\t})[0]\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\t\t\tindices = indices.map(function(index){\n\t\t\t\treturn {\n\t\t\t\t\tname: index,\n\t\t\t\t\tstate: \"open\",\n\t\t\t\t\tmetadata: clusterState.metadata.indices[index],\n\t\t\t\t\tstatus: status.indices[index]\n\t\t\t\t};\n\t\t\t}, this);\n\t\t\t$.each(clusterState.metadata.indices, function(name, index) {\n\t\t\t\tif(index.state === \"close\" && indexFilter( name )) {\n\t\t\t\t\tindices.push({\n\t\t\t\t\t\tname: name,\n\t\t\t\t\t\tstate: \"close\",\n\t\t\t\t\t\tmetadata: index,\n\t\t\t\t\t\tstatus: null\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\t\t\tnodes.forEach(function(node) {\n\t\t\t\tnode.stats = nodeStats.nodes[node.name];\n\t\t\t\tvar cluster = clusterNodes.nodes[node.name];\n\t\t\t\tnode.cluster = cluster || { name: \"<unknown>\" };\n\t\t\t\tnode.data_node = !( cluster && cluster.attributes && cluster.attributes.data === \"false\" );\n\t\t\t\tfor(var i = 0; i < indices.length; i++) {\n\t\t\t\t\tnode.routings[i] = node.routings[i] || { name: indices[i].name, replicas: [] };\n\t\t\t\t\tif (indices[i].metadata.settings) {\n\t\t\t\t\t\tnode.routings[i].max_number_of_shards = indices[i].metadata.settings[\"index.number_of_shards\"];\n\t\t\t\t\t}\n\t\t\t\t\tnode.routings[i].open = indices[i].state === \"open\";\n\t\t\t\t}\n\t\t\t});\n\t\t\tvar aliasesIndex = {};\n\t\t\tvar aliases = [];\n\t\t\tvar indexClone = indices.map(function() { return false; });\n\t\t\t$.each(clusterState.metadata.indices, function(name, index) {\n\t\t\t\tindex.aliases.forEach(function(alias) {\n\t\t\t\t\tvar aliasIndex = aliasesIndex[alias] = (alias in aliasesIndex) ? aliasesIndex[alias] : aliases.push( { name: alias, max: -1, min: 999, indices: [].concat(indexClone) }) - 1;\n\t\t\t\t\tvar indexIndex = indexIndices[name];\n\t\t\t\t\tvar aliasRow = aliases[aliasIndex];\n\t\t\t\t\taliasRow.min = Math.min(aliasRow.min, indexIndex);\n\t\t\t\t\taliasRow.max = Math.max(aliasRow.max, indexIndex);\n\t\t\t\t\taliasRow.indices[indexIndex] = indices[indexIndex];\n\t\t\t\t});\n\t\t\t});\n\t\t\tcluster.aliases = aliases;\n\t\t\tcluster.nodes = nodes\n\t\t\t\t.filter( nodeFilter_none )\n\t\t\t\t.sort( this._nodeSort );\n\t\t\tindices.unshift({ name: null });\n\t\t\tthis._drawNodesView( cluster, indices );\n\t\t\tthis._refreshButton.enable();\n\t\t},\n\t\t_drawNodesView: function( cluster, indices ) {\n\t\t\tthis._nodesView && this._nodesView.remove();\n\t\t\tthis._nodesView = new ui.NodesView({\n\t\t\t\tonRedraw: function() {\n\t\t\t\t\tthis.refresh();\n\t\t\t\t}.bind(this),\n\t\t\t\tinteractive: ( this._refreshButton.value === -1 ),\n\t\t\t\taliasRenderer: this._aliasRenderer,\n\t\t\t\tcluster: this.cluster,\n\t\t\t\tdata: {\n\t\t\t\t\tcluster: cluster,\n\t\t\t\t\tindices: indices\n\t\t\t\t}\n\t\t\t});\n\t\t\tthis._nodesView.attach( this.tablEl );\n\t\t},\n\t\t_main_template: function() {\n\t\t\treturn { tag: \"DIV\", id: this.id(), cls: \"uiClusterOverview\", children: [\n\t\t\t\tnew ui.Toolbar({\n\t\t\t\t\tlabel: i18n.text(\"Overview.PageTitle\"),\n\t\t\t\t\tleft: [\n\t\t\t\t\t\tthis._nodeSortMenu,\n\t\t\t\t\t\tthis._indicesSortMenu,\n\t\t\t\t\t\tthis._aliasMenu,\n\t\t\t\t\t\tthis._indexFilter\n\t\t\t\t\t],\n\t\t\t\t\tright: [\n\t\t\t\t\t\tthis._refreshButton\n\t\t\t\t\t]\n\t\t\t\t}),\n\t\t\t\t{ tag: \"DIV\", cls: \"uiClusterOverview-table\" }\n\t\t\t] };\n\t\t}\n\t});\n\n})( this.jQuery, this.app, this.i18n );\n"
  },
  {
    "path": "src/app/ui/csvTable/csvTable.js",
    "content": "( function( $, app, joey ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tvar CELL_SEPARATOR = \",\";\n\tvar CELL_QUOTE = '\"';\n\tvar LINE_SEPARATOR = \"\\r\\n\";\n\n\tui.CSVTable = ui.AbstractWidget.extend({\n\t\tdefaults: {\n\t\t\tresults: null\n\t\t},\n\t\t_baseCls: \"uiCSVTable\",\n\t\tinit: function( parent ) {\n\t\t\tthis._super();\n\t\t\tvar results = this.config.results.hits.hits;\n\t\t\tvar columns = this._parseResults( results );\n\t\t\tthis._downloadButton = new ui.Button({\n\t\t\t\tlabel: \"Generate Download Link\",\n\t\t\t\tonclick: this._downloadLinkGenerator_handler\n\t\t\t});\n\t\t\tthis._downloadLink = $.joey( { tag: \"A\", text: \"download\", });\n\t\t\tthis._downloadLink.hide();\n\t\t\tthis._csvText = this._csv_template( columns, results );\n\t\t\tthis.el = $.joey( this._main_template() );\n\t\t\tthis.attach( parent );\n\t\t},\n\t\t_downloadLinkGenerator_handler: function() {\n\t\t\tvar csvData = new Blob( [ this._csvText ], { type: 'text/csv' });\n\t\t\tvar csvURL = URL.createObjectURL( csvData );\n\t\t\tthis._downloadLink.attr( \"href\", csvURL );\n\t\t\tthis._downloadLink.show();\n\t\t},\n\t\t_parseResults: function( results ) {\n\t\t\tvar columnPaths = {};\n\t\t\t(function parse( path, obj ) {\n\t\t\t\tif( obj instanceof Array ) {\n\t\t\t\t\tfor( var i = 0; i < obj.length; i++ ) {\n\t\t\t\t\t\tparse( path, obj[i] );\n\t\t\t\t\t}\n\t\t\t\t} else if( typeof obj === \"object\" ) {\n\t\t\t\t\tfor( var prop in obj ) {\n\t\t\t\t\t\tparse( path + \".\" + prop, obj[ prop ] );\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tcolumnPaths[ path ] = true;\n\t\t\t\t}\n\t\t\t})( \"root\", results );\n\t\t\tvar columns = [];\n\t\t\tfor( var column in columnPaths ) {\n\t\t\t\tcolumns.push( column.split(\".\").slice(1) );\n\t\t\t}\n\t\t\treturn columns;\n\t\t},\n\t\t_main_template: function() { return (\n\t\t\t{ tag: \"DIV\", cls: this._baseCls, id: this.id(), children: [\n\t\t\t\tthis._downloadButton,\n\t\t\t\tthis._downloadLink,\n\t\t\t\t{ tag: \"PRE\", text: this._csvText }\n\t\t\t] }\n\t\t); },\n\t\t_csv_template: function( columns, results ) {\n\t\t\treturn this._header_template( columns ) + LINE_SEPARATOR + this._results_template( columns, results );\n\t\t},\n\t\t_header_template: function( columns ) {\n\t\t\treturn columns.map( function( column ) {\n\t\t\t\treturn column.join(\".\");\n\t\t\t}).join( CELL_SEPARATOR );\n\t\t},\n\t\t_results_template: function( columns, results ) {\n\t\t\treturn results.map( function( result ) {\n\t\t\t\treturn columns.map( function( column ) {\n\t\t\t\t\tvar l = 0,\n\t\t\t\t\t\tptr = result;\n\t\t\t\t\twhile( l !== column.length && ptr != null ) {\n\t\t\t\t\t\tptr = ptr[ column[ l++ ] ];\n\t\t\t\t\t}\n\t\t\t\t\treturn ( ptr == null ) ? \"\" : ( CELL_QUOTE + ptr.toString().replace(/\"/g, '\"\"') + CELL_QUOTE );\n\t\t\t\t}).join( CELL_SEPARATOR );\n\t\t\t}).join( LINE_SEPARATOR );\n\t\t}\n\t});\n\n})( this.jQuery, this.app, this.joey );\n"
  },
  {
    "path": "src/app/ui/dateHistogram/dateHistogram.js",
    "content": "(function( app, i18n, raphael ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.DateHistogram = ui.AbstractWidget.extend({\n\t\tdefaults: {\n\t\t\tprintEl: null, // (optional) if supplied, clicking on elements in the histogram changes the query\n\t\t\tcluster: null, // (required)\n\t\t\tquery: null,   // (required) the current query\n\t\t\tspec: null     // (required) // date field spec\n\t\t},\n\t\tinit: function() {\n\t\t\tthis._super();\n\t\t\tthis.el = $(this._main_template());\n\t\t\tthis.query = this.config.query.clone();\n\t\t\t// check if the index/types have changed and rebuild the histogram\n\t\t\tthis.config.query.on(\"results\", function(query) {\n\t\t\t\tif(this.queryChanged) {\n\t\t\t\t\tthis.buildHistogram(query);\n\t\t\t\t\tthis.queryChanged = false;\n\t\t\t\t}\n\t\t\t}.bind(this));\n\t\t\tthis.config.query.on(\"setIndex\", function(query, params) {\n\t\t\t\tthis.query.setIndex(params.index, params.add);\n\t\t\t\tthis.queryChanged = true;\n\t\t\t}.bind(this));\n\t\t\tthis.config.query.on(\"setType\", function(query, params) {\n\t\t\t\tthis.query.setType(params.type, params.add);\n\t\t\t\tthis.queryChanged = true;\n\t\t\t}.bind(this));\n\t\t\tthis.query.search.size = 0;\n\t\t\tthis.query.on(\"results\", this._stat_handler);\n\t\t\tthis.query.on(\"results\", this._aggs_handler);\n\t\t\tthis.buildHistogram();\n\t\t},\n\t\tbuildHistogram: function(query) {\n\t\t\tthis.statAggs = this.query.addAggs({\n\t\t\t\tstats: { field: this.config.spec.field_name }\n\t\t\t});\n\t\t\tthis.query.query();\n\t\t\tthis.query.removeAggs(this.statAggs);\n\t\t},\n\t\t_stat_handler: function(query, results) {\n\t\t\tif(! results.aggregations[this.statAggs]) { return; }\n\t\t\tthis.stats = results.aggregations[this.statAggs];\n\t\t\t// here we are calculating the approximate range  that will give us less than 121 columns\n\t\t\tvar rangeNames = [ \"year\", \"year\", \"month\", \"day\", \"hour\", \"minute\" ];\n\t\t\tvar rangeFactors = [100000, 12, 30, 24, 60, 60000 ];\n\t\t\tthis.intervalRange = 1;\n\t\t\tvar range = this.stats.max - this.stats.min;\n\t\t\tdo {\n\t\t\t\tthis.intervalName = rangeNames.pop();\n\t\t\t\tvar factor = rangeFactors.pop();\n\t\t\t\tthis.intervalRange *= factor;\n\t\t\t\trange = range / factor;\n\t\t\t} while(range > 70);\n\t\t\tthis.dateAggs = this.query.addAggs({\n\t\t\t\tdate_histogram : {\n\t\t\t\t\tfield: this.config.spec.field_name,\n\t\t\t\t\tinterval: this.intervalName\n\t\t\t\t}\n\t\t\t});\n\t\t\tthis.query.query();\n\t\t\tthis.query.removeAggs(this.dateAggs);\n\t\t},\n\t\t_aggs_handler: function(query, results) {\n\t\t\tif(! results.aggregations[this.dateAggs]) { return; }\n\t\t\tvar buckets = [], range = this.intervalRange;\n\t\t\tvar min = Math.floor(this.stats.min / range) * range;\n\t\t\tvar prec = [ \"year\", \"month\", \"day\", \"hour\", \"minute\", \"second\" ].indexOf(this.intervalName);\n\t\t\tresults.aggregations[this.dateAggs].buckets.forEach(function(entry) {\n\t\t\t\tbuckets[parseInt((entry.key - min) / range , 10)] = entry.doc_count;\n\t\t\t}, this);\n\t\t\tfor(var i = 0; i < buckets.length; i++) {\n\t\t\t\tbuckets[i] = buckets[i] || 0;\n\t\t\t}\n\t\t\tthis.el.removeClass(\"loading\");\n\t\t\tvar el = this.el.empty();\n\t\t\tvar w = el.width(), h = el.height();\n\t\t\tvar r = raphael(el[0], w, h );\n\t\t\tvar printEl = this.config.printEl;\n\t\t\tquery = this.config.query;\n\t\t\tr.g.barchart(0, 0, w, h, [buckets], { gutter: \"0\", vgutter: 0 }).hover(\n\t\t\t\tfunction() {\n\t\t\t\t\tthis.flag = r.g.popup(this.bar.x, h - 5, this.value || \"0\").insertBefore(this);\n\t\t\t\t}, function() {\n\t\t\t\t\tthis.flag.animate({opacity: 0}, 200, \">\", function () {this.remove();});\n\t\t\t\t}\n\t\t\t).click(function() {\n\t\t\t\tif(printEl) {\n\t\t\t\t\tprintEl.val(window.dateRangeParser.print(min + this.bar.index * range, prec));\n\t\t\t\t\tprintEl.trigger(\"keyup\");\n\t\t\t\t\tquery.query();\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\t\t_main_template: function() { return (\n\t\t\t{ tag: \"DIV\", cls: \"uiDateHistogram loading\", css: { height: \"50px\" }, children: [\n\t\t\t\ti18n.text(\"General.LoadingAggs\")\n\t\t\t] }\n\t\t); }\n\t});\n\n})( this.app, this.i18n, this.Raphael );"
  },
  {
    "path": "src/app/ui/dialogPanel/dialogPanel.js",
    "content": "(function( app ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.DialogPanel = ui.DraggablePanel.extend({\n\t\t_commit_handler: function(jEv) {\n\t\t\tthis.fire(\"commit\", this, { jEv: jEv });\n\t\t},\n\t\t_main_template: function() {\n\t\t\tvar t = this._super();\n\t\t\tt.children.push(this._actionsBar_template());\n\t\t\treturn t;\n\t\t},\n\t\t_actionsBar_template: function() {\n\t\t\treturn { tag: \"DIV\", cls: \"pull-right\", children: [\n\t\t\t\tnew app.ui.Button({ label: \"Cancel\", onclick: this._close_handler }),\n\t\t\t\tnew app.ui.Button({ label: \"OK\", onclick: this._commit_handler })\n\t\t\t]};\n\t\t}\n\t});\n\n})( this.app );\n"
  },
  {
    "path": "src/app/ui/draggablePanel/draggablePanel.js",
    "content": "(function( $, app ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.DraggablePanel = ui.AbstractPanel.extend({\n\t\tdefaults: {\n\t//\t\ttitle: \"\"   // (required) text for the panel title\n\t\t},\n\n\t\t_baseCls: \"uiPanel\",\n\n\t\tinit: function() {\n\t\t\tthis._super();\n\t\t\tthis.body = $(this._body_template());\n\t\t\tthis.title = $(this._title_template());\n\t\t\tthis.el = $.joey( this._main_template() );\n\t\t\tthis.el.css( { width: this.config.width } );\n\t\t\tthis.dd = new app.ux.DragDrop({\n\t\t\t\tpickupSelector: this.el.find(\".uiPanel-titleBar\"),\n\t\t\t\tdragObj: this.el\n\t\t\t});\n\t\t\t// open the panel if set in configuration\n\t\t\tthis.config.open && this.open();\n\t\t},\n\n\t\tsetBody: function(body) {\n\t\t\t\tthis.body.empty().append(body);\n\t\t},\n\t\t_body_template: function() { return { tag: \"DIV\", cls: \"uiPanel-body\", css: { height: this.config.height + (this.config.height === 'auto' ? \"\" : \"px\" ) }, children: [ this.config.body ] }; },\n\t\t_title_template: function() { return { tag: \"SPAN\", cls: \"uiPanel-title\", text: this.config.title }; },\n\t\t_main_template: function() { return (\n\t\t\t{ tag: \"DIV\", id: this.id(), cls: this._baseCls, children: [\n\t\t\t\t{ tag: \"DIV\", cls: \"uiPanel-titleBar\", children: [\n\t\t\t\t\t{ tag: \"DIV\", cls: \"uiPanel-close\", onclick: this._close_handler, text: \"x\" },\n\t\t\t\t\tthis.title\n\t\t\t\t]},\n\t\t\t\tthis.body\n\t\t\t] }\n\t\t); }\n\t});\n\n})( this.jQuery, this.app );\n"
  },
  {
    "path": "src/app/ui/filterBrowser/filterBrowser.css",
    "content": ".uiFilterBrowser-row * {\n\tmargin-right: 0.4em;\n}\n\n.uiFilterBrowser-row BUTTON {\n\theight: 22px;\n\tposition: relative;\n\ttop: 1px;\n}\n"
  },
  {
    "path": "src/app/ui/filterBrowser/filterBrowser.js",
    "content": "(function( $, app, i18n ) {\n\n\tvar ui = app.ns(\"ui\");\n\tvar data = app.ns(\"data\");\n\tvar ut = app.ns(\"ut\");\n\n\tui.FilterBrowser = ui.AbstractWidget.extend({\n\t\tdefaults: {\n\t\t\tcluster: null,  // (required) instanceof app.services.Cluster\n\t\t\tindex: \"\" // (required) name of the index to query\n\t\t},\n\n\t\tinit: function(parent) {\n\t\t\tthis._super();\n\t\t\tthis._cluster = this.config.cluster;\n\t\t\tthis.el = $(this._main_template());\n\t\t\tthis.filtersEl = this.el.find(\".uiFilterBrowser-filters\");\n\t\t\tthis.attach( parent );\n\t\t\tnew data.MetaDataFactory({ cluster: this._cluster, onReady: function(metadata, eventData) {\n\t\t\t\tthis.metadata = metadata;\n\t\t\t\tthis._createFilters_handler(eventData.originalData.metadata.indices);\n\t\t\t}.bind(this) });\n\t\t},\n\n\t\t_createFilters_handler: function(data) {\n\t\t\tvar filters = [];\n\t\t\tfunction scan_properties(path, obj) {\n\t\t\t\tif (obj.properties) {\n\t\t\t\t\tfor (var prop in obj.properties) {\n\t\t\t\t\t\tscan_properties(path.concat(prop), obj.properties[prop]);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// handle multi_field \n\t\t\t\t\tif (obj.fields) {\n\t\t\t\t\t\tfor (var subField in obj.fields) {\n\t\t\t\t\t\t\tfilters.push({ path: (path[path.length - 1] !== subField) ? path.concat(subField) : path, type: obj.fields[subField].type, meta: obj.fields[subField] });\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tfilters.push({ path: path, type: obj.type, meta: obj });\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (data[this.config.index]){\n\t\t\t\tfor(var type in data[this.config.index].mappings) {\n\t\t\t\t\tscan_properties([type], data[this.config.index].mappings[type]);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfilters.sort( function(a, b) {\n\t\t\t\tvar x = a.path.join(\".\");\n\t\t\t\tvar y = b.path.join(\".\");\n\t\t\t\treturn (x < y) ? -1 : (x > y) ? 1 : 0;\n\t\t\t});\n\n\t\t\tthis.filters = [\n\t\t\t\t{ path: [\"match_all\"], type: \"match_all\", meta: {} },\n\t\t\t\t{ path: [\"_all\"], type: \"_all\", meta: {}}\n\t\t\t].concat(filters);\n\n\t\t\tthis._addFilterRow_handler();\n\t\t},\n\t\t\n\t\t_addFilterRow_handler: function() {\n\t\t\tthis.filtersEl.append(this._filter_template());\n\t\t},\n\t\t\n\t\t_removeFilterRow_handler: function(jEv) {\n\t\t\t$(jEv.target).closest(\"DIV.uiFilterBrowser-row\").remove();\n\t\t\tif(this.filtersEl.children().length === 0) {\n\t\t\t\tthis._addFilterRow_handler();\n\t\t\t}\n\t\t},\n\t\t\n\t\t_search_handler: function() {\n\t\t\tvar search = new data.BoolQuery();\n\t\t\tsearch.setSize( this.el.find(\".uiFilterBrowser-outputSize\").val() )\n\t\t\tthis.fire(\"startingSearch\");\n\t\t\tthis.filtersEl.find(\".uiFilterBrowser-row\").each(function(i, row) {\n\t\t\t\trow = $(row);\n\t\t\t\tvar bool = row.find(\".bool\").val();\n\t\t\t\tvar field = row.find(\".field\").val();\n\t\t\t\tvar op = row.find(\".op\").val();\n\t\t\t\tvar value = {};\n\t\t\t\tif(field === \"match_all\") {\n\t\t\t\t\top = \"match_all\";\n\t\t\t\t} else if(op === \"range\") {\n\t\t\t\t\tvar lowqual = row.find(\".lowqual\").val(),\n\t\t\t\t\t\thighqual = row.find(\".highqual\").val();\n\t\t\t\t\tif(lowqual.length) {\n\t\t\t\t\t\tvalue[row.find(\".lowop\").val()] = lowqual;\n\t\t\t\t\t}\n\t\t\t\t\tif(highqual.length) {\n\t\t\t\t\t\tvalue[row.find(\".highop\").val()] = highqual;\n\t\t\t\t\t}\n\t\t\t\t} else if(op === \"fuzzy\") {\n\t\t\t\t\tvar qual = row.find(\".qual\").val(),\n\t\t\t\t\t\tfuzzyqual = row.find(\".fuzzyqual\").val();\n\t\t\t\t\tif(qual.length) {\n\t\t\t\t\t\tvalue[\"value\"] = qual;\n\t\t\t\t\t}\n\t\t\t\t\tif(fuzzyqual.length) {\n\t\t\t\t\t\tvalue[row.find(\".fuzzyop\").val()] = fuzzyqual;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tvalue = row.find(\".qual\").val();\n\t\t\t\t}\n\t\t\t\tsearch.addClause(value, field, op, bool);\n\t\t\t});\n\t\t\tif(this.el.find(\".uiFilterBrowser-showSrc\").attr(\"checked\")) {\n\t\t\t\tthis.fire(\"searchSource\", search.search);\n\t\t\t}\n\t\t\tthis._cluster.post( this.config.index + \"/_search\", search.getData(), this._results_handler );\n\t\t},\n\t\t\n\t\t_results_handler: function( data ) {\n\t\t\tvar type = this.el.find(\".uiFilterBrowser-outputFormat\").val();\n\t\t\tthis.fire(\"results\", this, { type: type, data: data, metadata: this.metadata });\n\t\t},\n\t\t\n\t\t_changeQueryField_handler: function(jEv) {\n\t\t\tvar select = $(jEv.target);\n\t\t\tvar spec = select.children(\":selected\").data(\"spec\");\n\t\t\tselect.siblings().remove(\".op,.qual,.range,.fuzzy\");\n\t\t\tvar ops = [];\n\t\t\tif(spec.type === 'match_all') {\n\t\t\t} else if(spec.type === '_all') {\n\t\t\t\tops = [\"query_string\"];\n\t\t\t} else if(spec.type === 'string' || spec.type === 'text' || spec.type === 'keyword') {\n\t\t\t\tops = [\"match\", \"term\", \"wildcard\", \"prefix\", \"fuzzy\", \"range\", \"query_string\", \"text\", \"missing\"];\n\t\t\t} else if(spec.type === 'long' || spec.type === 'integer' || spec.type === 'float' ||\n\t\t\t\t\tspec.type === 'byte' || spec.type === 'short' || spec.type === 'double') {\n\t\t\t\tops = [\"term\", \"range\", \"fuzzy\", \"query_string\", \"missing\"];\n\t\t\t} else if(spec.type === 'date') {\n\t\t\t\tops = [\"term\", \"range\", \"fuzzy\", \"query_string\", \"missing\"];\n\t\t\t} else if(spec.type === 'geo_point') {\n\t\t\t\tops = [\"missing\"];\n\t\t\t} else if(spec.type === 'ip') {\n\t\t\t\tops = [\"term\", \"range\", \"fuzzy\", \"query_string\", \"missing\"];\n\t\t\t} else if(spec.type === 'boolean') {\n\t\t\t\tops = [\"term\"]\n\t\t\t}\n\t\t\tselect.after({ tag: \"SELECT\", cls: \"op\", onchange: this._changeQueryOp_handler, children: ops.map(ut.option_template) });\n\t\t\tselect.next().change();\n\t\t},\n\t\t\n\t\t_changeQueryOp_handler: function(jEv) {\n\t\t\tvar op = $(jEv.target), opv = op.val();\n\t\t\top.siblings().remove(\".qual,.range,.fuzzy\");\n\t\t\tif(opv === 'match' || opv === 'term' || opv === 'wildcard' || opv === 'prefix' || opv === \"query_string\" || opv === 'text') {\n\t\t\t\top.after({ tag: \"INPUT\", cls: \"qual\", type: \"text\" });\n\t\t\t} else if(opv === 'range') {\n\t\t\t\top.after(this._range_template());\n\t\t\t} else if(opv === 'fuzzy') {\n\t\t\t\top.after(this._fuzzy_template());\n\t\t\t}\n\t\t},\n\t\t\n\t\t_main_template: function() {\n\t\t\treturn { tag: \"DIV\", children: [\n\t\t\t\t{ tag: \"DIV\", cls: \"uiFilterBrowser-filters\" },\n\t\t\t\t{ tag: \"BUTTON\", type: \"button\", text: i18n.text(\"General.Search\"), onclick: this._search_handler },\n\t\t\t\t{ tag: \"LABEL\", children:\n\t\t\t\t\ti18n.complex(\"FilterBrowser.OutputType\", { tag: \"SELECT\", cls: \"uiFilterBrowser-outputFormat\", children: [\n\t\t\t\t\t\t{ text: i18n.text(\"Output.Table\"), value: \"table\" },\n\t\t\t\t\t\t{ text: i18n.text(\"Output.JSON\"), value: \"json\" },\n\t\t\t\t\t\t{ text: i18n.text(\"Output.CSV\"), value: \"csv\" }\n\t\t\t\t\t].map(function( o ) { return $.extend({ tag: \"OPTION\" }, o ); } ) } )\n\t\t\t\t},\n\t\t\t\t{ tag: \"LABEL\", children:\n\t\t\t\t\ti18n.complex(\"FilterBrowser.OutputSize\", { tag: \"SELECT\", cls: \"uiFilterBrowser-outputSize\",\n\t\t\t\t\t\tchildren: [ \"10\", \"50\", \"250\", \"1000\", \"5000\", \"25000\" ].map( ut.option_template )\n\t\t\t\t\t} )\n\t\t\t\t},\n\t\t\t\t{ tag: \"LABEL\", children: [ { tag: \"INPUT\", type: \"checkbox\", cls: \"uiFilterBrowser-showSrc\" }, i18n.text(\"Output.ShowSource\") ] }\n\t\t\t]};\n\t\t},\n\t\t\n\t\t_filter_template: function() {\n\t\t\treturn { tag: \"DIV\", cls: \"uiFilterBrowser-row\", children: [\n\t\t\t\t{ tag: \"SELECT\", cls: \"bool\", children: [\"must\", \"must_not\", \"should\"].map(ut.option_template) },\n\t\t\t\t{ tag: \"SELECT\", cls: \"field\", onchange: this._changeQueryField_handler, children: this.filters.map(function(f) {\n\t\t\t\t\treturn { tag: \"OPTION\", data: { spec: f }, value: f.path.join(\".\"), text: f.path.join(\".\") };\n\t\t\t\t})},\n\t\t\t\t{ tag: \"BUTTON\", type: \"button\", text: \"+\", onclick: this._addFilterRow_handler },\n\t\t\t\t{ tag: \"BUTTON\", type: \"button\", text: \"-\", onclick: this._removeFilterRow_handler }\n\t\t\t]};\n\t\t},\n\t\t\n\t\t_range_template: function() {\n\t\t\treturn { tag: \"SPAN\", cls: \"range\", children: [\n\t\t\t\t{ tag: \"SELECT\", cls: \"lowop\", children: [\"gt\", \"gte\"].map(ut.option_template) },\n\t\t\t\t{ tag: \"INPUT\", type: \"text\", cls: \"lowqual\" },\n\t\t\t\t{ tag: \"SELECT\", cls: \"highop\", children: [\"lt\", \"lte\"].map(ut.option_template) },\n\t\t\t\t{ tag: \"INPUT\", type: \"text\", cls: \"highqual\" }\n\t\t\t]};\n\t\t},\n\n\t\t_fuzzy_template: function() {\n\t\t\treturn { tag: \"SPAN\", cls: \"fuzzy\", children: [\n\t\t\t\t{ tag: \"INPUT\", cls: \"qual\", type: \"text\" },\n\t\t\t\t{ tag: \"SELECT\", cls: \"fuzzyop\", children: [\"max_expansions\", \"min_similarity\"].map(ut.option_template) },\n\t\t\t\t{ tag: \"INPUT\", cls: \"fuzzyqual\", type: \"text\" }\n\t\t\t]};\n\t\t}\n\t});\n\t\n})( this.jQuery, this.app, this.i18n );\n"
  },
  {
    "path": "src/app/ui/header/header.css",
    "content": ".uiHeader {\n\tpadding: 3px 10px;\n}\n\n.uiHeader-name, .uiHeader-status {\n\tfont-size: 1.2em;\n\tfont-weight: bold;\n\tpadding: 0 10px;\n}\n\n"
  },
  {
    "path": "src/app/ui/header/header.js",
    "content": "(function( $, app, i18n ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.Header = ui.AbstractWidget.extend({\n\t\tdefaults: {\n\t\t\tcluster: null,\n\t\t\tclusterState: null\n\t\t},\n\t\t_baseCls: \"uiHeader\",\n\t\tinit: function() {\n\t\t\tthis._clusterConnect = new ui.ClusterConnect({\n\t\t\t\tcluster: this.config.cluster\n\t\t\t});\n\t\t\tvar quicks = [\n\t\t\t\t{ text: i18n.text(\"Nav.Info\"), path: \"\" },\n\t\t\t\t{ text: i18n.text(\"Nav.Status\"), path: \"_stats\" },\n\t\t\t\t{ text: i18n.text(\"Nav.NodeStats\"), path: \"_nodes/stats\" },\n\t\t\t\t{ text: i18n.text(\"Nav.ClusterNodes\"), path: \"_nodes\" },\n\t\t\t\t{ text: i18n.text(\"Nav.Plugins\"), path: \"_nodes/plugins\" },\n\t\t\t\t{ text: i18n.text(\"Nav.ClusterState\"), path: \"_cluster/state\" },\n\t\t\t\t{ text: i18n.text(\"Nav.ClusterHealth\"), path: \"_cluster/health\" },\n\t\t\t\t{ text: i18n.text(\"Nav.Templates\"), path: \"_template\" }\n\t\t\t];\n\t\t\tvar cluster = this.config.cluster;\n\t\t\tvar quickPanels = {};\n\t\t\tvar menuItems = quicks.map( function( item ) {\n\t\t\t\treturn { text: item.text, onclick: function() {\n\t\t\t\t\tcluster.get( item.path, function( data ) {\n\t\t\t\t\t\tquickPanels[ item.path ] && quickPanels[ item.path ].el && quickPanels[ item.path ].remove();\n\t\t\t\t\t\tquickPanels[ item.path ] = new ui.JsonPanel({\n\t\t\t\t\t\t\ttitle: item.text,\n\t\t\t\t\t\t\tjson: data\n\t\t\t\t\t\t});\n\t\t\t\t\t} );\n\t\t\t\t} };\n\t\t\t}, this );\n\t\t\tthis._quickMenu = new ui.MenuButton({\n\t\t\t\tlabel: i18n.text(\"NodeInfoMenu.Title\"),\n\t\t\t\tmenu: new ui.MenuPanel({\n\t\t\t\t\titems: menuItems\n\t\t\t\t})\n\t\t\t});\n\t\t\tthis.el = $.joey( this._main_template() );\n\t\t\tthis.nameEl = this.el.find(\".uiHeader-name\");\n\t\t\tthis.statEl = this.el.find(\".uiHeader-status\");\n\t\t\tthis._clusterState = this.config.clusterState;\n\t\t\tthis._clusterState.on(\"data\", function( state ) {\n\t\t\t\tvar shards = state.status._shards;\n\t\t\t\tvar colour = state.clusterHealth.status;\n\t\t\t\tvar name = state.clusterState.cluster_name;\n\t\t\t\tthis.nameEl.text( name );\n\t\t\t\tthis.statEl\n\t\t\t\t\t.text( i18n.text(\"Header.ClusterHealth\", colour, shards.successful, shards.total ) )\n\t\t\t\t\t.css( \"background\", colour );\n\t\t\t}.bind(this));\n\t\t\tthis.statEl.text( i18n.text(\"Header.ClusterNotConnected\") ).css(\"background\", \"grey\");\n\t\t\tthis._clusterState.refresh();\n\t\t},\n\t\t_main_template: function() { return (\n\t\t\t{ tag: \"DIV\", cls: this._baseCls, children: [\n\t\t\t\tthis._clusterConnect,\n\t\t\t\t{ tag: \"SPAN\", cls: \"uiHeader-name\" },\n\t\t\t\t{ tag: \"SPAN\", cls: \"uiHeader-status\" },\n\t\t\t\t{ tag: \"H1\", text: i18n.text(\"General.Elasticsearch\") },\n\t\t\t\t{ tag: \"SPAN\", cls: \"pull-right\", children: [\n\t\t\t\t\tthis._quickMenu\n\t\t\t\t] }\n\t\t\t] }\n\t\t); }\n\t} );\n\n})( this.jQuery, this.app, this.i18n );\n"
  },
  {
    "path": "src/app/ui/helpPanel/helpPanel.js",
    "content": "(function( app ){\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.HelpPanel = ui.InfoPanel.extend({\n\t\tdefaults: {\n\t\t\tref: \"\",\n\t\t\topen: true,\n\t\t\tautoRemove: true,\n\t\t\tmodal: false,\n\t\t\twidth: 500,\n\t\t\theight: 450,\n\t\t\ttitle: i18n.text(\"General.Help\")\n\t\t},\n\t\tinit: function() {\n\t\t\tthis._super();\n\t\t\tthis.body.append(i18n.text(this.config.ref));\n\t\t}\n\t});\n\n})( this.app );\n"
  },
  {
    "path": "src/app/ui/indexOverview/indexOverview.js",
    "content": "(function( $, app, i18n ) {\n\t\n\tvar ui = app.ns(\"ui\");\n\tvar ut = app.ns(\"ut\");\n\n\tui.IndexOverview = ui.Page.extend({\n\t\tdefaults: {\n\t\t\tcluster: null\n\t\t},\n\t\tinit: function() {\n\t\t\tthis._super();\n\t\t\tthis.cluster = this.config.cluster;\n\t\t\tthis._clusterState = this.config.clusterState;\n\t\t\tthis._clusterState.on(\"data\", this._refresh_handler );\n\t\t\tthis.el = $(this._main_template());\n\t\t\tthis._refresh_handler();\n\t\t},\n\t\tremove: function() {\n\t\t\tthis._clusterState.removeObserver( \"data\", this._refresh_handler );\n\t\t},\n\t\t_refresh_handler: function() {\n\t\t\tvar state = this._clusterState;\n\t\t\tvar view = {\n\t\t\t\tindices: acx.eachMap( state.status.indices, function( name, index ) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tname: name,\n\t\t\t\t\t\tstate: index\n\t\t\t\t\t};\n\t\t\t\t}).sort( function( a, b ) {\n\t\t\t\t\treturn a.name < b.name ? -1 : 1;\n\t\t\t\t})\n\t\t\t};\n\t\t\tthis._indexViewEl && this._indexViewEl.remove();\n\t\t\tthis._indexViewEl = $( this._indexTable_template( view ) );\n\t\t\tthis.el.find(\".uiIndexOverview-table\").append( this._indexViewEl );\n\t\t},\n\t\t_newIndex_handler: function() {\n\t\t\tvar fields = new app.ux.FieldCollection({\n\t\t\t\tfields: [\n\t\t\t\t\tnew ui.TextField({ label: i18n.text(\"ClusterOverView.IndexName\"), name: \"_name\", require: true }),\n\t\t\t\t\tnew ui.TextField({\n\t\t\t\t\t\tlabel: i18n.text(\"ClusterOverview.NumShards\"),\n\t\t\t\t\t\tname: \"number_of_shards\",\n\t\t\t\t\t\tvalue: \"5\",\n\t\t\t\t\t\trequire: function( val ) { return parseInt( val, 10 ) >= 1; }\n\t\t\t\t\t}),\n\t\t\t\t\tnew ui.TextField({\n\t\t\t\t\t\tlabel: i18n.text(\"ClusterOverview.NumReplicas\"),\n\t\t\t\t\t\tname: \"number_of_replicas\",\n\t\t\t\t\t\tvalue: \"1\",\n\t\t\t\t\t\trequire: function( val ) { return parseInt( val, 10 ) >= 0; }\n\t\t\t\t\t})\n\t\t\t\t]\n\t\t\t});\n\t\t\tvar dialog = new ui.DialogPanel({\n\t\t\t\ttitle: i18n.text(\"ClusterOverview.NewIndex\"),\n\t\t\t\tbody: new ui.PanelForm({ fields: fields }),\n\t\t\t\tonCommit: function(panel, args) {\n\t\t\t\t\tif(fields.validate()) {\n\t\t\t\t\t\tvar data = fields.getData();\n\t\t\t\t\t\tvar name = data[\"_name\"];\n\t\t\t\t\t\tdelete data[\"_name\"];\n\t\t\t\t\t\tthis.config.cluster.put( encodeURIComponent( name ), JSON.stringify({ settings: { index: data } }), function(d) {\n\t\t\t\t\t\t\tdialog.close();\n\t\t\t\t\t\t\talert(JSON.stringify(d));\n\t\t\t\t\t\t\tthis._clusterState.refresh();\n\t\t\t\t\t\t}.bind(this) );\n\t\t\t\t\t}\n\t\t\t\t}.bind(this)\n\t\t\t}).open();\n\t\t},\n\t\t_indexTable_template: function( view ) { return (\n\t\t\t{ tag: \"TABLE\", cls: \"table\", children: [\n\t\t\t\t{ tag: \"THEAD\", children: [\n\t\t\t\t\t{ tag: \"TR\", children: [\n\t\t\t\t\t\t{ tag: \"TH\" },\n\t\t\t\t\t\t{ tag: \"TH\", children: [\n\t\t\t\t\t\t\t{ tag: \"H3\", text: \"Size\" }\n\t\t\t\t\t\t] },\n\t\t\t\t\t\t{ tag: \"TH\", children: [\n\t\t\t\t\t\t\t{ tag: \"H3\", text: \"Docs\" }\n\t\t\t\t\t\t] }\n\t\t\t\t\t] }\n\t\t\t\t] },\n\t\t\t\t{ tag: \"TBODY\", cls: \"striped\", children: view.indices.map( this._index_template, this ) }\n\t\t\t] }\n\t\t); },\n\n\t\t_index_template: function( index ) { return (\n\t\t\t{ tag: \"TR\", children: [\n\t\t\t\t{ tag: \"TD\", children: [\n\t\t\t\t\t{ tag: \"H3\", text: index.name }\n\t\t\t\t] },\n\t\t\t\t{ tag: \"TD\", text: ut.byteSize_template( index.state.primaries.store.size_in_bytes ) + \"/\" + ut.byteSize_template( index.state.total.store.size_in_bytes ) },\n\t\t\t\t{ tag: \"TD\", text: ut.count_template( index.state.primaries.docs.count ) }\n\t\t\t] }\n\t\t); },\n\t\t_main_template: function() {\n\t\t\treturn { tag: \"DIV\", id: this.id(), cls: \"uiIndexOverview\", children: [\n\t\t\t\tnew ui.Toolbar({\n\t\t\t\t\tlabel: i18n.text(\"IndexOverview.PageTitle\"),\n\t\t\t\t\tleft: [\n\t\t\t\t\t\tnew ui.Button({\n\t\t\t\t\t\t\tlabel: i18n.text(\"ClusterOverview.NewIndex\"),\n\t\t\t\t\t\t\tonclick: this._newIndex_handler\n\t\t\t\t\t\t}),\n\t\t\t\t\t]\n\t\t\t\t}),\n\t\t\t\t{ tag: \"DIV\", cls: \"uiIndexOverview-table\", children: this._indexViewEl }\n\t\t\t] };\n\t\t}\n\n\t});\n\n})( this.jQuery, this.app, this.i18n );\n"
  },
  {
    "path": "src/app/ui/indexSelector/indexSelector.js",
    "content": "(function( $, app, i18n ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.IndexSelector = ui.AbstractWidget.extend({\n\t\tinit: function(parent) {\n\t\t\tthis._super();\n\t\t\tthis.el = $(this._main_template());\n\t\t\tthis.attach( parent );\n\t\t\tthis.cluster = this.config.cluster;\n\t\t\tthis.update();\n\t\t},\n\t\tupdate: function() {\n\t\t\tthis.cluster.get( \"_stats\", this._update_handler );\n\t\t},\n\t\t\n\t\t_update_handler: function(data) {\n\t\t\tvar options = [];\n\t\t\tvar index_names = Object.keys(data.indices).sort();\n\t\t\tfor(var i=0; i < index_names.length; i++) { \n\t\t\t\tname = index_names[i];\n\t\t\t\toptions.push(this._option_template(name, data.indices[name])); \n\t\t\t}\n\t\t\tthis.el.find(\".uiIndexSelector-select\").empty().append(this._select_template(options));\n\t\t\tthis._indexChanged_handler();\n\t\t},\n\t\t\n\t\t_main_template: function() {\n\t\t\treturn { tag: \"DIV\", cls: \"uiIndexSelector\", children: i18n.complex( \"IndexSelector.SearchIndexForDocs\", { tag: \"SPAN\", cls: \"uiIndexSelector-select\" } ) };\n\t\t},\n\n\t\t_indexChanged_handler: function() {\n\t\t\tthis.fire(\"indexChanged\", this.el.find(\"SELECT\").val());\n\t\t},\n\n\t\t_select_template: function(options) {\n\t\t\treturn { tag: \"SELECT\", children: options, onChange: this._indexChanged_handler };\n\t\t},\n\t\t\n\t\t_option_template: function(name, index) {\n\t\t\treturn  { tag: \"OPTION\", value: name, text: i18n.text(\"IndexSelector.NameWithDocs\", name, index.primaries.docs.count ) };\n\t\t}\n\t});\n\n})( this.jQuery, this.app, this.i18n );\n"
  },
  {
    "path": "src/app/ui/infoPanel/infoPanel.css",
    "content": "\n.uiInfoPanel {\n\tbackground: rgba(0, 0, 0, 0.75);\n\tcolor: white;\n\tborder-radius: 8px;\n\tpadding: 1px;\n}\n.uiInfoPanel .uiPanel-titleBar {\n\tbackground: rgba(74, 74, 74, 0.75);\n\tbackground: -moz-linear-gradient(top, rgba(84, 84, 84, 0.75), rgba(54, 54, 54, 0.75), rgba(64, 64, 64, 0.75));\n\tbackground: -webkit-linear-gradient(top, rgba(84, 84, 84, 0.75), rgba(54, 54, 54, 0.75), rgba(64, 64, 64, 0.75));\n\tborder-radius: 8px 8px 0 0;\n\tpadding: 1px 0 2px 0;\n\tborder-bottom: 0;\n}\n.uiInfoPanel .uiPanel-close {\n\tborder-radius: 6px;\n\theight: 13px;\n\twidth: 13px;\n\tbackground: #ccc;\n\tleft: 3px;\n\ttop: 1px;\n\tcolor: #333;\n\ttext-shadow: #222 0 0 1px;\n\tline-height: 11px;\n\tborder: 0;\n\tpadding: 0;\n}\n.uiInfoPanel .uiPanel-close:hover {\n\tbackground: #eee;\n}\n\n.uiInfoPanel .uiPanel-body {\n\tbackground: transparent;\n\tpadding: 20px;\n\tborder-radius: 0 0 8px 8px;\n\tborder: 1px solid #222;\n}\n"
  },
  {
    "path": "src/app/ui/infoPanel/infoPanel.js",
    "content": "(function( app ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.InfoPanel = ui.DraggablePanel.extend({\n\t\t_baseCls: \"uiPanel uiInfoPanel\"\n\t});\n\n})( this.app );\n"
  },
  {
    "path": "src/app/ui/jsonPanel/jsonPanel.css",
    "content": ".uiJsonPanel SPAN.uiJsonPretty-string { color: #6F6; }\n.uiJsonPanel SPAN.uiJsonPretty-number { color: #66F; }\n.uiJsonPanel SPAN.uiJsonPretty-null { color: #F66; }\n.uiJsonPanel SPAN.uiJsonPretty-boolean { color: #F6F; }\n"
  },
  {
    "path": "src/app/ui/jsonPanel/jsonPanel.js",
    "content": "(function( app ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.JsonPanel = ui.InfoPanel.extend({\n\t\tdefaults: {\n\t\t\tjson: null, // (required)\n\t\t\tmodal: false,\n\t\t\topen: true,\n\t\t\tautoRemove: true,\n\t\t\theight: 500,\n\t\t\twidth: 600\n\t\t},\n\n\t\t_baseCls: \"uiPanel uiInfoPanel uiJsonPanel\",\n\n\t\t_body_template: function() {\n\t\t\tvar body = this._super();\n\t\t\tbody.children = [ new ui.JsonPretty({ obj: this.config.json }) ];\n\t\t\treturn body;\n\t\t}\n\t});\n\n})( this.app );\n"
  },
  {
    "path": "src/app/ui/jsonPretty/jsonPretty.css",
    "content": "DIV.uiJsonPretty-object { font-size: 1.26em; font-family: monospace; }\nUL.uiJsonPretty-object,\nUL.uiJsonPretty-array { margin: 0; padding: 0 0 0 2em; list-style: none; }\nUL.uiJsonPretty-object LI,\nUL.uiJsonPretty-array LI { padding: 0; margin: 0; }\n.expando > SPAN.uiJsonPretty-name:before { content: \"\\25bc\\a0\"; color: #555; position: relative; top: 2px; }\n.expando.uiJsonPretty-minimised > SPAN.uiJsonPretty-name:before { content: \"\\25ba\\a0\"; top: 0; }\n.uiJsonPretty-minimised > UL SPAN.uiJsonPretty-name:before,\n.expando .uiJsonPretty-minimised > UL SPAN.uiJsonPretty-name:before { content: \"\"; }\nSPAN.uiJsonPretty-string,\nSPAN.uiJsonPretty-string A { color: green; }\nSPAN.uiJsonPretty-string A { text-decoration: underline;}\nSPAN.uiJsonPretty-number { color: blue; }\nSPAN.uiJsonPretty-null { color: red; }\nSPAN.uiJsonPretty-boolean { color: purple; }\n.expando > .uiJsonPretty-name { cursor: pointer; }\n.expando > .uiJsonPretty-name:hover { text-decoration: underline; }\n.uiJsonPretty-minimised { white-space: nowrap; overflow: hidden; }\n.uiJsonPretty-minimised > UL { opacity: 0.6; }\n.uiJsonPretty-minimised .uiJsonPretty-minimised > UL { opacity: 1; }\n.uiJsonPretty-minimised UL, .uiJsonPretty-minimised LI { display: inline; padding: 0; }\n\n"
  },
  {
    "path": "src/app/ui/jsonPretty/jsonPretty.js",
    "content": "(function( $, app ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.JsonPretty = ui.AbstractWidget.extend({\n\t\tdefaults: {\n\t\t\tobj: null\n\t\t},\n\t\tinit: function(parent) {\n\t\t\tthis._super();\n\t\t\tthis.el = $(this._main_template());\n\t\t\tthis.attach(parent);\n\t\t\tthis.el.click(this._click_handler);\n\t\t},\n\t\t\n\t\t_click_handler: function(jEv) {\n\t\t\tvar t = $(jEv.target).closest(\".uiJsonPretty-name\").closest(\"LI\");\n\t\t\tif(t.length === 0 || t.parents(\".uiJsonPretty-minimised\").length > 0) { return; }\n\t\t\tt.toggleClass(\"uiJsonPretty-minimised\");\n\t\t\tjEv.stopPropagation();\n\t\t},\n\t\t\n\t\t_main_template: function() {\n\t\t\ttry {\n\t\t\t\t\treturn { tag: \"DIV\", cls: \"uiJsonPretty\", children: this.pretty.parse(this.config.obj) };\n\t\t\t}\tcatch (error) {\n\t\t\t\t\tthrow \"JsonPretty error: \" + error.message;\n\t\t\t}\n\t\t},\n\t\t\n\t\tpretty: { // from https://github.com/RyanAmos/Pretty-JSON/blob/master/pretty_json.js\n\t\t\t\"expando\" : function(value) {\n\t\t\t\treturn (value && (/array|object/i).test(value.constructor.name)) ? \"expando\" : \"\";\n\t\t\t},\n\t\t\t\"parse\": function (member) {\n\t\t\t\treturn this[(member == null) ? 'null' : member.constructor.name.toLowerCase()](member);\n\t\t\t},\n\t\t\t\"null\": function (value) {\n\t\t\t\treturn this['value']('null', 'null');\n\t\t\t},\n\t\t\t\"array\": function (value) {\n\t\t\t\tvar results = [];\n\t\t\t\tvar lastItem = value.length - 1;\n\t\t\t\tvalue.forEach(function( v, i ) {\n\t\t\t\t\tresults.push({ tag: \"LI\", cls: this.expando(v), children: [ this['parse'](v) ] });\n\t\t\t\t\tif( i !== lastItem ) {\n\t\t\t\t\t\tresults.push(\",\");\n\t\t\t\t\t}\n\t\t\t\t}, this);\n\t\t\t\treturn [ \"[ \", ((results.length > 0) ? { tag: \"UL\", cls: \"uiJsonPretty-array\", children: results } : null), \"]\" ];\n\t\t\t},\n\t\t\t\"object\": function (value) {\n\t\t\t\tvar results = [];\n\t\t\t\tvar keys = Object.keys( value );\n\t\t\t\tvar lastItem = keys.length - 1;\n\t\t\t\tkeys.forEach( function( key, i ) {\n\t\t\t\t\tvar children = [ this['value']( 'name', '\"' + key + '\"' ), \": \", this['parse']( value[ key ]) ];\n\t\t\t\t\tif( i !== lastItem ) {\n\t\t\t\t\t\tchildren.push(\",\");\n\t\t\t\t\t}\n\t\t\t\t\tresults.push( { tag: \"LI\", cls: this.expando( value[ key ] ), children: children } );\n\t\t\t\t}, this);\n\t\t\t\treturn [ \"{ \", ((results.length > 0) ? { tag: \"UL\", cls: \"uiJsonPretty-object\", children: results } : null ),  \"}\" ];\n\t\t\t},\n\t\t\t\"number\": function (value) {\n\t\t\t\treturn this['value']('number', value.toString());\n\t\t\t},\n\t\t\t\"string\": function (value) {\n\t\t\t\tif (/^(http|https|file):\\/\\/[^\\s]+$/.test(value)) {\n\t\t\t\t\treturn this['link']( value );\n\t\t\t\t} else {\n\t\t\t\t\treturn this['value']('string', '\"' + value.toString() + '\"');\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"boolean\": function (value) {\n\t\t\t\treturn this['value']('boolean', value.toString());\n\t\t\t},\n\t\t\t\"link\": function( value ) {\n\t\t\t\t\treturn this['value'](\"string\", { tag: \"A\", href: value, target: \"_blank\", text: '\"' + value + '\"' } );\n\t\t\t},\n\t\t\t\"value\": function (type, value) {\n\t\t\t\tif (/^(http|https|file):\\/\\/[^\\s]+$/.test(value)) {\n\t\t\t\t}\n\t\t\t\treturn { tag: \"SPAN\", cls: \"uiJsonPretty-\" + type, text: value };\n\t\t\t}\n\t\t}\n\t});\n\n})( this.jQuery, this.app );\n"
  },
  {
    "path": "src/app/ui/menuButton/menuButton.css",
    "content": ".uiMenuButton {\n\tdisplay: inline-block;\n}\n\n.uiMenuButton .uiButton-label {\n\tbackground-image: url('data:image/gif;base64,R0lGODlhDwAPAIABAP///////yH5BAEAAAEALAAAAAAPAA8AAAITjI+py+0P4wG0gmavq1HLD4ZiAQA7');\n\tbackground-position: right 50%;\n\tbackground-repeat: no-repeat;\n\tpadding-right: 17px;\n\ttext-align: left;\n}\n"
  },
  {
    "path": "src/app/ui/menuButton/menuButton.js",
    "content": "(function( $, app ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.MenuButton = app.ui.Button.extend({\n\t\tdefaults: {\n\t\t\tmenu: null\n\t\t},\n\t\t_baseCls: \"uiButton uiMenuButton\",\n\t\tinit: function(parent) {\n\t\t\tthis._super(parent);\n\t\t\tthis.menu = this.config.menu;\n\t\t\tthis.on(\"click\", this.openMenu_handler);\n\t\t\tthis.menu.on(\"open\", function() { this.el.addClass(\"active\"); }.bind(this));\n\t\t\tthis.menu.on(\"close\", function() { this.el.removeClass(\"active\"); }.bind(this));\n\t\t},\n\t\topenMenu_handler: function(jEv) {\n\t\t\tthis.menu && this.menu.open(jEv);\n\t\t}\n\t});\n\n})( this.jQuery, this.app );\n"
  },
  {
    "path": "src/app/ui/menuPanel/menuPanel.css",
    "content": ".uiMenuPanel {\n\tborder: 1px solid #668dc6;\n\tposition: absolute;\n\tbackground: #96c6eb;\n\tcolor: white;\n}\n\n.uiMenuPanel LI {\n\tlist-style: none;\n\tborder-bottom: 1px solid #668dc6;\n}\n\n.uiMenuPanel LI:hover {\n\tbackground: #2575b7;\n}\n\n.uiMenuPanel LI:last-child {\n\tborder-bottom: 0;\n} \n\n.uiMenuPanel-label {\n\twhite-space: nowrap;\n\tpadding: 2px 10px 2px 10px;\n\tcursor: pointer;\n}\n\n.disabled .uiMenuPanel-label {\n\tcursor: auto;\n\tcolor: #888;\n}\n"
  },
  {
    "path": "src/app/ui/menuPanel/menuPanel.js",
    "content": "(function( app ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.MenuPanel = ui.AbstractPanel.extend({\n\t\tdefaults: {\n\t\t\titems: [],\t\t// (required) an array of menu items\n\t\t\tmodal: false\n\t\t},\n\t\t_baseCls: \"uiMenuPanel\",\n\t\tinit: function() {\n\t\t\tthis._super();\n\t\t\tthis.el = $(this._main_template());\n\t\t},\n\t\topen: function(jEv) {\n\t\t\tthis._super(jEv);\n\t\t\tvar cx = this; setTimeout(function() { $(document).bind(\"click\", cx._close_handler); }, 50);\n\t\t},\n\t\t_getItems: function() {\n\t\t\treturn this.config.items;\n\t\t},\n\t\t_close_handler: function(jEv) {\n\t\t\tthis._super(jEv);\n\t\t\t$(document).unbind(\"click\", this._close_handler);\n\t\t},\n\t\t_main_template: function() {\n\t\t\treturn { tag: \"DIV\", cls: this._baseCls, children: this._getItems().map(this._menuItem_template, this) };\n\t\t},\n\t\t_menuItem_template: function(item) {\n\t\t\tvar dx = item.disabled ? { onclick: function() {} } : {};\n\t\t\treturn { tag: \"LI\", cls: \"uiMenuPanel-item\" + (item.disabled ? \" disabled\" : \"\") + (item.selected ? \" selected\" : \"\"), children: [ $.extend({ tag: \"DIV\", cls: \"uiMenuPanel-label\" }, item, dx ) ] };\n\t\t},\n\t\t_getPosition: function(jEv) {\n\t\t\tvar right = !! $(jEv.target).parents(\".pull-right\").length;\n\t\t\tvar parent = $(jEv.target).closest(\"BUTTON\");\n\t\t\treturn parent.vOffset()\n\t\t\t\t.addY(parent.vSize().y)\n\t\t\t\t.addX( right ? parent.vSize().x - this.el.vOuterSize().x : 0 )\n\t\t\t\t.asOffset();\n\t\t}\n\t});\n\n})( this.app );\n"
  },
  {
    "path": "src/app/ui/nodesView/nodesView.css",
    "content": ".uiNodesView TH,\n.uiNodesView TD {\n\tvertical-align: top;\n\tpadding: 2px 20px;\n}\n\n.uiNodesView TH.close,\n.uiNodesView TD.close {\n\tcolor: #888;\n\tbackground: #f2f2f2;\n}\n\n.uiNodesView .uiMenuButton .uiButton-content {\n\tpadding-right: 3px;\n\tborder-radius: 8px;\n\theight: 14px;\n}\n\n.uiNodesView .uiMenuButton.active .uiButton-content,\n.uiNodesView .uiMenuButton:active .uiButton-content {\n\tborder-bottom-right-radius: 0px;\n\tborder-bottom-left-radius: 0px;\n}\n\n.uiNodesView .uiMenuButton .uiButton-label {\n\tpadding: 0px 17px 0px 7px;\n}\n\n.uiNodesView-hasAlias {\n\ttext-align: center;\n}\n.uiNodesView-hasAlias.max {\n\tborder-top-right-radius: 8px;\n\tborder-bottom-right-radius: 8px;\n}\n.uiNodesView-hasAlias.min {\n\tborder-top-left-radius: 8px;\n\tborder-bottom-left-radius: 8px;\n}\n.uiNodesView-hasAlias-remove {\n\tfloat: right;\n\tfont-weight: bold;\n\tcursor: pointer;\n}\n\n.uiNodesView TD.uiNodesView-icon {\n\tpadding: 20px 0px 15px 20px;\n}\n\n.uiNodesView-node:nth-child(odd) {\n\tbackground: #eee;\n}\n\n.uiNodesView-routing {\n\tposition: relative;\n\tmin-width: 90px;\n}\n\n.uiNodesView-nullReplica,\n.uiNodesView-replica {\n\tbox-sizing: border-box;\n\tcursor: pointer;\n\tfloat: left;\n\theight: 40px;\n\twidth: 35px;\n\tmargin: 4px;\n\tborder: 2px solid #444;\n\tpadding: 2px;\n\tfont-size: 32px;\n\tline-height: 32px;\n\ttext-align: center;\n\tletter-spacing: -5px;\n\ttext-indent: -7px;\n}\n\n.uiNodesView-replica.primary {\n\tborder-width: 4px;\n\tline-height: 29px;\n}\n\n.uiNodesView-nullReplica {\n\tborder-color: transparent;\n}\n\n.uiNodesView-replica.state-UNASSIGNED { background: #eeeeee; color: #999; border-color: #666; float: none; display: inline-block; }\n.uiNodesView-replica.state-INITIALIZING { background: #dddc88; }\n.uiNodesView-replica.state-STARTED { background: #99dd88; }\n.uiNodesView-replica.state-RELOCATING { background: #dc88dd; }\n"
  },
  {
    "path": "src/app/ui/nodesView/nodesView.js",
    "content": "(function( app, i18n, joey ) {\n\n\tvar ui = app.ns(\"ui\");\n\tvar ut = app.ns(\"ut\");\n\n\tui.NodesView = ui.AbstractWidget.extend({\n\t\tdefaults: {\n\t\t\tinteractive: true,\n\t\t\taliasRenderer: \"list\",\n\t\t\tscaleReplicas: 1,\n\t\t\tcluster: null,\n\t\t\tdata: null\n\t\t},\n\t\tinit: function() {\n\t\t\tthis._super();\n\t\t\tthis.interactive = this.config.interactive;\n\t\t\tthis.cluster = this.config.cluster;\n\t\t\tthis._aliasRenderFunction = {\n\t\t\t\t\"none\": this._aliasRender_template_none,\n\t\t\t\t\"list\": this._aliasRender_template_list,\n\t\t\t\t\"full\": this._aliasRender_template_full\n\t\t\t}[ this.config.aliasRenderer ];\n\t\t\tthis._styleSheetEl = joey({ tag: \"STYLE\", text: \".uiNodesView-nullReplica, .uiNodesView-replica { zoom: \" + this.config.scaleReplicas + \" }\" });\n\t\t\tthis.el = $( this._main_template( this.config.data.cluster, this.config.data.indices ) );\n\t\t},\n\n\t\t_newAliasAction_handler: function( index ) {\n\t\t\tvar fields = new app.ux.FieldCollection({\n\t\t\t\tfields: [\n\t\t\t\t\tnew ui.TextField({ label: i18n.text(\"AliasForm.AliasName\"), name: \"alias\", require: true })\n\t\t\t\t]\n\t\t\t});\n\t\t\tvar dialog = new ui.DialogPanel({\n\t\t\t\ttitle: i18n.text(\"AliasForm.NewAliasForIndexName\", index.name),\n\t\t\t\tbody: new ui.PanelForm({ fields: fields }),\n\t\t\t\tonCommit: function(panel, args) {\n\t\t\t\t\tif(fields.validate()) {\n\t\t\t\t\t\tvar data = fields.getData();\n\t\t\t\t\t\tvar command = {\n\t\t\t\t\t\t\t\"actions\" : [\n\t\t\t\t\t\t\t\t{ \"add\" : { \"index\" : index.name, \"alias\" : data[\"alias\"] } }\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t};\n\t\t\t\t\t\tthis.config.cluster.post('_aliases', JSON.stringify(command), function(d) {\n\t\t\t\t\t\t\tdialog.close();\n\t\t\t\t\t\t\talert(JSON.stringify(d));\n\t\t\t\t\t\t\tthis.fire(\"redraw\");\n\t\t\t\t\t\t}.bind(this) );\n\t\t\t\t\t}\n\t\t\t\t}.bind(this)\n\t\t\t}).open();\n\t\t},\n\t\t_postIndexAction_handler: function(action, index, redraw) {\n\t\t\tthis.cluster.post(encodeURIComponent( index.name ) + \"/\" + encodeURIComponent( action ), null, function(r) {\n\t\t\t\talert(JSON.stringify(r));\n\t\t\t\tredraw && this.fire(\"redraw\");\n\t\t\t}.bind(this));\n\t\t},\n\t\t_optimizeIndex_handler: function(index) {\n\t\t\tvar fields = new app.ux.FieldCollection({\n\t\t\t\tfields: [\n\t\t\t\t\tnew ui.TextField({ label: i18n.text(\"OptimizeForm.MaxSegments\"), name: \"max_num_segments\", value: \"1\", require: true }),\n\t\t\t\t\tnew ui.CheckField({ label: i18n.text(\"OptimizeForm.ExpungeDeletes\"), name: \"only_expunge_deletes\", value: false }),\n\t\t\t\t\tnew ui.CheckField({ label: i18n.text(\"OptimizeForm.FlushAfter\"), name: \"flush\", value: true }),\n\t\t\t\t\tnew ui.CheckField({ label: i18n.text(\"OptimizeForm.WaitForMerge\"), name: \"wait_for_merge\", value: false })\n\t\t\t\t]\n\t\t\t});\n\t\t\tvar dialog = new ui.DialogPanel({\n\t\t\t\ttitle: i18n.text(\"OptimizeForm.OptimizeIndex\", index.name),\n\t\t\t\tbody: new ui.PanelForm({ fields: fields }),\n\t\t\t\tonCommit: function( panel, args ) {\n\t\t\t\t\tif(fields.validate()) {\n\t\t\t\t\t\tthis.cluster.post(encodeURIComponent( index.name ) + \"/_optimize\", fields.getData(), function(r) {\n\t\t\t\t\t\t\talert(JSON.stringify(r));\n\t\t\t\t\t\t});\n\t\t\t\t\t\tdialog.close();\n\t\t\t\t\t}\n\t\t\t\t}.bind(this)\n\t\t\t}).open();\n\t\t},\n\t\t_forceMergeIndex_handler: function(index) {\n                        var fields = new app.ux.FieldCollection({\n                                fields: [\n                                        new ui.TextField({ label: i18n.text(\"ForceMergeForm.MaxSegments\"), name: \"max_num_segments\", value: \"1\", require: true }),\n                                        new ui.CheckField({ label: i18n.text(\"ForceMergeForm.ExpungeDeletes\"), name: \"only_expunge_deletes\", value: false }),\n                                        new ui.CheckField({ label: i18n.text(\"ForceMergeForm.FlushAfter\"), name: \"flush\", value: true })\n                                ]\n                        });\n                        var dialog = new ui.DialogPanel({\n                                title: i18n.text(\"ForceMergeForm.ForceMergeIndex\", index.name),\n                                body: new ui.PanelForm({ fields: fields }),\n                                onCommit: function( panel, args ) {\n                                        if(fields.validate()) {\n\n                                                this.cluster.post(encodeURIComponent( index.name ) + \"/_forcemerge?\"+jQuery.param(fields.getData()), null, function(r) {\n                                                        alert(JSON.stringify(r));\n                                                });\n                                                dialog.close();\n                                        }\n                                }.bind(this)\n                        }).open();\n\t\t},\n\t\t_testAnalyser_handler: function(index) {\n\t\t\tif(this.cluster._version_parts[0] <= 5) {\n\t\t\t\tthis.cluster.get(encodeURIComponent( index.name ) + \"/_analyze?text=\" + encodeURIComponent( prompt( i18n.text(\"IndexCommand.TextToAnalyze\") ) ), function(r) {\n\t\t\t\t\tnew ui.JsonPanel({ json: r, title: \"\" });\n\t\t\t\t}); \n\t\t\t} else {\n\t\t\t\tvar command = {\n\t\t\t\t\t\"analyzer\" : prompt( i18n.text(\"IndexCommand.AnalyzerToUse\") ),\n\t\t\t\t\t\"text\": prompt( i18n.text(\"IndexCommand.TextToAnalyze\") )\n\t\t\t\t};\n\t\t\t\tthis.cluster.post(encodeURIComponent(index.name) + \"/_analyze\", JSON.stringify(command), function(r) {\n\t\t\t\t\tnew ui.JsonPanel({ json: r, title: \"\" });\n\t\t\t\t});\n\t\t\t}\t\t\n\t\t},\n\t\t_deleteIndexAction_handler: function(index) {\n\t\t\tif( prompt( i18n.text(\"AliasForm.DeleteAliasMessage\", i18n.text(\"Command.DELETE\"), index.name ) ) === i18n.text(\"Command.DELETE\") ) {\n\t\t\t\tthis.cluster[\"delete\"](encodeURIComponent( index.name ), null, function(r) {\n\t\t\t\t\talert(JSON.stringify(r));\n\t\t\t\t\tthis.fire(\"redraw\");\n\t\t\t\t}.bind(this) );\n\t\t\t}\n\t\t},\n\t\t_shutdownNode_handler: function(node) {\n\t\t\tif(prompt( i18n.text(\"IndexCommand.ShutdownMessage\", i18n.text(\"Command.SHUTDOWN\"), node.cluster.name ) ) === i18n.text(\"Command.SHUTDOWN\") ) {\n\t\t\t\tthis.cluster.post( \"_cluster/nodes/\" + encodeURIComponent( node.name ) + \"/_shutdown\", null, function(r) {\n\t\t\t\t\talert(JSON.stringify(r));\n\t\t\t\t\tthis.fire(\"redraw\");\n\t\t\t\t}.bind(this));\n\t\t\t}\n\t\t},\n\t\t_deleteAliasAction_handler: function( index, alias ) {\n\t\t\tif( confirm( i18n.text(\"Command.DeleteAliasMessage\" ) ) ) {\n\t\t\t\tvar command = {\n\t\t\t\t\t\"actions\" : [\n\t\t\t\t\t\t{ \"remove\" : { \"index\" : index.name, \"alias\" : alias.name } }\n\t\t\t\t\t]\n\t\t\t\t};\n\t\t\t\tthis.config.cluster.post('_aliases', JSON.stringify(command), function(d) {\n\t\t\t\t\talert(JSON.stringify(d));\n\t\t\t\t\tthis.fire(\"redraw\");\n\t\t\t\t}.bind(this) );\n\t\t\t}\n\t\t},\n\n\t\t_replica_template: function(replica) {\n\t\t\tvar r = replica.replica;\n\t\t\treturn { tag: \"DIV\",\n\t\t\t\tcls: \"uiNodesView-replica\" + (r.primary ? \" primary\" : \"\") + ( \" state-\" + r.state ),\n\t\t\t\ttext: r.shard.toString(),\n\t\t\t\tonclick: function() { new ui.JsonPanel({\n\t\t\t\t\tjson: replica.status || r,\n\t\t\t\t\ttitle: r.index + \"/\" + r.node + \" [\" + r.shard + \"]\" });\n\t\t\t\t}\n\t\t\t};\n\t\t},\n\t\t_routing_template: function(routing) {\n\t\t\tvar cell = { tag: \"TD\", cls: \"uiNodesView-routing\" + (routing.open ? \"\" : \" close\"), children: [] };\n\t\t\tfor(var i = 0; i < routing.replicas.length; i++) {\n\t\t\t\tif(i % routing.max_number_of_shards === 0 && i > 0) {\n\t\t\t\t\tcell.children.push({ tag: \"BR\" });\n\t\t\t\t}\n\t\t\t\tif( routing.replicas[i] ) {\n\t\t\t\t\tcell.children.push(this._replica_template(routing.replicas[i]));\n\t\t\t\t} else {\n\t\t\t\t\tcell.children.push( { tag: \"DIV\", cls: \"uiNodesView-nullReplica\" } );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn cell;\n\t\t},\n\t\t_nodeControls_template: function( node ) { return (\n\t\t\t{ tag: \"DIV\", cls: \"uiNodesView-controls\", children: [\n\t\t\t\tnew ui.MenuButton({\n\t\t\t\t\tlabel: i18n.text(\"NodeInfoMenu.Title\"),\n\t\t\t\t\tmenu: new ui.MenuPanel({\n\t\t\t\t\t\titems: [\n\t\t\t\t\t\t\t{ text: i18n.text(\"NodeInfoMenu.ClusterNodeInfo\"), onclick: function() { new ui.JsonPanel({ json: node.cluster, title: node.name });} },\n\t\t\t\t\t\t\t{ text: i18n.text(\"NodeInfoMenu.NodeStats\"), onclick: function() { new ui.JsonPanel({ json: node.stats, title: node.name });} }\n\t\t\t\t\t\t]\n\t\t\t\t\t})\n\t\t\t\t}),\n\t\t\t\tnew ui.MenuButton({\n\t\t\t\t\tlabel: i18n.text(\"NodeActionsMenu.Title\"),\n\t\t\t\t\tmenu: new ui.MenuPanel({\n\t\t\t\t\t\titems: [\n\t\t\t\t\t\t\t{ text: i18n.text(\"NodeActionsMenu.Shutdown\"), onclick: function() { this._shutdownNode_handler(node); }.bind(this) }\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_nodeIcon_template: function( node ) {\n\t\t\tvar icon, alt;\n\t\t\tif( node.name === \"Unassigned\" ) {\n\t\t\t\ticon = \"fa-exclamation-triangle\";\n\t\t\t\talt = i18n.text( \"NodeType.Unassigned\" );\n\t\t\t} else if( node.cluster.settings && \"tribe\" in node.cluster.settings) {\n\t\t\t\ticon = \"fa-sitemap\";\n\t\t\t\talt = i18n.text(\"NodeType.Tribe\" );\n\t\t\t} else {\n\t\t\t\ticon = \"fa-\" + (node.master_node ? \"star\" : \"circle\") + (node.data_node ? \"\" : \"-o\" );\n\t\t\t\talt = i18n.text( node.master_node ? ( node.data_node ? \"NodeType.Master\" : \"NodeType.Coord\" ) : ( node.data_node ? \"NodeType.Worker\" : \"NodeType.Client\" ) );\n\t\t\t}\n\t\t\treturn { tag: \"TD\", title: alt, cls: \"uiNodesView-icon\", children: [\n\t\t\t\t{ tag: \"SPAN\", cls: \"fa fa-2x \" + icon }\n\t\t\t] };\n\t\t},\n\t\t_node_template: function(node) {\n\t\t\treturn { tag: \"TR\", cls: \"uiNodesView-node\" + (node.master_node ? \" master\": \"\"), children: [\n\t\t\t\tthis._nodeIcon_template( node ),\n\t\t\t\t{ tag: \"TH\", children: node.name === \"Unassigned\" ? [\n\t\t\t\t\t{ tag: \"H3\", text: node.name }\n\t\t\t\t] : [\n\t\t\t\t\t{ tag: \"H3\", text: node.cluster.name },\n\t\t\t\t\t{ tag: \"DIV\", text: node.cluster.hostname },\n\t\t\t\t\tthis.interactive ? this._nodeControls_template( node ) : null\n\t\t\t\t] }\n\t\t\t].concat(node.routings.map(this._routing_template, this))};\n\t\t},\n\t\t_indexHeaderControls_template: function( index ) { return (\n\t\t\t{ tag: \"DIV\", cls: \"uiNodesView-controls\", children: [\n\t\t\t\tnew ui.MenuButton({\n\t\t\t\t\tlabel: i18n.text(\"IndexInfoMenu.Title\"),\n\t\t\t\t\tmenu: new ui.MenuPanel({\n\t\t\t\t\t\titems: [\n\t\t\t\t\t\t\t{ text: i18n.text(\"IndexInfoMenu.Status\"), onclick: function() { new ui.JsonPanel({ json: index.status, title: index.name }); } },\n\t\t\t\t\t\t\t{ text: i18n.text(\"IndexInfoMenu.Metadata\"), onclick: function() { new ui.JsonPanel({ json: index.metadata, title: index.name }); } }\n\t\t\t\t\t\t]\n\t\t\t\t\t})\n\t\t\t\t}),\n\t\t\t\tnew ui.MenuButton({\n\t\t\t\t\tlabel: i18n.text(\"IndexActionsMenu.Title\"),\n\t\t\t\t\tmenu: new ui.MenuPanel({\n\t\t\t\t\t\titems: [\n\t\t\t\t\t\t\t{ text: i18n.text(\"IndexActionsMenu.NewAlias\"), onclick: function() { this._newAliasAction_handler(index); }.bind(this) },\n\t\t\t\t\t\t\t{ text: i18n.text(\"IndexActionsMenu.Refresh\"), onclick: function() { this._postIndexAction_handler(\"_refresh\", index, false); }.bind(this) },\n\t\t\t\t\t\t\t{ text: i18n.text(\"IndexActionsMenu.Flush\"), onclick: function() { this._postIndexAction_handler(\"_flush\", index, false); }.bind(this) },\n\t\t\t\t\t\t\t{ text: this.cluster.versionAtLeast(\"5.0.0.\") ? i18n.text(\"IndexActionsMenu.ForceMerge\") : i18n.text(\"IndexActionsMenu.Optimize\"), onclick: this.cluster.versionAtLeast(\"5.0.0.\") ? function () { this._forceMergeIndex_handler(index); }.bind(this) : function () { this._optimizeIndex_handler(index); }.bind(this) },\n\t\t\t\t\t\t\t{ text: i18n.text(\"IndexActionsMenu.Snapshot\"), disabled: closed, onclick: function() { this._postIndexAction_handler(\"_gateway/snapshot\", index, false); }.bind(this) },\n\t\t\t\t\t\t\t{ text: i18n.text(\"IndexActionsMenu.Analyser\"), onclick: function() { this._testAnalyser_handler(index); }.bind(this) },\n\t\t\t\t\t\t\t{ text: (index.state === \"close\") ? i18n.text(\"IndexActionsMenu.Open\") : i18n.text(\"IndexActionsMenu.Close\"), onclick: function() { this._postIndexAction_handler((index.state === \"close\") ? \"_open\" : \"_close\", index, true); }.bind(this) },\n\t\t\t\t\t\t\t{ text: i18n.text(\"IndexActionsMenu.Delete\"), onclick: function() { this._deleteIndexAction_handler(index); }.bind(this) }\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_indexHeader_template: function( index ) {\n\t\t\tvar closed = index.state === \"close\";\n\t\t\tvar line1 = closed ? \"index: close\" : ( \"size: \" + (index.status && index.status.primaries && index.status.total ? ut.byteSize_template( index.status.primaries.store.size_in_bytes ) + \" (\" + ut.byteSize_template( index.status.total.store.size_in_bytes ) + \")\" : \"unknown\" ) );\n\t\t\tvar line2 = closed ? \"\\u00A0\" : ( \"docs: \" + (index.status && index.status.primaries && index.status.primaries.docs && index.status.total && index.status.total.docs ? index.status.primaries.docs.count.toLocaleString() + \" (\" + (index.status.total.docs.count + index.status.total.docs.deleted).toLocaleString() + \")\" : \"unknown\" ) );\n\t\t\treturn index.name ? { tag: \"TH\", cls: (closed ? \"close\" : \"\"), children: [\n\t\t\t\t{ tag: \"H3\", text: index.name },\n\t\t\t\t{ tag: \"DIV\", text: line1 },\n\t\t\t\t{ tag: \"DIV\", text: line2 },\n\t\t\t\tthis.interactive ? this._indexHeaderControls_template( index ) : null\n\t\t\t] } : [ { tag: \"TD\" }, { tag: \"TH\" } ];\n\t\t},\n\t\t_aliasRender_template_none: function( cluster, indices ) {\n\t\t\treturn null;\n\t\t},\n\t\t_aliasRender_template_list: function( cluster, indices ) {\n\t\t\treturn cluster.aliases.length && { tag: \"TBODY\", children: [\n\t\t\t\t{ tag: \"TR\", children: [\n\t\t\t\t\t{ tag: \"TD\" }\n\t\t\t\t].concat( indices.map( function( index ) {\n\t\t\t\t\treturn { tag: \"TD\", children: index.metadata && index.metadata.aliases.map( function( alias ) {\n\t\t\t\t\t\treturn { tag: \"LI\", text: alias };\n\t\t\t\t\t} ) };\n\t\t\t\t})) }\n\t\t\t] };\n\t\t},\n\t\t_aliasRender_template_full: function( cluster, indices ) {\n\t\t\treturn cluster.aliases.length && { tag: \"TBODY\", children: cluster.aliases.map( function(alias, row) {\n\t\t\t\treturn { tag: \"TR\", children: [ { tag: \"TD\" },{ tag: \"TD\" } ].concat(alias.indices.map(function(index, i) {\n\t\t\t\t\tif (index) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttag: \"TD\",\n\t\t\t\t\t\t\tcss: { background: \"#\" + \"9ce9c7fc9\".substr((row+6)%7,3) },\n\t\t\t\t\t\t\tcls: \"uiNodesView-hasAlias\" + ( alias.min === i ? \" min\" : \"\" ) + ( alias.max === i ? \" max\" : \"\" ),\n\t\t\t\t\t\t\ttext: alias.name,\n\t\t\t\t\t\t\tchildren: this.interactive ? [\n\t\t\t\t\t\t\t\t{\ttag: 'SPAN',\n\t\t\t\t\t\t\t\t\ttext: i18n.text(\"General.CloseGlyph\"),\n\t\t\t\t\t\t\t\t\tcls: 'uiNodesView-hasAlias-remove',\n\t\t\t\t\t\t\t\t\tonclick: this._deleteAliasAction_handler.bind( this, index, alias )\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t]: null\n\t\t\t\t\t\t};\n\t\t\t\t\t}\telse {\n\t\t\t\t\t\treturn { tag: \"TD\" };\n\t\t\t\t\t}\n\t\t\t\t}, this ) ) };\n\t\t\t}, this )\t};\n\t\t},\n\t\t_main_template: function(cluster, indices) {\n\t\t\treturn { tag: \"TABLE\", cls: \"table uiNodesView\", children: [\n\t\t\t\tthis._styleSheetEl,\n\t\t\t\t{ tag: \"THEAD\", children: [ { tag: \"TR\", children: indices.map(this._indexHeader_template, this) } ] },\n\t\t\t\tthis._aliasRenderFunction( cluster, indices ),\n\t\t\t\t{ tag: \"TBODY\", children: cluster.nodes.map(this._node_template, this) }\n\t\t\t] };\n\t\t}\n\n\t});\n\n})( this.app, this.i18n, this.joey );\n"
  },
  {
    "path": "src/app/ui/nodesView/nodesViewDemo.js",
    "content": "$( function() {\n\n\tvar ui = window.app.ns(\"ui\");\n\n\tvar data = {\n\t\t\"cluster\":{\"nodes\":[{\"name\":\"cqTmT9GLSlSWx-B7pvM--w\",\"routings\":[{\"name\":\"_river\",\"replicas\":[],\"max_number_of_shards\":\"1\",\"open\":true},{\"name\":\"ag_01\",\"replicas\":[null,{\"replica\":{\"state\":\"STARTED\",\"primary\":true,\"node\":\"cqTmT9GLSlSWx-B7pvM--w\",\"relocating_node\":null,\"shard\":1,\"index\":\"ag_01\"},\"status\":{\"routing\":{\"state\":\"STARTED\",\"primary\":true,\"node\":\"cqTmT9GLSlSWx-B7pvM--w\",\"relocating_node\":null,\"shard\":1,\"index\":\"ag_01\"},\"state\":\"STARTED\",\"index\":{\"size\":\"99b\",\"size_in_bytes\":99},\"translog\":{\"id\":1381731712637,\"operations\":0},\"docs\":{\"num_docs\":10328420,\"max_doc\":10329720,\"deleted_docs\":4},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":1,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":7,\"total_time\":\"643ms\",\"total_time_in_millis\":643}}}],\"max_number_of_shards\":\"2\",\"open\":true},{\"name\":\"ag_02\",\"replicas\":[null,{\"replica\":{\"state\":\"STARTED\",\"primary\":false,\"node\":\"cqTmT9GLSlSWx-B7pvM--w\",\"relocating_node\":null,\"shard\":1,\"index\":\"ag_02\"},\"status\":{\"routing\":{\"state\":\"STARTED\",\"primary\":false,\"node\":\"cqTmT9GLSlSWx-B7pvM--w\",\"relocating_node\":null,\"shard\":1,\"index\":\"ag_02\"},\"state\":\"STARTED\",\"index\":{\"size\":\"79b\",\"size_in_bytes\":79},\"translog\":{\"id\":1381749663385,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":3,\"total_time\":\"75ms\",\"total_time_in_millis\":75}}}],\"max_number_of_shards\":\"3\",\"open\":true},{\"name\":\"ag_03\",\"replicas\":[null,{\"replica\":{\"state\":\"STARTED\",\"primary\":true,\"node\":\"cqTmT9GLSlSWx-B7pvM--w\",\"relocating_node\":null,\"shard\":1,\"index\":\"ag_03\"},\"status\":{\"routing\":{\"state\":\"STARTED\",\"primary\":true,\"node\":\"cqTmT9GLSlSWx-B7pvM--w\",\"relocating_node\":null,\"shard\":1,\"index\":\"ag_03\"},\"state\":\"STARTED\",\"index\":{\"size\":\"99b\",\"size_in_bytes\":99},\"translog\":{\"id\":1381731770058,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":1,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":7,\"total_time\":\"86ms\",\"total_time_in_millis\":86}}}],\"max_number_of_shards\":\"2\",\"open\":true},{\"name\":\"twitter_river\",\"replicas\":[],\"max_number_of_shards\":\"5\",\"open\":false}],\"master_node\":false,\"stats\":{\"timestamp\":1381790346979,\"name\":\"Elathan\",\"transport_address\":\"inet[/127.0.0.1:9301]\",\"hostname\":\"server\",\"indices\":{\"docs\":{\"count\":0,\"deleted\":0},\"store\":{\"size\":\"277b\",\"size_in_bytes\":277,\"throttle_time\":\"0s\",\"throttle_time_in_millis\":0},\"indexing\":{\"index_total\":0,\"index_time\":\"0s\",\"index_time_in_millis\":0,\"index_current\":0,\"delete_total\":0,\"delete_time\":\"0s\",\"delete_time_in_millis\":0,\"delete_current\":0},\"get\":{\"total\":0,\"get_time\":\"0s\",\"time_in_millis\":0,\"exists_total\":0,\"exists_time\":\"0s\",\"exists_time_in_millis\":0,\"missing_total\":0,\"missing_time\":\"0s\",\"missing_time_in_millis\":0,\"current\":0},\"search\":{\"open_contexts\":0,\"query_total\":6,\"query_time\":\"19ms\",\"query_time_in_millis\":19,\"query_current\":0,\"fetch_total\":0,\"fetch_time\":\"0s\",\"fetch_time_in_millis\":0,\"fetch_current\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":10,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":186,\"total_time\":\"9.1s\",\"total_time_in_millis\":9191},\"warmer\":{\"current\":0,\"total\":3,\"total_time\":\"6ms\",\"total_time_in_millis\":6},\"filter_cache\":{\"memory_size\":\"0b\",\"memory_size_in_bytes\":0,\"evictions\":0},\"id_cache\":{\"memory_size\":\"0b\",\"memory_size_in_bytes\":0},\"fielddata\":{\"memory_size\":\"0b\",\"memory_size_in_bytes\":0,\"evictions\":0},\"completion\":{\"size\":\"0b\",\"size_in_bytes\":0}},\"os\":{\"timestamp\":1381790346979,\"uptime\":\"15.5m\",\"uptime_in_millis\":932146,\"load_average\":[1.79736328125,1.95166015625,1.904296875],\"cpu\":{\"sys\":22,\"user\":6,\"idle\":70,\"stolen\":0},\"mem\":{\"free\":\"3.7gb\",\"free_in_bytes\":4065169408,\"used\":\"4.2gb\",\"used_in_bytes\":4524765184,\"free_percent\":51,\"used_percent\":48,\"actual_free\":\"4.1gb\",\"actual_free_in_bytes\":4426321920,\"actual_used\":\"3.8gb\",\"actual_used_in_bytes\":4163612672},\"swap\":{\"used\":\"2.8gb\",\"used_in_bytes\":3025272832,\"free\":\"1.1gb\",\"free_in_bytes\":1269694464}},\"process\":{\"timestamp\":1381790346979,\"open_file_descriptors\":266,\"cpu\":{\"percent\":0,\"sys\":\"2.8m\",\"sys_in_millis\":172614,\"user\":\"2.3m\",\"user_in_millis\":142295,\"total\":\"5.2m\",\"total_in_millis\":314909},\"mem\":{\"resident\":\"21.6mb\",\"resident_in_bytes\":22728704,\"share\":\"-1b\",\"share_in_bytes\":-1,\"total_virtual\":\"3.6gb\",\"total_virtual_in_bytes\":3900530688}},\"jvm\":{\"timestamp\":1381790346980,\"uptime\":\"4d\",\"uptime_in_millis\":349028405,\"mem\":{\"heap_used\":\"31.3mb\",\"heap_used_in_bytes\":32851896,\"heap_committed\":\"265.5mb\",\"heap_committed_in_bytes\":278462464,\"non_heap_used\":\"39.3mb\",\"non_heap_used_in_bytes\":41210896,\"non_heap_committed\":\"63.7mb\",\"non_heap_committed_in_bytes\":66809856,\"pools\":{\"Code Cache\":{\"used\":\"2mb\",\"used_in_bytes\":2120704,\"max\":\"48mb\",\"max_in_bytes\":50331648,\"peak_used\":\"2mb\",\"peak_used_in_bytes\":2131520,\"peak_max\":\"48mb\",\"peak_max_in_bytes\":50331648},\"Par Eden Space\":{\"used\":\"24mb\",\"used_in_bytes\":25224136,\"max\":\"66.5mb\",\"max_in_bytes\":69795840,\"peak_used\":\"27mb\",\"peak_used_in_bytes\":28311552,\"peak_max\":\"66.5mb\",\"peak_max_in_bytes\":69795840},\"Par Survivor Space\":{\"used\":\"816.5kb\",\"used_in_bytes\":836128,\"max\":\"8.3mb\",\"max_in_bytes\":8716288,\"peak_used\":\"2mb\",\"peak_used_in_bytes\":2162688,\"peak_max\":\"8.3mb\",\"peak_max_in_bytes\":8716288},\"CMS Old Gen\":{\"used\":\"6.4mb\",\"used_in_bytes\":6791632,\"max\":\"940.8mb\",\"max_in_bytes\":986513408,\"peak_used\":\"8.2mb\",\"peak_used_in_bytes\":8653824,\"peak_max\":\"940.8mb\",\"peak_max_in_bytes\":986513408},\"CMS Perm Gen\":{\"used\":\"37.2mb\",\"used_in_bytes\":39090192,\"max\":\"82mb\",\"max_in_bytes\":85983232,\"peak_used\":\"37.2mb\",\"peak_used_in_bytes\":39090192,\"peak_max\":\"82mb\",\"peak_max_in_bytes\":85983232}}},\"threads\":{\"count\":51,\"peak_count\":56},\"gc\":{\"collection_count\":43,\"collection_time\":\"374ms\",\"collection_time_in_millis\":374,\"collectors\":{\"ParNew\":{\"collection_count\":41,\"collection_time\":\"374ms\",\"collection_time_in_millis\":374},\"ConcurrentMarkSweep\":{\"collection_count\":2,\"collection_time\":\"0s\",\"collection_time_in_millis\":0}}}},\"thread_pool\":{\"generic\":{\"threads\":1,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":3,\"completed\":7505},\"index\":{\"threads\":0,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":0,\"completed\":0},\"get\":{\"threads\":0,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":0,\"completed\":0},\"snapshot\":{\"threads\":0,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":0,\"completed\":0},\"merge\":{\"threads\":0,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":0,\"completed\":0},\"suggest\":{\"threads\":0,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":0,\"completed\":0},\"bulk\":{\"threads\":0,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":0,\"completed\":0},\"optimize\":{\"threads\":0,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":0,\"completed\":0},\"warmer\":{\"threads\":1,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":1,\"completed\":16},\"flush\":{\"threads\":0,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":2,\"completed\":188},\"search\":{\"threads\":6,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":6,\"completed\":6},\"percolate\":{\"threads\":0,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":0,\"completed\":0},\"management\":{\"threads\":5,\"queue\":0,\"active\":1,\"rejected\":0,\"largest\":5,\"completed\":8593},\"refresh\":{\"threads\":0,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":0,\"completed\":0}},\"network\":{\"tcp\":{\"active_opens\":91033,\"passive_opens\":3206,\"curr_estab\":824,\"in_segs\":9438878,\"out_segs\":7330495,\"retrans_segs\":10420,\"estab_resets\":4179,\"attempt_fails\":2304,\"in_errs\":15,\"out_rsts\":-1}},\"fs\":{\"timestamp\":1381790347004,\"data\":[{\"path\":\"/var/elasticsearch/es2/data/elasticsearch/nodes/0\",\"mount\":\"/\",\"dev\":\"/dev/disk0s2\",\"total\":\"465.1gb\",\"total_in_bytes\":499418034176,\"free\":\"215.3gb\",\"free_in_bytes\":231241613312,\"available\":\"215.1gb\",\"available_in_bytes\":230979469312,\"disk_reads\":2641856,\"disk_writes\":3231915,\"disk_read_size\":\"75.9gb\",\"disk_read_size_in_bytes\":81593427456,\"disk_write_size\":\"76.2gb\",\"disk_write_size_in_bytes\":81856144384}]},\"transport\":{\"server_open\":60,\"rx_count\":155197,\"rx_size\":\"6.9mb\",\"rx_size_in_bytes\":7339947,\"tx_count\":155195,\"tx_size\":\"11.6mb\",\"tx_size_in_bytes\":12251491},\"http\":{\"current_open\":0,\"total_opened\":0}},\"cluster\":{\"name\":\"Elathan\",\"transport_address\":\"inet[/127.0.0.1:9301]\",\"hostname\":\"server\",\"version\":\"0.90.5\",\"http_address\":\"inet[server/127.0.0.1:9203]\"}},{\"name\":\"jw4owU-ZQgOYdM7ElauDTg\",\"routings\":[{\"name\":\"_river\",\"replicas\":[],\"max_number_of_shards\":\"1\",\"open\":true},{\"name\":\"ag_01\",\"replicas\":[null,{\"replica\":{\"state\":\"STARTED\",\"primary\":false,\"node\":\"jw4owU-ZQgOYdM7ElauDTg\",\"relocating_node\":null,\"shard\":1,\"index\":\"ag_01\"},\"status\":{\"routing\":{\"state\":\"STARTED\",\"primary\":false,\"node\":\"jw4owU-ZQgOYdM7ElauDTg\",\"relocating_node\":null,\"shard\":1,\"index\":\"ag_01\"},\"state\":\"STARTED\",\"index\":{\"size\":\"79b\",\"size_in_bytes\":79},\"translog\":{\"id\":1381731712637,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":6,\"total_time\":\"194ms\",\"total_time_in_millis\":194}}}],\"max_number_of_shards\":\"2\",\"open\":true},{\"name\":\"ag_02\",\"replicas\":[{\"replica\":{\"state\":\"STARTED\",\"primary\":true,\"node\":\"jw4owU-ZQgOYdM7ElauDTg\",\"relocating_node\":null,\"shard\":0,\"index\":\"ag_02\"},\"status\":{\"routing\":{\"state\":\"STARTED\",\"primary\":true,\"node\":\"jw4owU-ZQgOYdM7ElauDTg\",\"relocating_node\":null,\"shard\":0,\"index\":\"ag_02\"},\"state\":\"STARTED\",\"index\":{\"size\":\"99b\",\"size_in_bytes\":99},\"translog\":{\"id\":1381749663369,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":1,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":3,\"total_time\":\"107ms\",\"total_time_in_millis\":107}}}],\"max_number_of_shards\":\"3\",\"open\":true},{\"name\":\"ag_03\",\"replicas\":[],\"max_number_of_shards\":\"2\",\"open\":true},{\"name\":\"twitter_river\",\"replicas\":[],\"max_number_of_shards\":\"5\",\"open\":false}],\"master_node\":false,\"stats\":{\"timestamp\":1381790346963,\"name\":\"Numinus\",\"transport_address\":\"inet[/127.0.0.1:9303]\",\"hostname\":\"server\",\"indices\":{\"docs\":{\"count\":0,\"deleted\":0},\"store\":{\"size\":\"178b\",\"size_in_bytes\":178,\"throttle_time\":\"0s\",\"throttle_time_in_millis\":0},\"indexing\":{\"index_total\":2,\"index_time\":\"50ms\",\"index_time_in_millis\":50,\"index_current\":0,\"delete_total\":0,\"delete_time\":\"0s\",\"delete_time_in_millis\":0,\"delete_current\":0},\"get\":{\"total\":0,\"get_time\":\"0s\",\"time_in_millis\":0,\"exists_total\":0,\"exists_time\":\"0s\",\"exists_time_in_millis\":0,\"missing_total\":0,\"missing_time\":\"0s\",\"missing_time_in_millis\":0,\"current\":0},\"search\":{\"open_contexts\":0,\"query_total\":12,\"query_time\":\"32ms\",\"query_time_in_millis\":32,\"query_current\":0,\"fetch_total\":0,\"fetch_time\":\"0s\",\"fetch_time_in_millis\":0,\"fetch_current\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":9,\"total_time\":\"66ms\",\"total_time_in_millis\":66},\"flush\":{\"total\":218,\"total_time\":\"5.6s\",\"total_time_in_millis\":5697},\"warmer\":{\"current\":0,\"total\":2,\"total_time\":\"4ms\",\"total_time_in_millis\":4},\"filter_cache\":{\"memory_size\":\"0b\",\"memory_size_in_bytes\":0,\"evictions\":0},\"id_cache\":{\"memory_size\":\"0b\",\"memory_size_in_bytes\":0},\"fielddata\":{\"memory_size\":\"0b\",\"memory_size_in_bytes\":0,\"evictions\":0},\"completion\":{\"size\":\"0b\",\"size_in_bytes\":0}},\"os\":{\"timestamp\":1381790346963,\"uptime\":\"15.5m\",\"uptime_in_millis\":932146,\"load_average\":[1.79736328125,1.95166015625,1.904296875],\"cpu\":{\"sys\":22,\"user\":6,\"idle\":70,\"stolen\":0},\"mem\":{\"free\":\"3.7gb\",\"free_in_bytes\":4058091520,\"used\":\"4.2gb\",\"used_in_bytes\":4531843072,\"free_percent\":51,\"used_percent\":48,\"actual_free\":\"4.1gb\",\"actual_free_in_bytes\":4419244032,\"actual_used\":\"3.8gb\",\"actual_used_in_bytes\":4170690560},\"swap\":{\"used\":\"2.8gb\",\"used_in_bytes\":3025272832,\"free\":\"1.1gb\",\"free_in_bytes\":1269694464}},\"process\":{\"timestamp\":1381790346963,\"open_file_descriptors\":264,\"cpu\":{\"percent\":0,\"sys\":\"2.9m\",\"sys_in_millis\":174208,\"user\":\"2.3m\",\"user_in_millis\":139440,\"total\":\"5.2m\",\"total_in_millis\":313648},\"mem\":{\"resident\":\"27.2mb\",\"resident_in_bytes\":28606464,\"share\":\"-1b\",\"share_in_bytes\":-1,\"total_virtual\":\"3.6gb\",\"total_virtual_in_bytes\":3903823872}},\"jvm\":{\"timestamp\":1381790346978,\"uptime\":\"4d\",\"uptime_in_millis\":349026382,\"mem\":{\"heap_used\":\"12.8mb\",\"heap_used_in_bytes\":13428352,\"heap_committed\":\"265.5mb\",\"heap_committed_in_bytes\":278462464,\"non_heap_used\":\"39.8mb\",\"non_heap_used_in_bytes\":41791784,\"non_heap_committed\":\"55.2mb\",\"non_heap_committed_in_bytes\":57950208,\"pools\":{\"Code Cache\":{\"used\":\"1.9mb\",\"used_in_bytes\":2065280,\"max\":\"48mb\",\"max_in_bytes\":50331648,\"peak_used\":\"1.9mb\",\"peak_used_in_bytes\":2074880,\"peak_max\":\"48mb\",\"peak_max_in_bytes\":50331648},\"Par Eden Space\":{\"used\":\"2.4mb\",\"used_in_bytes\":2564176,\"max\":\"66.5mb\",\"max_in_bytes\":69795840,\"peak_used\":\"27mb\",\"peak_used_in_bytes\":28311552,\"peak_max\":\"66.5mb\",\"peak_max_in_bytes\":69795840},\"Par Survivor Space\":{\"used\":\"646.5kb\",\"used_in_bytes\":662048,\"max\":\"8.3mb\",\"max_in_bytes\":8716288,\"peak_used\":\"2.8mb\",\"peak_used_in_bytes\":3029584,\"peak_max\":\"8.3mb\",\"peak_max_in_bytes\":8716288},\"CMS Old Gen\":{\"used\":\"9.7mb\",\"used_in_bytes\":10202128,\"max\":\"940.8mb\",\"max_in_bytes\":986513408,\"peak_used\":\"9.7mb\",\"peak_used_in_bytes\":10202128,\"peak_max\":\"940.8mb\",\"peak_max_in_bytes\":986513408},\"CMS Perm Gen\":{\"used\":\"37.8mb\",\"used_in_bytes\":39726504,\"max\":\"82mb\",\"max_in_bytes\":85983232,\"peak_used\":\"37.8mb\",\"peak_used_in_bytes\":39726504,\"peak_max\":\"82mb\",\"peak_max_in_bytes\":85983232}}},\"threads\":{\"count\":60,\"peak_count\":66},\"gc\":{\"collection_count\":42,\"collection_time\":\"512ms\",\"collection_time_in_millis\":512,\"collectors\":{\"ParNew\":{\"collection_count\":40,\"collection_time\":\"512ms\",\"collection_time_in_millis\":512},\"ConcurrentMarkSweep\":{\"collection_count\":2,\"collection_time\":\"0s\",\"collection_time_in_millis\":0}}}},\"thread_pool\":{\"generic\":{\"threads\":1,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":3,\"completed\":7490},\"index\":{\"threads\":2,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":2,\"completed\":2},\"get\":{\"threads\":0,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":0,\"completed\":0},\"snapshot\":{\"threads\":1,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":1,\"completed\":2},\"merge\":{\"threads\":1,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":1,\"completed\":2},\"suggest\":{\"threads\":0,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":0,\"completed\":0},\"bulk\":{\"threads\":0,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":0,\"completed\":0},\"optimize\":{\"threads\":0,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":0,\"completed\":0},\"warmer\":{\"threads\":1,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":1,\"completed\":18},\"flush\":{\"threads\":0,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":2,\"completed\":221},\"search\":{\"threads\":12,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":12,\"completed\":12},\"percolate\":{\"threads\":0,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":0,\"completed\":0},\"management\":{\"threads\":3,\"queue\":0,\"active\":1,\"rejected\":0,\"largest\":5,\"completed\":8597},\"refresh\":{\"threads\":1,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":1,\"completed\":2}},\"network\":{\"tcp\":{\"active_opens\":91033,\"passive_opens\":3206,\"curr_estab\":824,\"in_segs\":9438878,\"out_segs\":7330495,\"retrans_segs\":10420,\"estab_resets\":4179,\"attempt_fails\":2304,\"in_errs\":15,\"out_rsts\":-1}},\"fs\":{\"timestamp\":1381790346992,\"data\":[{\"path\":\"/var/elasticsearch/es4/data/elasticsearch/nodes/0\",\"mount\":\"/\",\"dev\":\"/dev/disk0s2\",\"total\":\"465.1gb\",\"total_in_bytes\":499418034176,\"free\":\"215.3gb\",\"free_in_bytes\":231241613312,\"available\":\"215.1gb\",\"available_in_bytes\":230979469312,\"disk_reads\":2641856,\"disk_writes\":3231915,\"disk_read_size\":\"75.9gb\",\"disk_read_size_in_bytes\":81593427456,\"disk_write_size\":\"76.2gb\",\"disk_write_size_in_bytes\":81856144384}]},\"transport\":{\"server_open\":60,\"rx_count\":155179,\"rx_size\":\"7mb\",\"rx_size_in_bytes\":7341687,\"tx_count\":155177,\"tx_size\":\"11.6mb\",\"tx_size_in_bytes\":12249878},\"http\":{\"current_open\":0,\"total_opened\":0}},\"cluster\":{\"name\":\"Numinus\",\"transport_address\":\"inet[/127.0.0.1:9303]\",\"hostname\":\"server\",\"version\":\"0.90.5\",\"http_address\":\"inet[server/127.0.0.1:9202]\"}},{\"name\":\"SwCmq0QKQuShZcJAbuW8OQ\",\"routings\":[{\"name\":\"_river\",\"replicas\":[{\"replica\":{\"state\":\"STARTED\",\"primary\":false,\"node\":\"SwCmq0QKQuShZcJAbuW8OQ\",\"relocating_node\":null,\"shard\":0,\"index\":\"_river\"},\"status\":{\"routing\":{\"state\":\"STARTED\",\"primary\":false,\"node\":\"SwCmq0QKQuShZcJAbuW8OQ\",\"relocating_node\":null,\"shard\":0,\"index\":\"_river\"},\"state\":\"STARTED\",\"index\":{\"size\":\"79b\",\"size_in_bytes\":79},\"translog\":{\"id\":1380240228838,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":62,\"total_time\":\"1.6s\",\"total_time_in_millis\":1632}}}],\"max_number_of_shards\":\"1\",\"open\":true},{\"name\":\"ag_01\",\"replicas\":[{\"replica\":{\"state\":\"STARTED\",\"primary\":false,\"node\":\"SwCmq0QKQuShZcJAbuW8OQ\",\"relocating_node\":null,\"shard\":0,\"index\":\"ag_01\"},\"status\":{\"routing\":{\"state\":\"STARTED\",\"primary\":false,\"node\":\"SwCmq0QKQuShZcJAbuW8OQ\",\"relocating_node\":null,\"shard\":0,\"index\":\"ag_01\"},\"state\":\"STARTED\",\"index\":{\"size\":\"79b\",\"size_in_bytes\":79},\"translog\":{\"id\":1381731712651,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":7,\"total_time\":\"216ms\",\"total_time_in_millis\":216}}}],\"max_number_of_shards\":\"2\",\"open\":true},{\"name\":\"ag_02\",\"replicas\":[null,null,{\"replica\":{\"state\":\"STARTED\",\"primary\":true,\"node\":\"SwCmq0QKQuShZcJAbuW8OQ\",\"relocating_node\":null,\"shard\":2,\"index\":\"ag_02\"},\"status\":{\"routing\":{\"state\":\"STARTED\",\"primary\":true,\"node\":\"SwCmq0QKQuShZcJAbuW8OQ\",\"relocating_node\":null,\"shard\":2,\"index\":\"ag_02\"},\"state\":\"STARTED\",\"index\":{\"size\":\"99b\",\"size_in_bytes\":99},\"translog\":{\"id\":1381749663407,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":1,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":4,\"total_time\":\"17ms\",\"total_time_in_millis\":17}}}],\"max_number_of_shards\":\"3\",\"open\":true},{\"name\":\"ag_03\",\"replicas\":[],\"max_number_of_shards\":\"2\",\"open\":true},{\"name\":\"twitter_river\",\"replicas\":[],\"max_number_of_shards\":\"5\",\"open\":false}],\"master_node\":false,\"stats\":{\"timestamp\":1381790346944,\"name\":\"Ameridroid\",\"transport_address\":\"inet[/127.0.0.1:9305]\",\"hostname\":\"server\",\"indices\":{\"docs\":{\"count\":0,\"deleted\":0},\"store\":{\"size\":\"257b\",\"size_in_bytes\":257,\"throttle_time\":\"0s\",\"throttle_time_in_millis\":0},\"indexing\":{\"index_total\":6,\"index_time\":\"64ms\",\"index_time_in_millis\":64,\"index_current\":0,\"delete_total\":0,\"delete_time\":\"0s\",\"delete_time_in_millis\":0,\"delete_current\":0},\"get\":{\"total\":0,\"get_time\":\"0s\",\"time_in_millis\":0,\"exists_total\":0,\"exists_time\":\"0s\",\"exists_time_in_millis\":0,\"missing_total\":0,\"missing_time\":\"0s\",\"missing_time_in_millis\":0,\"current\":0},\"search\":{\"open_contexts\":0,\"query_total\":12,\"query_time\":\"27ms\",\"query_time_in_millis\":27,\"query_current\":0,\"fetch_total\":0,\"fetch_time\":\"0s\",\"fetch_time_in_millis\":0,\"fetch_current\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":10,\"total_time\":\"113ms\",\"total_time_in_millis\":113},\"flush\":{\"total\":241,\"total_time\":\"5.5s\",\"total_time_in_millis\":5553},\"warmer\":{\"current\":0,\"total\":3,\"total_time\":\"4ms\",\"total_time_in_millis\":4},\"filter_cache\":{\"memory_size\":\"0b\",\"memory_size_in_bytes\":0,\"evictions\":0},\"id_cache\":{\"memory_size\":\"0b\",\"memory_size_in_bytes\":0},\"fielddata\":{\"memory_size\":\"0b\",\"memory_size_in_bytes\":0,\"evictions\":0},\"completion\":{\"size\":\"0b\",\"size_in_bytes\":0}},\"os\":{\"timestamp\":1381790346944,\"uptime\":\"15.5m\",\"uptime_in_millis\":932146,\"load_average\":[1.79736328125,1.95166015625,1.904296875],\"cpu\":{\"sys\":22,\"user\":6,\"idle\":70,\"stolen\":0},\"mem\":{\"free\":\"3.7gb\",\"free_in_bytes\":4059074560,\"used\":\"4.2gb\",\"used_in_bytes\":4530860032,\"free_percent\":51,\"used_percent\":48,\"actual_free\":\"4.1gb\",\"actual_free_in_bytes\":4419702784,\"actual_used\":\"3.8gb\",\"actual_used_in_bytes\":4170231808},\"swap\":{\"used\":\"2.8gb\",\"used_in_bytes\":3025272832,\"free\":\"1.1gb\",\"free_in_bytes\":1269694464}},\"process\":{\"timestamp\":1381790346944,\"open_file_descriptors\":266,\"cpu\":{\"percent\":0,\"sys\":\"2.8m\",\"sys_in_millis\":171912,\"user\":\"2.3m\",\"user_in_millis\":143905,\"total\":\"5.2m\",\"total_in_millis\":315817},\"mem\":{\"resident\":\"30.4mb\",\"resident_in_bytes\":31936512,\"share\":\"-1b\",\"share_in_bytes\":-1,\"total_virtual\":\"3.6gb\",\"total_virtual_in_bytes\":3905077248}},\"jvm\":{\"timestamp\":1381790346944,\"uptime\":\"4d\",\"uptime_in_millis\":349024271,\"mem\":{\"heap_used\":\"16.6mb\",\"heap_used_in_bytes\":17485968,\"heap_committed\":\"253.9mb\",\"heap_committed_in_bytes\":266272768,\"non_heap_used\":\"39.7mb\",\"non_heap_used_in_bytes\":41733256,\"non_heap_committed\":\"40.4mb\",\"non_heap_committed_in_bytes\":42405888,\"pools\":{\"Code Cache\":{\"used\":\"1.9mb\",\"used_in_bytes\":2018624,\"max\":\"48mb\",\"max_in_bytes\":50331648,\"peak_used\":\"1.9mb\",\"peak_used_in_bytes\":2029504,\"peak_max\":\"48mb\",\"peak_max_in_bytes\":50331648},\"Par Eden Space\":{\"used\":\"5.9mb\",\"used_in_bytes\":6242912,\"max\":\"66.5mb\",\"max_in_bytes\":69795840,\"peak_used\":\"16.6mb\",\"peak_used_in_bytes\":17432576,\"peak_max\":\"66.5mb\",\"peak_max_in_bytes\":69795840},\"Par Survivor Space\":{\"used\":\"489.7kb\",\"used_in_bytes\":501496,\"max\":\"8.3mb\",\"max_in_bytes\":8716288,\"peak_used\":\"2mb\",\"peak_used_in_bytes\":2162688,\"peak_max\":\"8.3mb\",\"peak_max_in_bytes\":8716288},\"CMS Old Gen\":{\"used\":\"10.2mb\",\"used_in_bytes\":10741560,\"max\":\"940.8mb\",\"max_in_bytes\":986513408,\"peak_used\":\"10.2mb\",\"peak_used_in_bytes\":10741560,\"peak_max\":\"940.8mb\",\"peak_max_in_bytes\":986513408},\"CMS Perm Gen\":{\"used\":\"37.8mb\",\"used_in_bytes\":39714632,\"max\":\"82mb\",\"max_in_bytes\":85983232,\"peak_used\":\"37.8mb\",\"peak_used_in_bytes\":39714632,\"peak_max\":\"82mb\",\"peak_max_in_bytes\":85983232}}},\"threads\":{\"count\":63,\"peak_count\":70},\"gc\":{\"collection_count\":61,\"collection_time\":\"533ms\",\"collection_time_in_millis\":533,\"collectors\":{\"ParNew\":{\"collection_count\":61,\"collection_time\":\"533ms\",\"collection_time_in_millis\":533},\"ConcurrentMarkSweep\":{\"collection_count\":0,\"collection_time\":\"0s\",\"collection_time_in_millis\":0}}}},\"thread_pool\":{\"generic\":{\"threads\":1,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":4,\"completed\":7504},\"index\":{\"threads\":4,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":4,\"completed\":6},\"get\":{\"threads\":0,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":0,\"completed\":0},\"snapshot\":{\"threads\":1,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":1,\"completed\":4},\"merge\":{\"threads\":1,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":1,\"completed\":4},\"suggest\":{\"threads\":0,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":0,\"completed\":0},\"bulk\":{\"threads\":0,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":0,\"completed\":0},\"optimize\":{\"threads\":0,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":0,\"completed\":0},\"warmer\":{\"threads\":1,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":1,\"completed\":23},\"flush\":{\"threads\":0,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":2,\"completed\":241},\"search\":{\"threads\":12,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":12,\"completed\":12},\"percolate\":{\"threads\":0,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":0,\"completed\":0},\"management\":{\"threads\":4,\"queue\":0,\"active\":1,\"rejected\":0,\"largest\":5,\"completed\":10284},\"refresh\":{\"threads\":1,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":1,\"completed\":4}},\"network\":{\"tcp\":{\"active_opens\":91033,\"passive_opens\":3206,\"curr_estab\":824,\"in_segs\":9438844,\"out_segs\":7330461,\"retrans_segs\":10420,\"estab_resets\":4179,\"attempt_fails\":2304,\"in_errs\":15,\"out_rsts\":-1}},\"fs\":{\"timestamp\":1381790346959,\"data\":[{\"path\":\"/var/elasticsearch/es6/data/elasticsearch/nodes/0\",\"mount\":\"/\",\"dev\":\"/dev/disk0s2\",\"total\":\"465.1gb\",\"total_in_bytes\":499418034176,\"free\":\"215.3gb\",\"free_in_bytes\":231240040448,\"available\":\"215.1gb\",\"available_in_bytes\":230977896448,\"disk_reads\":2641849,\"disk_writes\":3231915,\"disk_read_size\":\"75.9gb\",\"disk_read_size_in_bytes\":81593058816,\"disk_write_size\":\"76.2gb\",\"disk_write_size_in_bytes\":81856144384}]},\"transport\":{\"server_open\":60,\"rx_count\":156880,\"rx_size\":\"7mb\",\"rx_size_in_bytes\":7431874,\"tx_count\":156877,\"tx_size\":\"11.9mb\",\"tx_size_in_bytes\":12480678},\"http\":{\"current_open\":0,\"total_opened\":0}},\"cluster\":{\"name\":\"Ameridroid\",\"transport_address\":\"inet[/127.0.0.1:9305]\",\"hostname\":\"server\",\"version\":\"0.90.5\",\"http_address\":\"inet[server/127.0.0.1:9205]\"}},{\"name\":\"aBuoaKR5QVCfUZHgrJEfVg\",\"routings\":[{\"name\":\"_river\",\"replicas\":[],\"max_number_of_shards\":\"1\",\"open\":true},{\"name\":\"ag_01\",\"replicas\":[{\"replica\":{\"state\":\"STARTED\",\"primary\":true,\"node\":\"aBuoaKR5QVCfUZHgrJEfVg\",\"relocating_node\":null,\"shard\":0,\"index\":\"ag_01\"},\"status\":{\"routing\":{\"state\":\"STARTED\",\"primary\":true,\"node\":\"aBuoaKR5QVCfUZHgrJEfVg\",\"relocating_node\":null,\"shard\":0,\"index\":\"ag_01\"},\"state\":\"STARTED\",\"index\":{\"size\":\"99b\",\"size_in_bytes\":99},\"translog\":{\"id\":1381731712651,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":1,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":7,\"total_time\":\"382ms\",\"total_time_in_millis\":382}}}],\"max_number_of_shards\":\"2\",\"open\":true},{\"name\":\"ag_02\",\"replicas\":[null,null,{\"replica\":{\"state\":\"STARTED\",\"primary\":false,\"node\":\"aBuoaKR5QVCfUZHgrJEfVg\",\"relocating_node\":null,\"shard\":2,\"index\":\"ag_02\"},\"status\":{\"routing\":{\"state\":\"STARTED\",\"primary\":false,\"node\":\"aBuoaKR5QVCfUZHgrJEfVg\",\"relocating_node\":null,\"shard\":2,\"index\":\"ag_02\"},\"state\":\"STARTED\",\"index\":{\"size\":\"79b\",\"size_in_bytes\":79},\"translog\":{\"id\":1381749663407,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":3,\"total_time\":\"15ms\",\"total_time_in_millis\":15}}}],\"max_number_of_shards\":\"3\",\"open\":true},{\"name\":\"ag_03\",\"replicas\":[{\"replica\":{\"state\":\"STARTED\",\"primary\":true,\"node\":\"aBuoaKR5QVCfUZHgrJEfVg\",\"relocating_node\":null,\"shard\":0,\"index\":\"ag_03\"},\"status\":{\"routing\":{\"state\":\"STARTED\",\"primary\":true,\"node\":\"aBuoaKR5QVCfUZHgrJEfVg\",\"relocating_node\":null,\"shard\":0,\"index\":\"ag_03\"},\"state\":\"STARTED\",\"index\":{\"size\":\"99b\",\"size_in_bytes\":99},\"translog\":{\"id\":1381731770063,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":1,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":6,\"total_time\":\"101ms\",\"total_time_in_millis\":101}}}],\"max_number_of_shards\":\"2\",\"open\":true},{\"name\":\"twitter_river\",\"replicas\":[],\"max_number_of_shards\":\"5\",\"open\":false}],\"master_node\":false,\"stats\":{\"timestamp\":1381790346945,\"name\":\"Immortus\",\"transport_address\":\"inet[/127.0.0.1:9302]\",\"hostname\":\"server\",\"indices\":{\"docs\":{\"count\":0,\"deleted\":0},\"store\":{\"size\":\"277b\",\"size_in_bytes\":277,\"throttle_time\":\"0s\",\"throttle_time_in_millis\":0},\"indexing\":{\"index_total\":2,\"index_time\":\"59ms\",\"index_time_in_millis\":59,\"index_current\":0,\"delete_total\":0,\"delete_time\":\"0s\",\"delete_time_in_millis\":0,\"delete_current\":0},\"get\":{\"total\":0,\"get_time\":\"0s\",\"time_in_millis\":0,\"exists_total\":0,\"exists_time\":\"0s\",\"exists_time_in_millis\":0,\"missing_total\":0,\"missing_time\":\"0s\",\"missing_time_in_millis\":0,\"current\":0},\"search\":{\"open_contexts\":0,\"query_total\":12,\"query_time\":\"27ms\",\"query_time_in_millis\":27,\"query_current\":0,\"fetch_total\":1,\"fetch_time\":\"9ms\",\"fetch_time_in_millis\":9,\"fetch_current\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":9,\"total_time\":\"72ms\",\"total_time_in_millis\":72},\"flush\":{\"total\":239,\"total_time\":\"6.3s\",\"total_time_in_millis\":6363},\"warmer\":{\"current\":0,\"total\":3,\"total_time\":\"8ms\",\"total_time_in_millis\":8},\"filter_cache\":{\"memory_size\":\"0b\",\"memory_size_in_bytes\":0,\"evictions\":0},\"id_cache\":{\"memory_size\":\"0b\",\"memory_size_in_bytes\":0},\"fielddata\":{\"memory_size\":\"0b\",\"memory_size_in_bytes\":0,\"evictions\":0},\"completion\":{\"size\":\"0b\",\"size_in_bytes\":0}},\"os\":{\"timestamp\":1381790346963,\"uptime\":\"15.5m\",\"uptime_in_millis\":932146,\"load_average\":[1.79736328125,1.95166015625,1.904296875],\"cpu\":{\"sys\":22,\"user\":6,\"idle\":70,\"stolen\":0},\"mem\":{\"free\":\"3.7gb\",\"free_in_bytes\":4058099712,\"used\":\"4.2gb\",\"used_in_bytes\":4531834880,\"free_percent\":51,\"used_percent\":48,\"actual_free\":\"4.1gb\",\"actual_free_in_bytes\":4419252224,\"actual_used\":\"3.8gb\",\"actual_used_in_bytes\":4170682368},\"swap\":{\"used\":\"2.8gb\",\"used_in_bytes\":3025272832,\"free\":\"1.1gb\",\"free_in_bytes\":1269694464}},\"process\":{\"timestamp\":1381790346963,\"open_file_descriptors\":266,\"cpu\":{\"percent\":0,\"sys\":\"2.9m\",\"sys_in_millis\":174105,\"user\":\"2.4m\",\"user_in_millis\":145373,\"total\":\"5.3m\",\"total_in_millis\":319478},\"mem\":{\"resident\":\"29mb\",\"resident_in_bytes\":30453760,\"share\":\"-1b\",\"share_in_bytes\":-1,\"total_virtual\":\"3.6gb\",\"total_virtual_in_bytes\":3912540160}},\"jvm\":{\"timestamp\":1381790346963,\"uptime\":\"4d\",\"uptime_in_millis\":349027381,\"mem\":{\"heap_used\":\"28.5mb\",\"heap_used_in_bytes\":29980664,\"heap_committed\":\"265.5mb\",\"heap_committed_in_bytes\":278462464,\"non_heap_used\":\"40mb\",\"non_heap_used_in_bytes\":42021480,\"non_heap_committed\":\"65.6mb\",\"non_heap_committed_in_bytes\":68853760,\"pools\":{\"Code Cache\":{\"used\":\"2mb\",\"used_in_bytes\":2183808,\"max\":\"48mb\",\"max_in_bytes\":50331648,\"peak_used\":\"2mb\",\"peak_used_in_bytes\":2193408,\"peak_max\":\"48mb\",\"peak_max_in_bytes\":50331648},\"Par Eden Space\":{\"used\":\"23.8mb\",\"used_in_bytes\":25026800,\"max\":\"66.5mb\",\"max_in_bytes\":69795840,\"peak_used\":\"27mb\",\"peak_used_in_bytes\":28311552,\"peak_max\":\"66.5mb\",\"peak_max_in_bytes\":69795840},\"Par Survivor Space\":{\"used\":\"464.1kb\",\"used_in_bytes\":475296,\"max\":\"8.3mb\",\"max_in_bytes\":8716288,\"peak_used\":\"2mb\",\"peak_used_in_bytes\":2162688,\"peak_max\":\"8.3mb\",\"peak_max_in_bytes\":8716288},\"CMS Old Gen\":{\"used\":\"4.2mb\",\"used_in_bytes\":4478568,\"max\":\"940.8mb\",\"max_in_bytes\":986513408,\"peak_used\":\"12.4mb\",\"peak_used_in_bytes\":13054208,\"peak_max\":\"940.8mb\",\"peak_max_in_bytes\":986513408},\"CMS Perm Gen\":{\"used\":\"37.9mb\",\"used_in_bytes\":39837672,\"max\":\"82mb\",\"max_in_bytes\":85983232,\"peak_used\":\"38.2mb\",\"peak_used_in_bytes\":40134632,\"peak_max\":\"82mb\",\"peak_max_in_bytes\":85983232}}},\"threads\":{\"count\":62,\"peak_count\":67},\"gc\":{\"collection_count\":80,\"collection_time\":\"561ms\",\"collection_time_in_millis\":561,\"collectors\":{\"ParNew\":{\"collection_count\":78,\"collection_time\":\"557ms\",\"collection_time_in_millis\":557},\"ConcurrentMarkSweep\":{\"collection_count\":2,\"collection_time\":\"4ms\",\"collection_time_in_millis\":4}}}},\"thread_pool\":{\"generic\":{\"threads\":1,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":4,\"completed\":7528},\"index\":{\"threads\":2,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":2,\"completed\":2},\"get\":{\"threads\":0,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":0,\"completed\":0},\"snapshot\":{\"threads\":1,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":1,\"completed\":2},\"merge\":{\"threads\":1,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":1,\"completed\":2},\"suggest\":{\"threads\":0,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":0,\"completed\":0},\"bulk\":{\"threads\":0,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":0,\"completed\":0},\"optimize\":{\"threads\":0,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":0,\"completed\":0},\"warmer\":{\"threads\":1,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":1,\"completed\":26},\"flush\":{\"threads\":0,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":2,\"completed\":242},\"search\":{\"threads\":12,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":12,\"completed\":13},\"percolate\":{\"threads\":0,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":0,\"completed\":0},\"management\":{\"threads\":5,\"queue\":0,\"active\":2,\"rejected\":0,\"largest\":5,\"completed\":10288},\"refresh\":{\"threads\":1,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":1,\"completed\":2}},\"network\":{\"tcp\":{\"active_opens\":91033,\"passive_opens\":3206,\"curr_estab\":824,\"in_segs\":9438862,\"out_segs\":7330479,\"retrans_segs\":10420,\"estab_resets\":4179,\"attempt_fails\":2304,\"in_errs\":15,\"out_rsts\":-1}},\"fs\":{\"timestamp\":1381790346977,\"data\":[{\"path\":\"/var/elasticsearch/es3/data/elasticsearch/nodes/0\",\"mount\":\"/\",\"dev\":\"/dev/disk0s2\",\"total\":\"465.1gb\",\"total_in_bytes\":499418034176,\"free\":\"215.3gb\",\"free_in_bytes\":231241089024,\"available\":\"215.1gb\",\"available_in_bytes\":230978945024,\"disk_reads\":2641854,\"disk_writes\":3231915,\"disk_read_size\":\"75.9gb\",\"disk_read_size_in_bytes\":81593402880,\"disk_write_size\":\"76.2gb\",\"disk_write_size_in_bytes\":81856144384}]},\"transport\":{\"server_open\":60,\"rx_count\":156920,\"rx_size\":\"7.1mb\",\"rx_size_in_bytes\":7451979,\"tx_count\":156915,\"tx_size\":\"11.9mb\",\"tx_size_in_bytes\":12499329},\"http\":{\"current_open\":0,\"total_opened\":0}},\"cluster\":{\"name\":\"Immortus\",\"transport_address\":\"inet[/127.0.0.1:9302]\",\"hostname\":\"server\",\"version\":\"0.90.5\",\"http_address\":\"inet[server/127.0.0.1:9201]\"}},{\"name\":\"3Rbfod0sS9eZ6VrOkY0JKw\",\"routings\":[{\"name\":\"_river\",\"replicas\":[{\"replica\":{\"state\":\"STARTED\",\"primary\":true,\"node\":\"3Rbfod0sS9eZ6VrOkY0JKw\",\"relocating_node\":null,\"shard\":0,\"index\":\"_river\"},\"status\":{\"routing\":{\"state\":\"STARTED\",\"primary\":true,\"node\":\"3Rbfod0sS9eZ6VrOkY0JKw\",\"relocating_node\":null,\"shard\":0,\"index\":\"_river\"},\"state\":\"STARTED\",\"index\":{\"size\":\"79b\",\"size_in_bytes\":79},\"translog\":{\"id\":1380240228838,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":1,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":62,\"total_time\":\"833ms\",\"total_time_in_millis\":833}}}],\"max_number_of_shards\":\"1\",\"open\":true},{\"name\":\"ag_01\",\"replicas\":[],\"max_number_of_shards\":\"2\",\"open\":true},{\"name\":\"ag_02\",\"replicas\":[{\"replica\":{\"state\":\"STARTED\",\"primary\":false,\"node\":\"3Rbfod0sS9eZ6VrOkY0JKw\",\"relocating_node\":null,\"shard\":0,\"index\":\"ag_02\"},\"status\":{\"routing\":{\"state\":\"STARTED\",\"primary\":false,\"node\":\"3Rbfod0sS9eZ6VrOkY0JKw\",\"relocating_node\":null,\"shard\":0,\"index\":\"ag_02\"},\"state\":\"STARTED\",\"index\":{\"size\":\"79b\",\"size_in_bytes\":79},\"translog\":{\"id\":1381749663369,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":3,\"total_time\":\"4ms\",\"total_time_in_millis\":4}}}],\"max_number_of_shards\":\"3\",\"open\":true},{\"name\":\"ag_03\",\"replicas\":[{\"replica\":{\"state\":\"STARTED\",\"primary\":false,\"node\":\"3Rbfod0sS9eZ6VrOkY0JKw\",\"relocating_node\":null,\"shard\":0,\"index\":\"ag_03\"},\"status\":{\"routing\":{\"state\":\"STARTED\",\"primary\":false,\"node\":\"3Rbfod0sS9eZ6VrOkY0JKw\",\"relocating_node\":null,\"shard\":0,\"index\":\"ag_03\"},\"state\":\"STARTED\",\"index\":{\"size\":\"79b\",\"size_in_bytes\":79},\"translog\":{\"id\":1381731770063,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":7,\"total_time\":\"274ms\",\"total_time_in_millis\":274}}}],\"max_number_of_shards\":\"2\",\"open\":true},{\"name\":\"twitter_river\",\"replicas\":[],\"max_number_of_shards\":\"5\",\"open\":false}],\"master_node\":true,\"stats\":{\"timestamp\":1381790346938,\"name\":\"Steel Serpent\",\"transport_address\":\"inet[server/127.0.0.1:9300]\",\"hostname\":\"server\",\"indices\":{\"docs\":{\"count\":0,\"deleted\":0},\"store\":{\"size\":\"237b\",\"size_in_bytes\":237,\"throttle_time\":\"0s\",\"throttle_time_in_millis\":0},\"indexing\":{\"index_total\":2,\"index_time\":\"59ms\",\"index_time_in_millis\":59,\"index_current\":0,\"delete_total\":0,\"delete_time\":\"0s\",\"delete_time_in_millis\":0,\"delete_current\":0},\"get\":{\"total\":0,\"get_time\":\"0s\",\"time_in_millis\":0,\"exists_total\":0,\"exists_time\":\"0s\",\"exists_time_in_millis\":0,\"missing_total\":0,\"missing_time\":\"0s\",\"missing_time_in_millis\":0,\"current\":0},\"search\":{\"open_contexts\":0,\"query_total\":12,\"query_time\":\"32ms\",\"query_time_in_millis\":32,\"query_current\":0,\"fetch_total\":3,\"fetch_time\":\"5ms\",\"fetch_time_in_millis\":5,\"fetch_current\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":6,\"total_time\":\"58ms\",\"total_time_in_millis\":58},\"flush\":{\"total\":240,\"total_time\":\"4.3s\",\"total_time_in_millis\":4339},\"warmer\":{\"current\":0,\"total\":3,\"total_time\":\"8ms\",\"total_time_in_millis\":8},\"filter_cache\":{\"memory_size\":\"0b\",\"memory_size_in_bytes\":0,\"evictions\":0},\"id_cache\":{\"memory_size\":\"0b\",\"memory_size_in_bytes\":0},\"fielddata\":{\"memory_size\":\"0b\",\"memory_size_in_bytes\":0,\"evictions\":0},\"completion\":{\"size\":\"0b\",\"size_in_bytes\":0}},\"os\":{\"timestamp\":1381790346938,\"uptime\":\"15.5m\",\"uptime_in_millis\":932146,\"load_average\":[1.79736328125,1.95166015625,1.904296875],\"cpu\":{\"sys\":22,\"user\":6,\"idle\":70,\"stolen\":0},\"mem\":{\"free\":\"3.7gb\",\"free_in_bytes\":4062093312,\"used\":\"4.2gb\",\"used_in_bytes\":4527841280,\"free_percent\":51,\"used_percent\":48,\"actual_free\":\"4.1gb\",\"actual_free_in_bytes\":4422721536,\"actual_used\":\"3.8gb\",\"actual_used_in_bytes\":4167213056},\"swap\":{\"used\":\"2.8gb\",\"used_in_bytes\":3025272832,\"free\":\"1.1gb\",\"free_in_bytes\":1269694464}},\"process\":{\"timestamp\":1381790346938,\"open_file_descriptors\":272,\"cpu\":{\"percent\":0,\"sys\":\"3.3m\",\"sys_in_millis\":200578,\"user\":\"3.2m\",\"user_in_millis\":192613,\"total\":\"6.5m\",\"total_in_millis\":393191},\"mem\":{\"resident\":\"43.8mb\",\"resident_in_bytes\":46018560,\"share\":\"-1b\",\"share_in_bytes\":-1,\"total_virtual\":\"3.6gb\",\"total_virtual_in_bytes\":3910467584}},\"jvm\":{\"timestamp\":1381790346938,\"uptime\":\"4d\",\"uptime_in_millis\":349029191,\"mem\":{\"heap_used\":\"28.9mb\",\"heap_used_in_bytes\":30381984,\"heap_committed\":\"253.9mb\",\"heap_committed_in_bytes\":266272768,\"non_heap_used\":\"42.9mb\",\"non_heap_used_in_bytes\":45068896,\"non_heap_committed\":\"43.3mb\",\"non_heap_committed_in_bytes\":45420544,\"pools\":{\"Code Cache\":{\"used\":\"3.3mb\",\"used_in_bytes\":3534656,\"max\":\"48mb\",\"max_in_bytes\":50331648,\"peak_used\":\"3.3mb\",\"peak_used_in_bytes\":3545408,\"peak_max\":\"48mb\",\"peak_max_in_bytes\":50331648},\"Par Eden Space\":{\"used\":\"15.6mb\",\"used_in_bytes\":16402808,\"max\":\"66.5mb\",\"max_in_bytes\":69795840,\"peak_used\":\"16.6mb\",\"peak_used_in_bytes\":17432576,\"peak_max\":\"66.5mb\",\"peak_max_in_bytes\":69795840},\"Par Survivor Space\":{\"used\":\"44.9kb\",\"used_in_bytes\":46016,\"max\":\"8.3mb\",\"max_in_bytes\":8716288,\"peak_used\":\"2mb\",\"peak_used_in_bytes\":2162688,\"peak_max\":\"8.3mb\",\"peak_max_in_bytes\":8716288},\"CMS Old Gen\":{\"used\":\"13.2mb\",\"used_in_bytes\":13933160,\"max\":\"940.8mb\",\"max_in_bytes\":986513408,\"peak_used\":\"13.2mb\",\"peak_used_in_bytes\":13933160,\"peak_max\":\"940.8mb\",\"peak_max_in_bytes\":986513408},\"CMS Perm Gen\":{\"used\":\"39.6mb\",\"used_in_bytes\":41534240,\"max\":\"82mb\",\"max_in_bytes\":85983232,\"peak_used\":\"39.6mb\",\"peak_used_in_bytes\":41534240,\"peak_max\":\"82mb\",\"peak_max_in_bytes\":85983232}}},\"threads\":{\"count\":64,\"peak_count\":68},\"gc\":{\"collection_count\":272,\"collection_time\":\"967ms\",\"collection_time_in_millis\":967,\"collectors\":{\"ParNew\":{\"collection_count\":272,\"collection_time\":\"967ms\",\"collection_time_in_millis\":967},\"ConcurrentMarkSweep\":{\"collection_count\":0,\"collection_time\":\"0s\",\"collection_time_in_millis\":0}}}},\"thread_pool\":{\"generic\":{\"threads\":2,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":4,\"completed\":9499},\"index\":{\"threads\":2,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":2,\"completed\":2},\"get\":{\"threads\":0,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":0,\"completed\":0},\"snapshot\":{\"threads\":1,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":1,\"completed\":2},\"merge\":{\"threads\":1,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":1,\"completed\":2},\"suggest\":{\"threads\":0,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":0,\"completed\":0},\"bulk\":{\"threads\":0,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":0,\"completed\":0},\"optimize\":{\"threads\":0,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":0,\"completed\":0},\"warmer\":{\"threads\":1,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":1,\"completed\":21},\"flush\":{\"threads\":0,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":2,\"completed\":241},\"search\":{\"threads\":12,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":12,\"completed\":15},\"percolate\":{\"threads\":0,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":0,\"completed\":0},\"management\":{\"threads\":5,\"queue\":0,\"active\":1,\"rejected\":0,\"largest\":5,\"completed\":15207},\"refresh\":{\"threads\":1,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":1,\"completed\":2}},\"network\":{\"tcp\":{\"active_opens\":91033,\"passive_opens\":3206,\"curr_estab\":824,\"in_segs\":9438818,\"out_segs\":7330435,\"retrans_segs\":10420,\"estab_resets\":4179,\"attempt_fails\":2304,\"in_errs\":15,\"out_rsts\":-1}},\"fs\":{\"timestamp\":1381790346956,\"data\":[{\"path\":\"/var/elasticsearch/es1/data/elasticsearch/nodes/0\",\"mount\":\"/\",\"dev\":\"/dev/disk0s2\",\"total\":\"465.1gb\",\"total_in_bytes\":499418034176,\"free\":\"215.3gb\",\"free_in_bytes\":231240040448,\"available\":\"215.1gb\",\"available_in_bytes\":230977896448,\"disk_reads\":2641849,\"disk_writes\":3231915,\"disk_read_size\":\"75.9gb\",\"disk_read_size_in_bytes\":81593058816,\"disk_write_size\":\"76.2gb\",\"disk_write_size_in_bytes\":81856144384}]},\"transport\":{\"server_open\":60,\"rx_count\":780551,\"rx_size\":\"59mb\",\"rx_size_in_bytes\":61929023,\"tx_count\":780563,\"tx_size\":\"35.2mb\",\"tx_size_in_bytes\":36961925},\"http\":{\"current_open\":6,\"total_opened\":201}},\"cluster\":{\"name\":\"Steel Serpent\",\"transport_address\":\"inet[server/127.0.0.1:9300]\",\"hostname\":\"server\",\"version\":\"0.90.5\",\"http_address\":\"inet[server/127.0.0.1:9200]\"}},{\"name\":\"PO1wHIidQo-w7sGHaYHvjg\",\"routings\":[{\"name\":\"_river\",\"replicas\":[],\"max_number_of_shards\":\"1\",\"open\":true},{\"name\":\"ag_01\",\"replicas\":[],\"max_number_of_shards\":\"2\",\"open\":true},{\"name\":\"ag_02\",\"replicas\":[null,{\"replica\":{\"state\":\"STARTED\",\"primary\":true,\"node\":\"PO1wHIidQo-w7sGHaYHvjg\",\"relocating_node\":null,\"shard\":1,\"index\":\"ag_02\"},\"status\":{\"routing\":{\"state\":\"STARTED\",\"primary\":true,\"node\":\"PO1wHIidQo-w7sGHaYHvjg\",\"relocating_node\":null,\"shard\":1,\"index\":\"ag_02\"},\"state\":\"STARTED\",\"index\":{\"size\":\"99b\",\"size_in_bytes\":99},\"translog\":{\"id\":1381749663385,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":1,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":4,\"total_time\":\"122ms\",\"total_time_in_millis\":122}}}],\"max_number_of_shards\":\"3\",\"open\":true},{\"name\":\"ag_03\",\"replicas\":[null,{\"replica\":{\"state\":\"STARTED\",\"primary\":false,\"node\":\"PO1wHIidQo-w7sGHaYHvjg\",\"relocating_node\":null,\"shard\":1,\"index\":\"ag_03\"},\"status\":{\"routing\":{\"state\":\"STARTED\",\"primary\":false,\"node\":\"PO1wHIidQo-w7sGHaYHvjg\",\"relocating_node\":null,\"shard\":1,\"index\":\"ag_03\"},\"state\":\"STARTED\",\"index\":{\"size\":\"79b\",\"size_in_bytes\":79},\"translog\":{\"id\":1381731770058,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":7,\"total_time\":\"137ms\",\"total_time_in_millis\":137}}}],\"max_number_of_shards\":\"2\",\"open\":true},{\"name\":\"twitter_river\",\"replicas\":[],\"max_number_of_shards\":\"5\",\"open\":false}],\"master_node\":false,\"stats\":{\"timestamp\":1381790346964,\"name\":\"Thumbelina\",\"transport_address\":\"inet[/127.0.0.1:9304]\",\"hostname\":\"server\",\"indices\":{\"docs\":{\"count\":0,\"deleted\":0},\"store\":{\"size\":\"178b\",\"size_in_bytes\":178,\"throttle_time\":\"0s\",\"throttle_time_in_millis\":0},\"indexing\":{\"index_total\":4,\"index_time\":\"55ms\",\"index_time_in_millis\":55,\"index_current\":0,\"delete_total\":0,\"delete_time\":\"0s\",\"delete_time_in_millis\":0,\"delete_current\":0},\"get\":{\"total\":0,\"get_time\":\"0s\",\"time_in_millis\":0,\"exists_total\":0,\"exists_time\":\"0s\",\"exists_time_in_millis\":0,\"missing_total\":0,\"missing_time\":\"0s\",\"missing_time_in_millis\":0,\"current\":0},\"search\":{\"open_contexts\":0,\"query_total\":6,\"query_time\":\"21ms\",\"query_time_in_millis\":21,\"query_current\":0,\"fetch_total\":2,\"fetch_time\":\"10ms\",\"fetch_time_in_millis\":10,\"fetch_current\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":9,\"total_time\":\"81ms\",\"total_time_in_millis\":81},\"flush\":{\"total\":198,\"total_time\":\"3.6s\",\"total_time_in_millis\":3662},\"warmer\":{\"current\":0,\"total\":2,\"total_time\":\"3ms\",\"total_time_in_millis\":3},\"filter_cache\":{\"memory_size\":\"0b\",\"memory_size_in_bytes\":0,\"evictions\":0},\"id_cache\":{\"memory_size\":\"0b\",\"memory_size_in_bytes\":0},\"fielddata\":{\"memory_size\":\"0b\",\"memory_size_in_bytes\":0,\"evictions\":0},\"completion\":{\"size\":\"0b\",\"size_in_bytes\":0}},\"os\":{\"timestamp\":1381790346964,\"uptime\":\"15.5m\",\"uptime_in_millis\":932146,\"load_average\":[1.79736328125,1.95166015625,1.904296875],\"cpu\":{\"sys\":22,\"user\":6,\"idle\":70,\"stolen\":0},\"mem\":{\"free\":\"3.7gb\",\"free_in_bytes\":4058308608,\"used\":\"4.2gb\",\"used_in_bytes\":4531625984,\"free_percent\":51,\"used_percent\":48,\"actual_free\":\"4.1gb\",\"actual_free_in_bytes\":4419461120,\"actual_used\":\"3.8gb\",\"actual_used_in_bytes\":4170473472},\"swap\":{\"used\":\"2.8gb\",\"used_in_bytes\":3025272832,\"free\":\"1.1gb\",\"free_in_bytes\":1269694464}},\"process\":{\"timestamp\":1381790346964,\"open_file_descriptors\":264,\"cpu\":{\"percent\":0,\"sys\":\"2.8m\",\"sys_in_millis\":172378,\"user\":\"2.3m\",\"user_in_millis\":140227,\"total\":\"5.2m\",\"total_in_millis\":312605},\"mem\":{\"resident\":\"28.5mb\",\"resident_in_bytes\":29892608,\"share\":\"-1b\",\"share_in_bytes\":-1,\"total_virtual\":\"3.6gb\",\"total_virtual_in_bytes\":3904798720}},\"jvm\":{\"timestamp\":1381790346976,\"uptime\":\"4d\",\"uptime_in_millis\":349025339,\"mem\":{\"heap_used\":\"20.8mb\",\"heap_used_in_bytes\":21889120,\"heap_committed\":\"253.9mb\",\"heap_committed_in_bytes\":266272768,\"non_heap_used\":\"40.2mb\",\"non_heap_used_in_bytes\":42232320,\"non_heap_committed\":\"40.8mb\",\"non_heap_committed_in_bytes\":42799104,\"pools\":{\"Code Cache\":{\"used\":\"2mb\",\"used_in_bytes\":2125312,\"max\":\"48mb\",\"max_in_bytes\":50331648,\"peak_used\":\"2mb\",\"peak_used_in_bytes\":2134912,\"peak_max\":\"48mb\",\"peak_max_in_bytes\":50331648},\"Par Eden Space\":{\"used\":\"8.4mb\",\"used_in_bytes\":8836504,\"max\":\"66.5mb\",\"max_in_bytes\":69795840,\"peak_used\":\"16.6mb\",\"peak_used_in_bytes\":17432576,\"peak_max\":\"66.5mb\",\"peak_max_in_bytes\":69795840},\"Par Survivor Space\":{\"used\":\"659.3kb\",\"used_in_bytes\":675192,\"max\":\"8.3mb\",\"max_in_bytes\":8716288,\"peak_used\":\"2mb\",\"peak_used_in_bytes\":2162688,\"peak_max\":\"8.3mb\",\"peak_max_in_bytes\":8716288},\"CMS Old Gen\":{\"used\":\"11.8mb\",\"used_in_bytes\":12377424,\"max\":\"940.8mb\",\"max_in_bytes\":986513408,\"peak_used\":\"11.8mb\",\"peak_used_in_bytes\":12377424,\"peak_max\":\"940.8mb\",\"peak_max_in_bytes\":986513408},\"CMS Perm Gen\":{\"used\":\"38.2mb\",\"used_in_bytes\":40107008,\"max\":\"82mb\",\"max_in_bytes\":85983232,\"peak_used\":\"38.2mb\",\"peak_used_in_bytes\":40107008,\"peak_max\":\"82mb\",\"peak_max_in_bytes\":85983232}}},\"threads\":{\"count\":59,\"peak_count\":65},\"gc\":{\"collection_count\":61,\"collection_time\":\"632ms\",\"collection_time_in_millis\":632,\"collectors\":{\"ParNew\":{\"collection_count\":61,\"collection_time\":\"632ms\",\"collection_time_in_millis\":632},\"ConcurrentMarkSweep\":{\"collection_count\":0,\"collection_time\":\"0s\",\"collection_time_in_millis\":0}}}},\"thread_pool\":{\"generic\":{\"threads\":1,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":4,\"completed\":7515},\"index\":{\"threads\":4,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":4,\"completed\":4},\"get\":{\"threads\":0,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":0,\"completed\":0},\"snapshot\":{\"threads\":1,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":1,\"completed\":2},\"merge\":{\"threads\":1,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":1,\"completed\":2},\"suggest\":{\"threads\":0,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":0,\"completed\":0},\"bulk\":{\"threads\":0,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":0,\"completed\":0},\"optimize\":{\"threads\":0,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":0,\"completed\":0},\"warmer\":{\"threads\":1,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":1,\"completed\":22},\"flush\":{\"threads\":0,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":2,\"completed\":198},\"search\":{\"threads\":8,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":8,\"completed\":8},\"percolate\":{\"threads\":0,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":0,\"completed\":0},\"management\":{\"threads\":4,\"queue\":0,\"active\":1,\"rejected\":0,\"largest\":5,\"completed\":10266},\"refresh\":{\"threads\":1,\"queue\":0,\"active\":0,\"rejected\":0,\"largest\":1,\"completed\":2}},\"network\":{\"tcp\":{\"active_opens\":91033,\"passive_opens\":3206,\"curr_estab\":824,\"in_segs\":9438872,\"out_segs\":7330489,\"retrans_segs\":10420,\"estab_resets\":4179,\"attempt_fails\":2304,\"in_errs\":15,\"out_rsts\":-1}},\"fs\":{\"timestamp\":1381790347016,\"data\":[{\"path\":\"/var/elasticsearch/es5/data/elasticsearch/nodes/0\",\"mount\":\"/\",\"dev\":\"/dev/disk0s2\",\"total\":\"465.1gb\",\"total_in_bytes\":499418034176,\"free\":\"215.3gb\",\"free_in_bytes\":231241613312,\"available\":\"215.1gb\",\"available_in_bytes\":230979469312,\"disk_reads\":2641856,\"disk_writes\":3231915,\"disk_read_size\":\"75.9gb\",\"disk_read_size_in_bytes\":81593427456,\"disk_write_size\":\"76.2gb\",\"disk_write_size_in_bytes\":81856144384}]},\"transport\":{\"server_open\":60,\"rx_count\":156869,\"rx_size\":\"7mb\",\"rx_size_in_bytes\":7444733,\"tx_count\":156866,\"tx_size\":\"11.9mb\",\"tx_size_in_bytes\":12497730},\"http\":{\"current_open\":0,\"total_opened\":2}},\"cluster\":{\"name\":\"Thumbelina\",\"transport_address\":\"inet[/127.0.0.1:9304]\",\"hostname\":\"server\",\"version\":\"0.90.5\",\"http_address\":\"inet[server/127.0.0.1:9204]\"}}],\"aliases\":[{\"name\":\"search\",\"max\":3,\"min\":1,\"indices\":[false,{\"name\":\"ag_01\",\"state\":\"open\",\"metadata\":{\"state\":\"open\",\"settings\":{\"index.number_of_replicas\":\"1\",\"index.number_of_shards\":\"2\",\"index.version.created\":\"900599\"},\"mappings\":{},\"aliases\":[\"search\"]},\"status\":{\"index\":{\"primary_size\":\"198b\",\"primary_size_in_bytes\":198,\"size\":\"356b\",\"size_in_bytes\":356},\"translog\":{\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":2,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":27,\"total_time\":\"1.4s\",\"total_time_in_millis\":1435},\"shards\":{\"0\":[{\"routing\":{\"state\":\"STARTED\",\"primary\":false,\"node\":\"SwCmq0QKQuShZcJAbuW8OQ\",\"relocating_node\":null,\"shard\":0,\"index\":\"ag_01\"},\"state\":\"STARTED\",\"index\":{\"size\":\"79b\",\"size_in_bytes\":79},\"translog\":{\"id\":1381731712651,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":7,\"total_time\":\"216ms\",\"total_time_in_millis\":216}},{\"routing\":{\"state\":\"STARTED\",\"primary\":true,\"node\":\"aBuoaKR5QVCfUZHgrJEfVg\",\"relocating_node\":null,\"shard\":0,\"index\":\"ag_01\"},\"state\":\"STARTED\",\"index\":{\"size\":\"99b\",\"size_in_bytes\":99},\"translog\":{\"id\":1381731712651,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":1,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":7,\"total_time\":\"382ms\",\"total_time_in_millis\":382}}],\"1\":[{\"routing\":{\"state\":\"STARTED\",\"primary\":true,\"node\":\"cqTmT9GLSlSWx-B7pvM--w\",\"relocating_node\":null,\"shard\":1,\"index\":\"ag_01\"},\"state\":\"STARTED\",\"index\":{\"size\":\"99b\",\"size_in_bytes\":99},\"translog\":{\"id\":1381731712637,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":1,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":7,\"total_time\":\"643ms\",\"total_time_in_millis\":643}},{\"routing\":{\"state\":\"STARTED\",\"primary\":false,\"node\":\"jw4owU-ZQgOYdM7ElauDTg\",\"relocating_node\":null,\"shard\":1,\"index\":\"ag_01\"},\"state\":\"STARTED\",\"index\":{\"size\":\"79b\",\"size_in_bytes\":79},\"translog\":{\"id\":1381731712637,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":6,\"total_time\":\"194ms\",\"total_time_in_millis\":194}}]}}},{\"name\":\"ag_02\",\"state\":\"open\",\"metadata\":{\"state\":\"open\",\"settings\":{\"index.number_of_replicas\":\"1\",\"index.number_of_shards\":\"3\",\"index.version.created\":\"900599\"},\"mappings\":{},\"aliases\":[\"search\"]},\"status\":{\"index\":{\"primary_size\":\"297b\",\"primary_size_in_bytes\":297,\"size\":\"534b\",\"size_in_bytes\":534},\"translog\":{\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":3,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":20,\"total_time\":\"340ms\",\"total_time_in_millis\":340},\"shards\":{\"0\":[{\"routing\":{\"state\":\"STARTED\",\"primary\":true,\"node\":\"jw4owU-ZQgOYdM7ElauDTg\",\"relocating_node\":null,\"shard\":0,\"index\":\"ag_02\"},\"state\":\"STARTED\",\"index\":{\"size\":\"99b\",\"size_in_bytes\":99},\"translog\":{\"id\":1381749663369,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":1,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":3,\"total_time\":\"107ms\",\"total_time_in_millis\":107}},{\"routing\":{\"state\":\"STARTED\",\"primary\":false,\"node\":\"3Rbfod0sS9eZ6VrOkY0JKw\",\"relocating_node\":null,\"shard\":0,\"index\":\"ag_02\"},\"state\":\"STARTED\",\"index\":{\"size\":\"79b\",\"size_in_bytes\":79},\"translog\":{\"id\":1381749663369,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":3,\"total_time\":\"4ms\",\"total_time_in_millis\":4}}],\"1\":[{\"routing\":{\"state\":\"STARTED\",\"primary\":false,\"node\":\"cqTmT9GLSlSWx-B7pvM--w\",\"relocating_node\":null,\"shard\":1,\"index\":\"ag_02\"},\"state\":\"STARTED\",\"index\":{\"size\":\"79b\",\"size_in_bytes\":79},\"translog\":{\"id\":1381749663385,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":3,\"total_time\":\"75ms\",\"total_time_in_millis\":75}},{\"routing\":{\"state\":\"STARTED\",\"primary\":true,\"node\":\"PO1wHIidQo-w7sGHaYHvjg\",\"relocating_node\":null,\"shard\":1,\"index\":\"ag_02\"},\"state\":\"STARTED\",\"index\":{\"size\":\"99b\",\"size_in_bytes\":99},\"translog\":{\"id\":1381749663385,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":1,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":4,\"total_time\":\"122ms\",\"total_time_in_millis\":122}}],\"2\":[{\"routing\":{\"state\":\"STARTED\",\"primary\":true,\"node\":\"SwCmq0QKQuShZcJAbuW8OQ\",\"relocating_node\":null,\"shard\":2,\"index\":\"ag_02\"},\"state\":\"STARTED\",\"index\":{\"size\":\"99b\",\"size_in_bytes\":99},\"translog\":{\"id\":1381749663407,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":1,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":4,\"total_time\":\"17ms\",\"total_time_in_millis\":17}},{\"routing\":{\"state\":\"STARTED\",\"primary\":false,\"node\":\"aBuoaKR5QVCfUZHgrJEfVg\",\"relocating_node\":null,\"shard\":2,\"index\":\"ag_02\"},\"state\":\"STARTED\",\"index\":{\"size\":\"79b\",\"size_in_bytes\":79},\"translog\":{\"id\":1381749663407,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":3,\"total_time\":\"15ms\",\"total_time_in_millis\":15}}]}}},{\"name\":\"ag_03\",\"state\":\"open\",\"metadata\":{\"state\":\"open\",\"settings\":{\"index.number_of_replicas\":\"1\",\"index.number_of_shards\":\"2\",\"index.version.created\":\"900599\"},\"mappings\":{},\"aliases\":[\"search\",\"live\"]},\"status\":{\"index\":{\"primary_size\":\"198b\",\"primary_size_in_bytes\":198,\"size\":\"356b\",\"size_in_bytes\":356},\"translog\":{\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":2,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":27,\"total_time\":\"598ms\",\"total_time_in_millis\":598},\"shards\":{\"0\":[{\"routing\":{\"state\":\"STARTED\",\"primary\":true,\"node\":\"aBuoaKR5QVCfUZHgrJEfVg\",\"relocating_node\":null,\"shard\":0,\"index\":\"ag_03\"},\"state\":\"STARTED\",\"index\":{\"size\":\"99b\",\"size_in_bytes\":99},\"translog\":{\"id\":1381731770063,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":1,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":6,\"total_time\":\"101ms\",\"total_time_in_millis\":101}},{\"routing\":{\"state\":\"STARTED\",\"primary\":false,\"node\":\"3Rbfod0sS9eZ6VrOkY0JKw\",\"relocating_node\":null,\"shard\":0,\"index\":\"ag_03\"},\"state\":\"STARTED\",\"index\":{\"size\":\"79b\",\"size_in_bytes\":79},\"translog\":{\"id\":1381731770063,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":7,\"total_time\":\"274ms\",\"total_time_in_millis\":274}}],\"1\":[{\"routing\":{\"state\":\"STARTED\",\"primary\":true,\"node\":\"cqTmT9GLSlSWx-B7pvM--w\",\"relocating_node\":null,\"shard\":1,\"index\":\"ag_03\"},\"state\":\"STARTED\",\"index\":{\"size\":\"99b\",\"size_in_bytes\":99},\"translog\":{\"id\":1381731770058,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":1,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":7,\"total_time\":\"86ms\",\"total_time_in_millis\":86}},{\"routing\":{\"state\":\"STARTED\",\"primary\":false,\"node\":\"PO1wHIidQo-w7sGHaYHvjg\",\"relocating_node\":null,\"shard\":1,\"index\":\"ag_03\"},\"state\":\"STARTED\",\"index\":{\"size\":\"79b\",\"size_in_bytes\":79},\"translog\":{\"id\":1381731770058,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":7,\"total_time\":\"137ms\",\"total_time_in_millis\":137}}]}}},false]},{\"name\":\"live\",\"max\":3,\"min\":3,\"indices\":[false,false,false,{\"name\":\"ag_03\",\"state\":\"open\",\"metadata\":{\"state\":\"open\",\"settings\":{\"index.number_of_replicas\":\"1\",\"index.number_of_shards\":\"2\",\"index.version.created\":\"900599\"},\"mappings\":{},\"aliases\":[\"search\",\"live\"]},\"status\":{\"index\":{\"primary_size\":\"198b\",\"primary_size_in_bytes\":198,\"size\":\"356b\",\"size_in_bytes\":356},\"translog\":{\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":2,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":27,\"total_time\":\"598ms\",\"total_time_in_millis\":598},\"shards\":{\"0\":[{\"routing\":{\"state\":\"STARTED\",\"primary\":true,\"node\":\"aBuoaKR5QVCfUZHgrJEfVg\",\"relocating_node\":null,\"shard\":0,\"index\":\"ag_03\"},\"state\":\"STARTED\",\"index\":{\"size\":\"99b\",\"size_in_bytes\":99},\"translog\":{\"id\":1381731770063,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":1,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":6,\"total_time\":\"101ms\",\"total_time_in_millis\":101}},{\"routing\":{\"state\":\"STARTED\",\"primary\":false,\"node\":\"3Rbfod0sS9eZ6VrOkY0JKw\",\"relocating_node\":null,\"shard\":0,\"index\":\"ag_03\"},\"state\":\"STARTED\",\"index\":{\"size\":\"79b\",\"size_in_bytes\":79},\"translog\":{\"id\":1381731770063,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":7,\"total_time\":\"274ms\",\"total_time_in_millis\":274}}],\"1\":[{\"routing\":{\"state\":\"STARTED\",\"primary\":true,\"node\":\"cqTmT9GLSlSWx-B7pvM--w\",\"relocating_node\":null,\"shard\":1,\"index\":\"ag_03\"},\"state\":\"STARTED\",\"index\":{\"size\":\"99b\",\"size_in_bytes\":99},\"translog\":{\"id\":1381731770058,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":1,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":7,\"total_time\":\"86ms\",\"total_time_in_millis\":86}},{\"routing\":{\"state\":\"STARTED\",\"primary\":false,\"node\":\"PO1wHIidQo-w7sGHaYHvjg\",\"relocating_node\":null,\"shard\":1,\"index\":\"ag_03\"},\"state\":\"STARTED\",\"index\":{\"size\":\"79b\",\"size_in_bytes\":79},\"translog\":{\"id\":1381731770058,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":7,\"total_time\":\"137ms\",\"total_time_in_millis\":137}}]}}},false]}]},\n\t\t\"indices\":[{\"name\":null},{\"name\":\"_river\",\"state\":\"open\",\"metadata\":{\"state\":\"open\",\"settings\":{\"index.version.created\":\"900599\",\"index.number_of_replicas\":\"1\",\"index.number_of_shards\":\"1\"},\"mappings\":{},\"aliases\":[]},\"status\":{\"index\":{\"primary_size\":\"79b\",\"primary_size_in_bytes\":79,\"size\":\"158b\",\"size_in_bytes\":158},\"translog\":{\"operations\":0},\"docs\":{\"num_docs\":1,\"max_doc\":1,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":1,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":124,\"total_time\":\"2.4s\",\"total_time_in_millis\":2465},\"shards\":{\"0\":[{\"routing\":{\"state\":\"STARTED\",\"primary\":false,\"node\":\"SwCmq0QKQuShZcJAbuW8OQ\",\"relocating_node\":null,\"shard\":0,\"index\":\"_river\"},\"state\":\"STARTED\",\"index\":{\"size\":\"79b\",\"size_in_bytes\":79},\"translog\":{\"id\":1380240228838,\"operations\":0},\"docs\":{\"num_docs\":187162420,\"max_doc\":187171320,\"deleted_docs\":9},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":62,\"total_time\":\"1.6s\",\"total_time_in_millis\":1632}},{\"routing\":{\"state\":\"STARTED\",\"primary\":true,\"node\":\"3Rbfod0sS9eZ6VrOkY0JKw\",\"relocating_node\":null,\"shard\":0,\"index\":\"_river\"},\"state\":\"STARTED\",\"index\":{\"size\":\"79b\",\"size_in_bytes\":79},\"translog\":{\"id\":1380240228838,\"operations\":0},\"docs\":{\"num_docs\":187162420,\"max_doc\":187171320,\"deleted_docs\":9},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":1,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":62,\"total_time\":\"833ms\",\"total_time_in_millis\":833}}]}}},{\"name\":\"ag_01\",\"state\":\"open\",\"metadata\":{\"state\":\"open\",\"settings\":{\"index.number_of_replicas\":\"1\",\"index.number_of_shards\":\"2\",\"index.version.created\":\"900599\"},\"mappings\":{},\"aliases\":[\"search\"]},\"status\":{\"index\":{\"primary_size\":\"198b\",\"primary_size_in_bytes\":198,\"size\":\"356b\",\"size_in_bytes\":356},\"translog\":{\"operations\":0},\"docs\":{\"num_docs\":18716242,\"max_doc\":18717132,\"deleted_docs\":9},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":2,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":27,\"total_time\":\"1.4s\",\"total_time_in_millis\":1435},\"shards\":{\"0\":[{\"routing\":{\"state\":\"STARTED\",\"primary\":false,\"node\":\"SwCmq0QKQuShZcJAbuW8OQ\",\"relocating_node\":null,\"shard\":0,\"index\":\"ag_01\"},\"state\":\"STARTED\",\"index\":{\"size\":\"79b\",\"size_in_bytes\":79},\"translog\":{\"id\":1381731712651,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":7,\"total_time\":\"216ms\",\"total_time_in_millis\":216}},{\"routing\":{\"state\":\"STARTED\",\"primary\":true,\"node\":\"aBuoaKR5QVCfUZHgrJEfVg\",\"relocating_node\":null,\"shard\":0,\"index\":\"ag_01\"},\"state\":\"STARTED\",\"index\":{\"size\":\"99b\",\"size_in_bytes\":99},\"translog\":{\"id\":1381731712651,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":1,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":7,\"total_time\":\"382ms\",\"total_time_in_millis\":382}}],\"1\":[{\"routing\":{\"state\":\"STARTED\",\"primary\":true,\"node\":\"cqTmT9GLSlSWx-B7pvM--w\",\"relocating_node\":null,\"shard\":1,\"index\":\"ag_01\"},\"state\":\"STARTED\",\"index\":{\"size\":\"99b\",\"size_in_bytes\":99},\"translog\":{\"id\":1381731712637,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":1,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":7,\"total_time\":\"643ms\",\"total_time_in_millis\":643}},{\"routing\":{\"state\":\"STARTED\",\"primary\":false,\"node\":\"jw4owU-ZQgOYdM7ElauDTg\",\"relocating_node\":null,\"shard\":1,\"index\":\"ag_01\"},\"state\":\"STARTED\",\"index\":{\"size\":\"79b\",\"size_in_bytes\":79},\"translog\":{\"id\":1381731712637,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":6,\"total_time\":\"194ms\",\"total_time_in_millis\":194}}]}}},{\"name\":\"ag_02\",\"state\":\"open\",\"metadata\":{\"state\":\"open\",\"settings\":{\"index.number_of_replicas\":\"1\",\"index.number_of_shards\":\"3\",\"index.version.created\":\"900599\"},\"mappings\":{},\"aliases\":[\"search\"]},\"status\":{\"index\":{\"primary_size\":\"297b\",\"primary_size_in_bytes\":297,\"size\":\"534b\",\"size_in_bytes\":534},\"translog\":{\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":3,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":20,\"total_time\":\"340ms\",\"total_time_in_millis\":340},\"shards\":{\"0\":[{\"routing\":{\"state\":\"STARTED\",\"primary\":true,\"node\":\"jw4owU-ZQgOYdM7ElauDTg\",\"relocating_node\":null,\"shard\":0,\"index\":\"ag_02\"},\"state\":\"STARTED\",\"index\":{\"size\":\"99b\",\"size_in_bytes\":99},\"translog\":{\"id\":1381749663369,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":1,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":3,\"total_time\":\"107ms\",\"total_time_in_millis\":107}},{\"routing\":{\"state\":\"STARTED\",\"primary\":false,\"node\":\"3Rbfod0sS9eZ6VrOkY0JKw\",\"relocating_node\":null,\"shard\":0,\"index\":\"ag_02\"},\"state\":\"STARTED\",\"index\":{\"size\":\"79b\",\"size_in_bytes\":79},\"translog\":{\"id\":1381749663369,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":3,\"total_time\":\"4ms\",\"total_time_in_millis\":4}}],\"1\":[{\"routing\":{\"state\":\"STARTED\",\"primary\":false,\"node\":\"cqTmT9GLSlSWx-B7pvM--w\",\"relocating_node\":null,\"shard\":1,\"index\":\"ag_02\"},\"state\":\"STARTED\",\"index\":{\"size\":\"79b\",\"size_in_bytes\":79},\"translog\":{\"id\":1381749663385,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":3,\"total_time\":\"75ms\",\"total_time_in_millis\":75}},{\"routing\":{\"state\":\"STARTED\",\"primary\":true,\"node\":\"PO1wHIidQo-w7sGHaYHvjg\",\"relocating_node\":null,\"shard\":1,\"index\":\"ag_02\"},\"state\":\"STARTED\",\"index\":{\"size\":\"99b\",\"size_in_bytes\":99},\"translog\":{\"id\":1381749663385,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":1,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":4,\"total_time\":\"122ms\",\"total_time_in_millis\":122}}],\"2\":[{\"routing\":{\"state\":\"STARTED\",\"primary\":true,\"node\":\"SwCmq0QKQuShZcJAbuW8OQ\",\"relocating_node\":null,\"shard\":2,\"index\":\"ag_02\"},\"state\":\"STARTED\",\"index\":{\"size\":\"99b\",\"size_in_bytes\":99},\"translog\":{\"id\":1381749663407,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":1,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":4,\"total_time\":\"17ms\",\"total_time_in_millis\":17}},{\"routing\":{\"state\":\"STARTED\",\"primary\":false,\"node\":\"aBuoaKR5QVCfUZHgrJEfVg\",\"relocating_node\":null,\"shard\":2,\"index\":\"ag_02\"},\"state\":\"STARTED\",\"index\":{\"size\":\"79b\",\"size_in_bytes\":79},\"translog\":{\"id\":1381749663407,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":3,\"total_time\":\"15ms\",\"total_time_in_millis\":15}}]}}},{\"name\":\"ag_03\",\"state\":\"open\",\"metadata\":{\"state\":\"open\",\"settings\":{\"index.number_of_replicas\":\"1\",\"index.number_of_shards\":\"2\",\"index.version.created\":\"900599\"},\"mappings\":{},\"aliases\":[\"search\",\"live\"]},\"status\":{\"index\":{\"primary_size\":\"198b\",\"primary_size_in_bytes\":198,\"size\":\"356b\",\"size_in_bytes\":356},\"translog\":{\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":2,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":27,\"total_time\":\"598ms\",\"total_time_in_millis\":598},\"shards\":{\"0\":[{\"routing\":{\"state\":\"STARTED\",\"primary\":true,\"node\":\"aBuoaKR5QVCfUZHgrJEfVg\",\"relocating_node\":null,\"shard\":0,\"index\":\"ag_03\"},\"state\":\"STARTED\",\"index\":{\"size\":\"99b\",\"size_in_bytes\":99},\"translog\":{\"id\":1381731770063,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":1,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":6,\"total_time\":\"101ms\",\"total_time_in_millis\":101}},{\"routing\":{\"state\":\"STARTED\",\"primary\":false,\"node\":\"3Rbfod0sS9eZ6VrOkY0JKw\",\"relocating_node\":null,\"shard\":0,\"index\":\"ag_03\"},\"state\":\"STARTED\",\"index\":{\"size\":\"79b\",\"size_in_bytes\":79},\"translog\":{\"id\":1381731770063,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":7,\"total_time\":\"274ms\",\"total_time_in_millis\":274}}],\"1\":[{\"routing\":{\"state\":\"STARTED\",\"primary\":true,\"node\":\"cqTmT9GLSlSWx-B7pvM--w\",\"relocating_node\":null,\"shard\":1,\"index\":\"ag_03\"},\"state\":\"STARTED\",\"index\":{\"size\":\"99b\",\"size_in_bytes\":99},\"translog\":{\"id\":1381731770058,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":1,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":7,\"total_time\":\"86ms\",\"total_time_in_millis\":86}},{\"routing\":{\"state\":\"STARTED\",\"primary\":false,\"node\":\"PO1wHIidQo-w7sGHaYHvjg\",\"relocating_node\":null,\"shard\":1,\"index\":\"ag_03\"},\"state\":\"STARTED\",\"index\":{\"size\":\"79b\",\"size_in_bytes\":79},\"translog\":{\"id\":1381731770058,\"operations\":0},\"docs\":{\"num_docs\":0,\"max_doc\":0,\"deleted_docs\":0},\"merges\":{\"current\":0,\"current_docs\":0,\"current_size\":\"0b\",\"current_size_in_bytes\":0,\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0,\"total_docs\":0,\"total_size\":\"0b\",\"total_size_in_bytes\":0},\"refresh\":{\"total\":0,\"total_time\":\"0s\",\"total_time_in_millis\":0},\"flush\":{\"total\":7,\"total_time\":\"137ms\",\"total_time_in_millis\":137}}]}}},{\"name\":\"twitter_river\",\"state\":\"close\",\"metadata\":{\"state\":\"close\",\"settings\":{\"index.number_of_replicas\":\"1\",\"index.version.created\":\"900599\",\"index.number_of_shards\":\"5\"},\"mappings\":{\"status\":{\"properties\":{\"text\":{\"type\":\"string\"},\"location\":{\"properties\":{\"lon\":{\"type\":\"double\"},\"lat\":{\"type\":\"double\"}}},\"link\":{\"properties\":{\"start\":{\"type\":\"long\"},\"expand_url\":{\"type\":\"string\"},\"display_url\":{\"type\":\"string\"},\"url\":{\"type\":\"string\"},\"end\":{\"type\":\"long\"}}},\"hashtag\":{\"properties\":{\"text\":{\"type\":\"string\"},\"start\":{\"type\":\"long\"},\"end\":{\"type\":\"long\"}}},\"truncated\":{\"type\":\"boolean\"},\"source\":{\"type\":\"string\"},\"retweet\":{\"properties\":{\"id\":{\"type\":\"long\"},\"user_screen_name\":{\"type\":\"string\"},\"retweet_count\":{\"type\":\"long\"},\"user_id\":{\"type\":\"long\"}}},\"created_at\":{\"format\":\"dateOptionalTime\",\"type\":\"date\"},\"retweet_count\":{\"type\":\"long\"},\"in_reply\":{\"properties\":{\"user_screen_name\":{\"type\":\"string\"},\"status\":{\"type\":\"long\"},\"user_id\":{\"type\":\"long\"}}},\"mention\":{\"properties\":{\"id\":{\"type\":\"long\"},\"start\":{\"type\":\"long\"},\"name\":{\"type\":\"string\"},\"screen_name\":{\"type\":\"string\"},\"end\":{\"type\":\"long\"}}},\"place\":{\"properties\":{\"id\":{\"type\":\"string\"},\"name\":{\"type\":\"string\"},\"type\":{\"type\":\"string\"},\"country_code\":{\"type\":\"string\"},\"url\":{\"type\":\"string\"},\"full_name\":{\"type\":\"string\"},\"country\":{\"type\":\"string\"}}},\"user\":{\"properties\":{\"id\":{\"type\":\"long\"},\"profile_image_url_https\":{\"type\":\"string\"},\"location\":{\"type\":\"string\"},\"description\":{\"type\":\"string\"},\"name\":{\"type\":\"string\"},\"screen_name\":{\"type\":\"string\"},\"profile_image_url\":{\"type\":\"string\"}}}}}},\"aliases\":[]},\"status\":null}]\n\t};\n\n\twindow.builder = function() {\n\t\treturn new ui.NodesView({\n\t\t\tinteractive: true,\n\t\t\tdata: data\n\t\t});\n\t};\n\n});"
  },
  {
    "path": "src/app/ui/page/page.js",
    "content": "(function( app ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.Page = ui.AbstractWidget.extend({\n\t\tshow: function() {\n\t\t\tthis.el.show();\n\t\t},\n\t\thide: function() {\n\t\t\tthis.el.hide();\n\t\t}\n\t});\n\n})( this.app );"
  },
  {
    "path": "src/app/ui/panelForm/panelForm.css",
    "content": ".uiPanelForm-field {\n\tdisplay: block;\n\tpadding: 2px 0;\n\tclear: both;\n}\n\n.uiPanelForm-label {\n\tfloat: left;\n\twidth: 200px;\n\tpadding: 3px 7px;\n\ttext-align: right;\n}\n"
  },
  {
    "path": "src/app/ui/panelForm/panelForm.js",
    "content": "(function( $, app ) {\n\n\tvar ui = app.ns(\"ui\");\n\tvar ut = app.ns(\"ut\");\n\n\tui.PanelForm = ui.AbstractWidget.extend({\n\t\tdefaults: {\n\t\t\tfields: null\t// (required) instanceof app.ux.FieldCollection\n\t\t},\n\t\tinit: function(parent) {\n\t\t\tthis._super();\n\t\t\tthis.el = $.joey(this._main_template());\n\t\t\tthis.attach( parent );\n\t\t},\n\t\t_main_template: function() {\n\t\t\treturn { tag: \"DIV\", id: this.id(), cls: \"uiPanelForm\", children: this.config.fields.fields.map(this._field_template, this) };\n\t\t},\n\t\t_field_template: function(field) {\n\t\t\treturn { tag: \"LABEL\", cls: \"uiPanelForm-field\", children: [\n\t\t\t\t{ tag: \"DIV\", cls: \"uiPanelForm-label\", children: [ field.label, ut.require_template(field) ] },\n\t\t\t\tfield\n\t\t\t]};\n\t\t}\n\t});\n\n})( this.jQuery, this.app );\n"
  },
  {
    "path": "src/app/ui/queryFilter/queryFilter.css",
    "content": ".uiQueryFilter {\n\twidth: 350px;\n\tpadding: 5px;\n\tbackground: #d8e7ff;\n\tbackground: -moz-linear-gradient(left, #d8e7ff, #e8f1ff);\n\tbackground: -webkit-linear-gradient(left, #d8e7ff, #e8f1ff);\n}\n\n.uiQueryFilter DIV.uiQueryFilter-section {\n\tmargin-bottom: 5px;\n}\n\n.uiQueryFilter HEADER {\n\tdisplay: block;\n\tfont-variant: small-caps;\n\tfont-weight: bold;\n\tmargin: 5px 0;\n}\n\n.uiQueryFilter-aliases SELECT {\n\twidth: 100%;\n}\n\n.uiQueryFilter-booble {\n\tcursor: pointer;\n\tbackground: #e8f1ff;\n\tborder: 1px solid #e8f1ff;\n\tborder-radius: 5px;\n\tpadding: 1px 4px;\n\tmargin-bottom: 1px;\n\toverflow: hidden;\n\twhite-space: nowrap;\n}\n\n.uiQueryFilter-booble.selected {\n\tbackground: #dae3f0;\n\tborder-top: 1px solid #c8d4e6;\n\tborder-left: 1px solid #c8d4e6;\n\tborder-bottom: 1px solid #ffffff;\n\tborder-right: 1px solid #ffffff;\n}\n\n.uiQueryFilter-filterName {\n\tbackground-color: #cbdfff;\n\tmargin-bottom: 4px;\n\tpadding: 3px;\n\tcursor: pointer;\n}\n\n.uiQueryFilter-filters INPUT  {\n\twidth: 300px;\n}\n\n.uiQueryFilter-subMultiFields {\n\tpadding-left: 10px;\n}\n\n.uiQueryFilter-rangeHintFrom,\n.uiQueryFilter-rangeHintTo {\n\tmargin: 0;\n\topacity: 0.75;\n}"
  },
  {
    "path": "src/app/ui/queryFilter/queryFilter.js",
    "content": "(function( $, app, i18n ) {\n\n\tvar ui = app.ns(\"ui\");\n\tvar ut = app.ns(\"ut\");\n\n\tui.QueryFilter = ui.AbstractWidget.extend({\n\t\tdefaults: {\n\t\t\tmetadata: null,   // (required) instanceof app.data.MetaData\n\t\t\tquery: null       // (required) instanceof app.data.Query that the filters will act apon\n\t\t},\n\t\tinit: function() {\n\t\t\tthis._super();\n\t\t\tthis.metadata = this.config.metadata;\n\t\t\tthis.query = this.config.query;\n\t\t\tthis.el = $(this._main_template());\n\t\t},\n\t\thelpTypeMap: {\n\t\t\t\"date\" : \"QueryFilter.DateRangeHelp\"\n\t\t},\n\t\trequestUpdate: function(jEv) {\n\t\t\tif(jEv && jEv.originalEvent) { // we only want to update on real user interaction not generated events\n\t\t\t\tthis.query.setPage(1);\n\t\t\t\tthis.query.query();\n\t\t\t}\n\t\t},\n\t\tgetSpec: function(fieldName) {\n\t\t\treturn this.metadata.fields[fieldName];\n\t\t},\n\t\t_selectAlias_handler: function(jEv) {\n\t\t\tvar indices = (jEv.target.selectedIndex === 0) ? [] : this.metadata.getIndices($(jEv.target).val());\n\t\t\t$(\".uiQueryFilter-index\").each(function(i, el) {\n\t\t\t\tvar jEl = $(el);\n\t\t\t\tif(indices.contains(jEl.text()) !== jEl.hasClass(\"selected\")) {\n\t\t\t\t\tjEl.click();\n\t\t\t\t}\n\t\t\t});\n\t\t\tthis.requestUpdate(jEv);\n\t\t},\n\t\t_selectIndex_handler: function(jEv) {\n\t\t\tvar jEl = $(jEv.target).closest(\".uiQueryFilter-index\");\n\t\t\tjEl.toggleClass(\"selected\");\n\t\t\tvar selected = jEl.hasClass(\"selected\");\n\t\t\tthis.query.setIndex(jEl.text(), selected);\n\t\t\tif(selected) {\n\t\t\t\tvar types = this.metadata.getTypes(this.query.indices);\n\t\t\t\tthis.el.find(\"DIV.uiQueryFilter-type.selected\").each(function(n, el) {\n\t\t\t\t\tif(! types.contains($(el).text())) {\n\t\t\t\t\t\t$(el).click();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t\tthis.requestUpdate(jEv);\n\t\t},\n\t\t_selectType_handler: function(jEv) {\n\t\t\tvar jEl = $(jEv.target).closest(\".uiQueryFilter-type\");\n\t\t\tjEl.toggleClass(\"selected\");\n\t\t\tvar type = jEl.text(), selected = jEl.hasClass(\"selected\");\n\t\t\tthis.query.setType(type, selected);\n\t\t\tif(selected) {\n\t\t\t\tvar indices = this.metadata.types[type].indices;\n\t\t\t\t// es throws a 500 if searching an index for a type it does not contain - so we prevent that\n\t\t\t\tthis.el.find(\"DIV.uiQueryFilter-index.selected\").each(function(n, el) {\n\t\t\t\t\tif(! indices.contains($(el).text())) {\n\t\t\t\t\t\t$(el).click();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\t// es throws a 500 if you specify types from different indices with _all\n\t\t\t\tjEl.siblings(\".uiQueryFilter-type.selected\").forEach(function(el) {\n\t\t\t\t\tif(this.metadata.types[$(el).text()].indices.intersection(indices).length === 0) {\n\t\t\t\t\t\t$(el).click();\n\t\t\t\t\t}\n\t\t\t\t}, this);\n\t\t\t}\n\t\t\tthis.requestUpdate(jEv);\n\t\t},\n\t\t_openFilter_handler: function(section) {\n\t\t\tvar field_name = section.config.title;\n\t\t\tif(! section.loaded) {\n\t\t\t\tvar spec = this.getSpec(field_name);\n\t\t\t\tif(spec.core_type === \"string\") {\n\t\t\t\t\tsection.body.append(this._textFilter_template(spec));\n\t\t\t\t} else if(spec.core_type === \"date\") {\n\t\t\t\t\tsection.body.append(this._dateFilter_template(spec));\n\t\t\t\t\tsection.body.append(new ui.DateHistogram({ printEl: section.body.find(\"INPUT\"), cluster: this.cluster, query: this.query, spec: spec }));\n\t\t\t\t} else if(spec.core_type === \"number\") {\n\t\t\t\t\tsection.body.append(this._numericFilter_template(spec));\n\t\t\t\t} else if(spec.core_type === 'boolean') {\n\t\t\t\t\tsection.body.append(this._booleanFilter_template(spec));\n\t\t\t\t} else if (spec.core_type === 'multi_field') {\n\t\t\t\t\tsection.body.append(this._multiFieldFilter_template(section, spec));\n\t\t\t\t} \n\t\t\t\tsection.loaded = true;\n\t\t\t}\n\t\t\tsection.on(\"animComplete\", function(section) { section.body.find(\"INPUT\").focus(); });\n\t\t},\n\t\t_textFilterChange_handler: function(jEv) {\n\t\t\tvar jEl = $(jEv.target).closest(\"INPUT\");\n\t\t\tvar val = jEl.val();\n\t\t\tvar spec = jEl.data(\"spec\");\n\t\t\tvar uqids = jEl.data(\"uqids\") || [];\n\t\t\tuqids.forEach(function(uqid) {\n\t\t\t\tuqid && this.query.removeClause(uqid);\n\t\t\t}, this);\n\t\t\tif(val.length) {\n\t\t\t\tif(jEl[0] === document.activeElement && jEl[0].selectionStart === jEl[0].selectionEnd) {\n\t\t\t\t\tval = val.replace(new RegExp(\"(.{\"+jEl[0].selectionStart+\"})\"), \"$&*\");\n\t\t\t\t}\n\t\t\t\tuqids = val.split(/\\s+/).map(function(term) {\n\t\t\t\t\t// Figure out the actual field name - needed for multi_field, because\n\t\t\t\t\t// querying for \"field.field\" will not work. Simply \"field\" must be used\n\t\t\t\t\t// if nothing is aliased.\n\t\t\t\t\tvar fieldNameParts = spec.field_name.split('.');\n\t\t\t\t\tvar part = fieldNameParts.length - 1;\n\t\t\t\t\tvar name = fieldNameParts[part];\n\t\t\t\t\twhile (part >= 1) {\n\t\t\t\t\t\tif (fieldNameParts[part] !== fieldNameParts[part - 1]) {\n\t\t\t\t\t\t\tname = fieldNameParts[part - 1] + \".\" + name;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tpart--;\n\t\t\t\t\t}\n\t\t\t\t\treturn term && this.query.addClause(term, name, \"wildcard\", \"must\");\n\t\t\t\t}, this);\n\t\t\t}\n\t\t\tjEl.data(\"uqids\", uqids);\n\t\t\tthis.requestUpdate(jEv);\n\t\t},\n\t\t_dateFilterChange_handler: function(jEv) {\n\t\t\tvar jEl = $(jEv.target).closest(\"INPUT\");\n\t\t\tvar val = jEl.val();\n\t\t\tvar spec = jEl.data(\"spec\");\n\t\t\tvar uqid = jEl.data(\"uqid\") || null;\n\t\t\tvar range = window.dateRangeParser.parse(val);\n\t\t\tvar lastRange = jEl.data(\"lastRange\");\n\t\t\tif(!range || (lastRange && lastRange.start === range.start && lastRange.end === range.end)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tuqid && this.query.removeClause(uqid);\n\t\t\tif((range.start && range.end) === null) {\n\t\t\t\tuqid = null;\n\t\t\t} else {\n\t\t\t\tvar value = {};\n\t\t\t\tif( range.start ) {\n\t\t\t\t\tvalue[\"gte\"] = range.start;\n\t\t\t\t}\n\t\t\t\tif( range.end ) {\n\t\t\t\t\tvalue[\"lte\"] = range.end;\n\t\t\t\t}\n\t\t\t\tuqid = this.query.addClause( value, spec.field_name, \"range\", \"must\");\n\t\t\t}\n\t\t\tjEl.data(\"lastRange\", range);\n\t\t\tjEl.siblings(\".uiQueryFilter-rangeHintFrom\")\n\t\t\t\t.text(i18n.text(\"QueryFilter.DateRangeHint.from\", range.start && new Date(range.start).toUTCString()));\n\t\t\tjEl.siblings(\".uiQueryFilter-rangeHintTo\")\n\t\t\t\t.text(i18n.text(\"QueryFilter.DateRangeHint.to\", range.end && new Date(range.end).toUTCString()));\n\t\t\tjEl.data(\"uqid\", uqid);\n\t\t\tthis.requestUpdate(jEv);\n\t\t},\n\t\t_numericFilterChange_handler: function(jEv) {\n\t\t\tvar jEl = $(jEv.target).closest(\"INPUT\");\n\t\t\tvar val = jEl.val();\n\t\t\tvar spec = jEl.data(\"spec\");\n\t\t\tvar uqid = jEl.data(\"uqid\") || null;\n\t\t\tvar lastRange = jEl.data(\"lastRange\");\n\t\t\tvar range = (function(val) {\n\t\t\t\tvar ops = val.split(/->|<>|</).map( function(v) { return parseInt(v.trim(), 10); });\n\t\t\t\tif(/<>/.test(val)) {\n\t\t\t\t\treturn { gte: (ops[0] - ops[1]), lte: (ops[0] + ops[1]) };\n\t\t\t\t} else if(/->|</.test(val)) {\n\t\t\t\t\treturn { gte: ops[0], lte: ops[1] };\n\t\t\t\t} else {\n\t\t\t\t\treturn { gte: ops[0], lte: ops[0] };\n\t\t\t\t}\n\t\t\t})(val || \"\");\n\t\t\tif(!range || (lastRange && lastRange.lte === range.lte && lastRange.gte === range.gte)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tjEl.data(\"lastRange\", range);\n\t\t\tuqid && this.query.removeClause(uqid);\n\t\t\tuqid = this.query.addClause( range, spec.field_name, \"range\", \"must\");\n\t\t\tjEl.data(\"uqid\", uqid);\n\t\t\tthis.requestUpdate(jEv);\n\t\t},\n\t\t_booleanFilterChange_handler: function( jEv ) {\n\t\t\tvar jEl = $(jEv.target).closest(\"SELECT\");\n\t\t\tvar val = jEl.val();\n\t\t\tvar spec = jEl.data(\"spec\");\n\t\t\tvar uqid = jEl.data(\"uqid\") || null;\n\t\t\tuqid && this.query.removeClause(uqid);\n\t\t\tif(val === \"true\" || val === \"false\") {\n\t\t\t\tjEl.data(\"uqid\", this.query.addClause(val, spec.field_name, \"term\", \"must\") );\n\t\t\t}\n\t\t\tthis.requestUpdate(jEv);\n\t\t},\n\t\t_main_template: function() {\n\t\t\treturn { tag: \"DIV\", id: this.id(), cls: \"uiQueryFilter\", children: [\n\t\t\t\tthis._aliasSelector_template(),\n\t\t\t\tthis._indexSelector_template(),\n\t\t\t\tthis._typesSelector_template(),\n\t\t\t\tthis._filters_template()\n\t\t\t] };\n\t\t},\n\t\t_aliasSelector_template: function() {\n\t\t\tvar aliases = Object.keys(this.metadata.aliases).sort();\n\t\t\taliases.unshift( i18n.text(\"QueryFilter.AllIndices\") );\n\t\t\treturn { tag: \"DIV\", cls: \"uiQueryFilter-section uiQueryFilter-aliases\", children: [\n\t\t\t\t{ tag: \"SELECT\", onChange: this._selectAlias_handler, children: aliases.map(ut.option_template) }\n\t\t\t] };\n\t\t},\n\t\t_indexSelector_template: function() {\n\t\t\tvar indices = Object.keys( this.metadata.indices ).sort();\n\t\t\treturn { tag: \"DIV\", cls: \"uiQueryFilter-section uiQueryFilter-indices\", children: [\n\t\t\t\t{ tag: \"HEADER\", text: i18n.text(\"QueryFilter-Header-Indices\") },\n\t\t\t\t{ tag: \"DIV\", onClick: this._selectIndex_handler, children: indices.map( function( name ) {\n\t\t\t\t\treturn { tag: \"DIV\", cls: \"uiQueryFilter-booble uiQueryFilter-index\", text: name };\n\t\t\t\t})}\n\t\t\t] };\n\t\t},\n\t\t_typesSelector_template: function() {\n\t\t\tvar types = Object.keys( this.metadata.types ).sort();\n\t\t\treturn { tag: \"DIV\", cls: \"uiQueryFilter-section uiQueryFilter-types\", children: [\n\t\t\t\t{ tag: \"HEADER\", text: i18n.text(\"QueryFilter-Header-Types\") },\n\t\t\t\t{ tag: \"DIV\", onClick: this._selectType_handler, children: types.map( function( name ) {\n\t\t\t\t\treturn { tag: \"DIV\", cls: \"uiQueryFilter-booble uiQueryFilter-type\", text: name };\n\t\t\t\t})}\n\t\t\t] };\n\t\t},\n\t\t_filters_template: function() {\n\t\t\tvar _metadataFields = this.metadata.fields;\n\t\t\tvar fields = Object.keys( _metadataFields ).sort()\n\t\t\t\t.filter(function(d) { return (_metadataFields[d].core_type !== undefined); });\n\t\t\treturn { tag: \"DIV\", cls: \"uiQueryFilter-section uiQueryFilter-filters\", children: [\n\t\t\t\t{ tag: \"HEADER\", text: i18n.text(\"QueryFilter-Header-Fields\") },\n\t\t\t\t{ tag: \"DIV\", children: fields.map( function(name ) {\n\t\t\t\t\treturn new app.ui.SidebarSection({\n\t\t\t\t\t\ttitle: name,\n\t\t\t\t\t\thelp: this.helpTypeMap[this.metadata.fields[ name ].type],\n\t\t\t\t\t\tonShow: this._openFilter_handler\n\t\t\t\t\t});\n\t\t\t\t}, this ) }\n\t\t\t] };\n\t\t},\n\t\t_textFilter_template: function(spec) {\n\t\t\treturn { tag: \"INPUT\", data: { spec: spec }, onKeyup: this._textFilterChange_handler };\n\t\t},\n\t\t_dateFilter_template: function(spec) {\n\t\t\treturn { tag: \"DIV\", children: [\n\t\t\t\t{ tag: \"INPUT\", data: { spec: spec }, onKeyup: this._dateFilterChange_handler },\n\t\t\t\t{ tag: \"PRE\", cls: \"uiQueryFilter-rangeHintFrom\", text: i18n.text(\"QueryFilter.DateRangeHint.from\", \"\")},\n\t\t\t\t{ tag: \"PRE\", cls: \"uiQueryFilter-rangeHintTo\", text: i18n.text(\"QueryFilter.DateRangeHint.to\", \"\") }\n\t\t\t]};\n\t\t},\n\t\t_numericFilter_template: function(spec) {\n\t\t\treturn { tag: \"INPUT\", data: { spec: spec }, onKeyup: this._numericFilterChange_handler };\n\t\t},\n\t\t_booleanFilter_template: function(spec) {\n\t\t\treturn { tag: \"SELECT\", data: { spec: spec }, onChange: this._booleanFilterChange_handler,\n\t\t\t\tchildren: [ i18n.text(\"QueryFilter.AnyValue\"), \"true\", \"false\" ].map( function( val ) {\n\t\t\t\t\treturn { tag: \"OPTION\", value: val, text: val };\n\t\t\t\t})\n\t\t\t};\n\t\t},\n\t\t_multiFieldFilter_template: function(section, spec) {\n\t\t\treturn {\n\t\t\t\ttag : \"DIV\", cls : \"uiQueryFilter-subMultiFields\", children : acx.eachMap(spec.fields, function(name, data) {\n\t\t\t\t\tif (name === spec.field_name) {\n\t\t\t\t\t\tsection.config.title = spec.field_name + \".\" + name;\n\t\t\t\t\t\treturn this._openFilter_handler(section);\n\t\t\t\t\t}\n\t\t\t\t\treturn new app.ui.SidebarSection({\n\t\t\t\t\t\ttitle : data.field_name, help : this.helpTypeMap[data.type], onShow : this._openFilter_handler\n\t\t\t\t\t});\n\t\t\t\t}, this)\n\t\t\t};\n\t\t}\t\n\t});\n\n})( this.jQuery, this.app, this.i18n );\n"
  },
  {
    "path": "src/app/ui/refreshButton/refreshButton.js",
    "content": "(function( $, app, i18n ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.RefreshButton = ui.SplitButton.extend({\n\t\tdefaults: {\n\t\t\ttimer: -1\n\t\t},\n\t\tinit: function( parent ) {\n\t\t\tthis.config.label = i18n.text(\"General.RefreshResults\");\n\t\t\tthis._super( parent );\n\t\t\tthis.set( this.config.timer );\n\t\t},\n\t\tset: function( value ) {\n\t\t\tthis.value = value;\n\t\t\twindow.clearInterval( this._timer );\n\t\t\tif( this.value > 0 ) {\n\t\t\t\tthis._timer = window.setInterval( this._refresh_handler, this.value );\n\t\t\t}\n\t\t},\n\t\t_click_handler: function() {\n\t\t\tthis._refresh_handler();\n\t\t},\n\t\t_select_handler: function( el, event ) {\n\t\t\tthis.set( event.value );\n\t\t\tthis.fire(\"change\", this );\n\t\t},\n\t\t_refresh_handler: function() {\n\t\t\tthis.fire(\"refresh\", this );\n\t\t},\n\t\t_getItems: function() {\n\t\t\treturn [\n\t\t\t\t{ text: i18n.text(\"General.ManualRefresh\"), value: -1 },\n\t\t\t\t{ text: i18n.text(\"General.RefreshQuickly\"), value: 100 },\n\t\t\t\t{ text: i18n.text(\"General.Refresh5seconds\"), value: 5000 },\n\t\t\t\t{ text: i18n.text(\"General.Refresh1minute\"), value: 60000 }\n\t\t\t];\n\t\t}\n\t});\n\n})( this.jQuery, this.app, this.i18n );\n"
  },
  {
    "path": "src/app/ui/refreshButton/refreshButtonDemo.js",
    "content": "$( function() {\n\n\tvar ui = window.app.ns(\"ui\");\n\n\twindow.builder = function() {\n\t\treturn new ui.RefreshButton({\n\t\t\tonRefresh: function() { console.log(\"-> refresh\", arguments ); },\n\t\t\tonChange: function() { console.log(\"-> change\", arguments ); }\n\t\t});\n\t};\n\n});\n"
  },
  {
    "path": "src/app/ui/refreshButton/refreshButtonSpec.js",
    "content": "describe(\"app.ui.RefreshButton\", function() {\n\n\tvar RefreshButton = window.app.ui.RefreshButton;\n\n\tvar r, refresh_handler, change_handler;\n\n\tfunction openMenuPanel( button, label ) {\n\t\tbutton.el.find(\"BUTTON\").eq(1).click();\n\t\t$(\".uiMenuPanel-label:contains(\" + label + \")\").click();\n\t\ttest.clock.tick(); // menuPanel -> bind _close_handler\n\t}\n\n\n\tbeforeEach( function() {\n\t\ttest.clock.steal();\n\t\trefresh_handler = jasmine.createSpy(\"refresh_handler\");\n\t\tchange_handler = jasmine.createSpy(\"change_handler\");\n\t\tr = new RefreshButton({\n\t\t\tonRefresh: refresh_handler,\n\t\t\tonChange: change_handler\n\t\t});\n\t\tr.attach( document.body );\n\t});\n\n\tafterEach( function() {\n\t\tr.remove();\n\t\ttest.clock.restore();\n\t});\n\n\tit(\"should have an initial default value\", function() {\n\t\texpect( r.value ).toBe( -1 );\n\t});\n\n\tit(\"should fire a refresh event after clicking the refresh button \", function() {\n\t\tr.el.find(\"BUTTON\").eq(0).click();\n\n\t\texpect( refresh_handler ).toHaveBeenCalled();\n\t});\n\n\tit(\"should change the refresh rate when set it called\", function() {\n\t\tr.set( 100 );\n\t\texpect( r.value ).toBe( 100 );\n\t});\n\n\tit(\"should set an interval when rate is set to a positive value\", function() {\n\t\tr.set( 100 );\n\t\ttest.clock.tick();\n\t\texpect( refresh_handler.calls.count() ).toBe( 1 );\n\t});\n\n\tit(\"should not set an interval when rate is set to a non positive value\", function() {\n\t\tr.set( -1 );\n\t\ttest.clock.tick();\n\t\texpect( refresh_handler.calls.count() ).toBe( 0 );\n\t});\n\n\tit(\"should fire a refresh event on intervals if refresh menu item is set to quickly\", function() {\n\t\topenMenuPanel( r, \"quickly\" );\n\n\t\texpect( refresh_handler.calls.count() ).toBe( 0 );\n\t\ttest.clock.tick();\n\t\texpect( refresh_handler.calls.count() ).toBe( 1 );\n\t\ttest.clock.tick();\n\t\texpect( refresh_handler.calls.count() ).toBe( 2 );\n\t});\n\n\tit(\"should not fire refresh events when user selects Manual\", function() {\n\n\t\topenMenuPanel( r, \"quickly\" );\n\n\t\texpect( refresh_handler.calls.count() ).toBe( 0 );\n\t\ttest.clock.tick();\n\t\texpect( refresh_handler.calls.count() ).toBe( 1 );\n\n\t\topenMenuPanel( r, \"Manual\" );\n\n\t\ttest.clock.tick();\n\t\texpect( refresh_handler.calls.count() ).toBe( 1 );\n\t\ttest.clock.tick();\n\t\texpect( refresh_handler.calls.count() ).toBe( 1 );\n\t});\n\n\tit(\"should fire a change event when a new refresh rate is selected\", function() {\n\t\topenMenuPanel( r, \"quickly\" );\n\t\texpect( change_handler.calls.count() ).toBe( 1 );\n\t\texpect( r.value ).toBe( 100 );\n\t\topenMenuPanel( r, \"Manual\" );\n\t\texpect( change_handler.calls.count() ).toBe( 2 );\n\t\texpect( r.value ).toBe( -1 );\n\t});\n\n});\n"
  },
  {
    "path": "src/app/ui/resultTable/resultTable.js",
    "content": "(function( $, app ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.ResultTable = ui.Table.extend({\n\t\tdefaults: {\n\t\t\twidth: 500,\n\t\t\theight: 400\n\t\t},\n\n\t\tinit: function() {\n\t\t\tthis._super();\n\t\t\tthis.on(\"rowClick\", this._showPreview_handler);\n\t\t\tthis.selectedRow = null;\n\t\t\t$(document).bind(\"keydown\", this._nav_handler);\n\t\t},\n\t\tremove: function() {\n\t\t\t$(document).unbind(\"keydown\", this._nav_handler);\n\t\t\tthis._super();\n\t\t},\n\t\tattach: function(parent) {\n\t\t\tif(parent) {\n\t\t\t\tvar height = parent.height() || ( $(document).height() - parent.offset().top - 41 ); // 41 = height in px of .uiTable-tools + uiTable-header\n\t\t\t\tvar width = parent.width();\n\t\t\t\tthis.el.width( width );\n\t\t\t\tthis.body.width( width ).height( height );\n\t\t\t}\n\t\t\tthis._super(parent);\n\t\t},\n\t\tshowPreview: function(row) {\n\t\t\trow.addClass(\"selected\");\n\t\t\tthis.preview = new app.ui.JsonPanel({\n\t\t\t\ttitle: i18n.text(\"Browser.ResultSourcePanelTitle\"),\n\t\t\t\tjson: row.data(\"row\")._source,\n\t\t\t\tonClose: function() { row.removeClass(\"selected\"); }\n\t\t\t});\n\t\t},\n\t\t_nav_handler: function(jEv) {\n\t\t\tif(jEv.keyCode !== 40 && jEv.keyCode !== 38) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.selectedRow && this.preview && this.preview.remove();\n\t\t\tif(jEv.keyCode === 40) { // up arrow\n\t\t\t\tthis.selectedRow = this.selectedRow ? this.selectedRow.next(\"TR\") : this.body.find(\"TR:first\");\n\t\t\t} else if(jEv.keyCode === 38) { // down arrow\n\t\t\t\tthis.selectedRow = this.selectedRow ? this.selectedRow.prev(\"TR\") : this.body.find(\"TR:last\");\n\t\t\t}\n\t\t\tthis.selectedRow && this.showPreview(this.selectedRow);\n\t\t},\n\t\t_showPreview_handler: function(obj, data) {\n\t\t\tthis.showPreview(this.selectedRow = data.row);\n\t\t}\n\t});\n\n})( this.jQuery, this.app );\n"
  },
  {
    "path": "src/app/ui/selectMenuPanel/selectMenuPanel.css",
    "content": ".uiSelectMenuPanel .uiMenuPanel-label {\n\tmargin-left: 1em;\n\tpadding-left: 4px;\n}\n\n.uiSelectMenuPanel .uiMenuPanel-item.selected .uiMenuPanel-label:before {\n\tcontent: \"\\2713\";\n\twidth: 12px;\n\tmargin-left: -12px;\n\tdisplay: inline-block;\n}\n"
  },
  {
    "path": "src/app/ui/selectMenuPanel/selectMenuPanel.js",
    "content": "(function( app ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.SelectMenuPanel = ui.MenuPanel.extend({\n\t\tdefaults: {\n\t\t\titems: [],\t\t// (required) an array of menu items\n\t\t\tvalue: null\n\t\t},\n\t\t_baseCls: \"uiSelectMenuPanel uiMenuPanel\",\n\t\tinit: function() {\n\t\t\tthis.value = this.config.value;\n\t\t\tthis._super();\n\t\t},\n\t\t_getItems: function() {\n\t\t\treturn this.config.items.map( function( item ) {\n\t\t\t\treturn {\n\t\t\t\t\ttext: item.text,\n\t\t\t\t\tselected: this.value === item.value,\n\t\t\t\t\tonclick: function( jEv ) {\n\t\t\t\t\t\tvar el = $( jEv.target ).closest(\"LI\");\n\t\t\t\t\t\tel.parent().children().removeClass(\"selected\");\n\t\t\t\t\t\tel.addClass(\"selected\");\n\t\t\t\t\t\tthis.fire( \"select\", this, { value: item.value } );\n\t\t\t\t\t\tthis.value = item.value;\n\t\t\t\t\t}.bind(this)\n\t\t\t\t};\n\t\t\t}, this );\n\n\t\t}\n\t});\n\n})( this.app );\n"
  },
  {
    "path": "src/app/ui/sidebarSection/sidebarSection.css",
    "content": ".uiSidebarSection-head {\n\tbackground-color: #b9cfff;\n\tbackground-image: url('data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAcCAMAAABifa5OAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAMAUExURQUCFf///wICAgMDAwQEBAUFBQYGBgcHBwgICAkJCQoKCgsLCwwMDA0NDQ4ODg8PDxAQEBERERISEhMTExQUFBUVFRYWFhcXFxgYGBkZGRoaGhsbGxwcHB0dHR4eHh8fHyAgICEhISIiIiMjIyQkJCUlJSYmJicnJygoKCkpKSoqKisrKywsLC0tLS4uLi8vLzAwMDExMTIyMjMzMzQ0NDU1NTY2Njc3Nzg4ODk5OTo6Ojs7Ozw8PD09PT4+Pj8/P0BAQEFBQUJCQkNDQ0REREVFRUZGRkdHR0hISElJSUpKSktLS0xMTE1NTU5OTk9PT1BQUFFRUVJSUlNTU1RUVFVVVVZWVldXV1hYWFlZWVpaWltbW1xcXF1dXV5eXl9fX2BgYGFhYWJiYmNjY2RkZGVlZWZmZmdnZ2hoaGlpaWpqamtra2xsbG1tbW5ubm9vb3BwcHFxcXJycnNzc3R0dHV1dXZ2dnd3d3h4eHl5eXp6ent7e3x8fH19fX5+fn9/f4CAgIGBgYKCgoODg4SEhIWFhYaGhoeHh4iIiImJiYqKiouLi4yMjI2NjY6Ojo+Pj5CQkJGRkZKSkpOTk5SUlJWVlZaWlpeXl5iYmJmZmZqampubm5ycnJ2dnZ6enp+fn6CgoKGhoaKioqOjo6SkpKWlpaampqenp6ioqKmpqaqqqqurq6ysrK2tra6urq+vr7CwsLGxsbKysrOzs7S0tLW1tba2tre3t7i4uLm5ubq6uru7u7y8vL29vb6+vr+/v8DAwMHBwcLCwsPDw8TExMXFxcbGxsfHx8jIyMnJycrKysvLy8zMzM3Nzc7Ozs/Pz9DQ0NHR0dLS0tPT09TU1NXV1dbW1tfX19jY2NnZ2dra2tvb29zc3N3d3d7e3t/f3+Dg4OHh4eLi4uPj4+Tk5OXl5ebm5ufn5+jo6Onp6erq6uvr6+zs7O3t7e7u7u/v7/Dw8PHx8fLy8vPz8/T09PX19fb29vf39/j4+Pn5+fr6+vv7+/z8/P39/f7+/v///2Oyy/cAAAACdFJOU/8A5bcwSgAAADxJREFUeNq8zzkOACAMA8Hd/3+agiuRcIsrRopIjArOoLK1QAMNNBCRPkhLyzkn35Bjfd7JR1Nr09NoDACnvgDl1zlzoQAAAABJRU5ErkJggg==');\n\tbackground-repeat: no-repeat;\n\tbackground-position: 2px 5px;\n\tmargin-bottom: 1px;\n\tpadding: 3px 3px 3px 17px;\n\tcursor: pointer;\n}\n\n.shown > .uiSidebarSection-head {\n\tbackground-position: 2px -13px;\n}\n\n.uiSidebarSection-body {\n\tmargin-bottom: 3px;\n\tdisplay: none;\n}\n\n.uiSidebarSection-help {\n\ttext-shadow: #228 1px 1px 2px;\n\tcolor: blue;\n\tcursor: pointer;\n}\n\n.uiSidebarSection-help:hover {\n\ttext-decoration: underline;\n}\n"
  },
  {
    "path": "src/app/ui/sidebarSection/sidebarSection.js",
    "content": "(function( $, app, i18n ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.SidebarSection = ui.AbstractWidget.extend({\n\t\tdefaults: {\n\t\t\ttitle: \"\",\n\t\t\thelp: null,\n\t\t\tbody: null,\n\t\t\topen: false\n\t\t},\n\t\tinit: function() {\n\t\t\tthis._super();\n\t\t\tthis.el = $.joey( this._main_template() );\n\t\t\tthis.body = this.el.children(\".uiSidebarSection-body\");\n\t\t\tthis.config.open && ( this.el.addClass(\"shown\") && this.body.css(\"display\", \"block\") );\n\t\t},\n\t\t_showSection_handler: function( ev ) {\n\t\t\tvar shown = $( ev.target ).closest(\".uiSidebarSection\")\n\t\t\t\t.toggleClass(\"shown\")\n\t\t\t\t\t.children(\".uiSidebarSection-body\").slideToggle(200, function() { this.fire(\"animComplete\", this); }.bind(this))\n\t\t\t\t.end()\n\t\t\t\t.hasClass(\"shown\");\n\t\t\tthis.fire(shown ? \"show\" : \"hide\", this);\n\t\t},\n\t\t_showHelp_handler: function( ev ) {\n\t\t\tnew ui.HelpPanel({ref: this.config.help});\n\t\t\tev.stopPropagation();\n\t\t},\n\t\t_main_template: function() { return (\n\t\t\t{ tag: \"DIV\", cls: \"uiSidebarSection\", children: [\n\t\t\t\t(this.config.title && { tag: \"DIV\", cls: \"uiSidebarSection-head\", onclick: this._showSection_handler, children: [\n\t\t\t\t\tthis.config.title,\n\t\t\t\t\t( this.config.help && { tag: \"SPAN\", cls: \"uiSidebarSection-help pull-right\", onclick: this._showHelp_handler, text: i18n.text(\"General.HelpGlyph\") } )\n\t\t\t\t] }),\n\t\t\t\t{ tag: \"DIV\", cls: \"uiSidebarSection-body\", children: [ this.config.body ] }\n\t\t\t] }\n\t\t); }\n\t});\n\n})( this.jQuery, this.app, this.i18n );\n"
  },
  {
    "path": "src/app/ui/splitButton/splitButton.css",
    "content": ".uiSplitButton {\n\twhite-space: nowrap;\n}\n\n.uiSplitButton .uiButton:first-child {\n\tmargin-right: 0;\n\tdisplay: inline-block;\n}\n\n.uiSplitButton .uiButton:first-child .uiButton-content {\n\tborder-right-width: 1;\n\tborder-right-color: #5296c7;\n\tborder-top-right-radius: 0;\n\tborder-bottom-right-radius: 0;\n}\n\n.uiSplitButton .uiMenuButton {\n\tmargin-left: 0;\n}\n\n.uiSplitButton .uiButton:last-child .uiButton-content {\n\tborder-radius: 2px;\n\tborder-left-width: 1;\n\tborder-left-color: #96c6eb;\n\tborder-top-left-radius: 0;\n\tborder-bottom-left-radius: 0;\n\theight: 20px;\n}\n\n.uiSplitButton .uiButton:last-child .uiButton-label {\n\tpadding: 2px 17px 2px 6px;\n\tmargin-left: -8px;\n}\n"
  },
  {
    "path": "src/app/ui/splitButton/splitButton.js",
    "content": "(function( $, app ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.SplitButton = ui.AbstractWidget.extend({\n\t\tdefaults: {\n\t\t\titems: [],\n\t\t\tlabel: \"\"\n\t\t},\n\t\t_baseCls: \"uiSplitButton\",\n\t\tinit: function( parent ) {\n\t\t\tthis._super( parent );\n\t\t\tthis.value = null;\n\t\t\tthis.button = new ui.Button({\n\t\t\t\tlabel: this.config.label,\n\t\t\t\tonclick: this._click_handler\n\t\t\t});\n\t\t\tthis.menu = new ui.SelectMenuPanel({\n\t\t\t\tvalue: this.config.value,\n\t\t\t\titems: this._getItems(),\n\t\t\t\tonSelect: this._select_handler\n\t\t\t});\n\t\t\tthis.menuButton = new ui.MenuButton({\n\t\t\t\tlabel: \"\\u00a0\",\n\t\t\t\tmenu: this.menu\n\t\t\t});\n\t\t\tthis.el = $.joey(this._main_template());\n\t\t},\n\t\tremove: function() {\n\t\t\tthis.menu.remove();\n\t\t},\n\t\tdisable: function() {\n\t\t\tthis.button.disable();\n\t\t},\n\t\tenable: function() {\n\t\t\tthis.button.enable();\n\t\t},\n\t\t_click_handler: function() {\n\t\t\tthis.fire(\"click\", this, { value: this.value } );\n\t\t},\n\t\t_select_handler: function( panel, event ) {\n\t\t\tthis.fire( \"select\", this, event );\n\t\t},\n\t\t_getItems: function() {\n\t\t\treturn this.config.items;\n\t\t},\n\t\t_main_template: function() {\n\t\t\treturn { tag: \"DIV\", cls: this._baseCls, children: [\n\t\t\t\tthis.button, this.menuButton\n\t\t\t] };\n\t\t}\n\t});\n\n})( this.jQuery, this.app );\n"
  },
  {
    "path": "src/app/ui/splitButton/splitButtonDemo.js",
    "content": "$( function() {\n\n\tvar ui = window.app.ns(\"ui\");\n\n\twindow.builder = function() {\n\t\treturn new ui.SplitButton({\n\t\t\tlabel: \"Default\",\n\t\t\titems: [\n\t\t\t\t{ label: \"Action\" },\n\t\t\t\t{ label: \"Another Action\" },\n\t\t\t\t{ label: \"Selected\", selected: true }\n\t\t\t]\n\t\t});\n\t};\n\n});"
  },
  {
    "path": "src/app/ui/structuredQuery/structuredQuery.css",
    "content": ".uiStructuredQuery {\n\tpadding: 10px;\n}\n\n.uiStructuredQuery-out {\n\tmin-height: 30px;\n}\n"
  },
  {
    "path": "src/app/ui/structuredQuery/structuredQuery.js",
    "content": "(function( $, app, i18n ) {\n\n\tvar ui = app.ns(\"ui\");\n\tvar data = app.ns(\"data\");\n\n\tvar StructuredQuery = ui.AbstractWidget.extend({\n\t\tdefaults: {\n\t\t\tcluster: null  // (required) instanceof app.services.Cluster\n\t\t},\n\t\t_baseCls: \"uiStructuredQuery\",\n\t\tinit: function(parent) {\n\t\t\tthis._super();\n\t\t\tthis.selector = new ui.IndexSelector({\n\t\t\t\tonIndexChanged: this._indexChanged_handler,\n\t\t\t\tcluster: this.config.cluster\n\t\t\t});\n\t\t\tthis.el = $(this._main_template());\n\t\t\tthis.out = this.el.find(\"DIV.uiStructuredQuery-out\");\n\t\t\tthis.attach( parent );\n\t\t},\n\t\t\n\t\t_indexChanged_handler: function( index ) {\n\t\t\tthis.filter && this.filter.remove();\n\t\t\tthis.filter = new ui.FilterBrowser({\n\t\t\t\tcluster: this.config.cluster,\n\t\t\t\tindex: index,\n\t\t\t\tonStartingSearch: function() { this.el.find(\"DIV.uiStructuredQuery-out\").text( i18n.text(\"General.Searching\") ); this.el.find(\"DIV.uiStructuredQuery-src\").hide(); }.bind(this),\n\t\t\t\tonSearchSource: this._searchSource_handler,\n\t\t\t\tonResults: this._results_handler\n\t\t\t});\n\t\t\tthis.el.find(\".uiStructuredQuery-body\").append(this.filter);\n\t\t},\n\t\t\n\t\t_results_handler: function( filter, event ) {\n\t\t\tvar typeMap = {\n\t\t\t\t\"json\": this._jsonResults_handler,\n\t\t\t\t\"table\": this._tableResults_handler,\n\t\t\t\t\"csv\": this._csvResults_handler\n\t\t\t};\n\t\t\ttypeMap[ event.type ].call( this, event.data, event.metadata );\n\t\t},\n\t\t_jsonResults_handler: function( results ) {\n\t\t\tthis.el.find(\"DIV.uiStructuredQuery-out\").empty().append( new ui.JsonPretty({ obj: results }));\n\t\t},\n\t\t_csvResults_handler: function( results ) {\n\t\t\tthis.el.find(\"DIV.uiStructuredQuery-out\").empty().append( new ui.CSVTable({ results: results }));\n\t\t},\n\t\t_tableResults_handler: function( results, metadata ) {\n\t\t\t// hack up a QueryDataSourceInterface so that StructuredQuery keeps working without using a Query object\n\t\t\tvar qdi = new data.QueryDataSourceInterface({ metadata: metadata, query: new data.Query() });\n\t\t\tvar tab = new ui.Table( {\n\t\t\t\tstore: qdi,\n\t\t\t\theight: 400,\n\t\t\t\twidth: this.out.innerWidth()\n\t\t\t} ).attach(this.out.empty());\n\t\t\tqdi._results_handler(qdi.config.query, results);\n\t\t},\n\t\t\n\t\t_showRawJSON : function() {\n\t\t\tif($(\"#rawJsonText\").length === 0) {\n\t\t\t\tvar hiddenButton = $(\"#showRawJSON\");\n\t\t\t\tvar jsonText = $({tag: \"P\", type: \"p\", id: \"rawJsonText\"});\n\t\t\t\tjsonText.text(hiddenButton[0].value);\n\t\t\t\thiddenButton.parent().append(jsonText);\n\t\t\t}\n\t\t},\n\t\t\n\t\t_searchSource_handler: function(src) {\n\t\t\tvar searchSourceDiv = this.el.find(\"DIV.uiStructuredQuery-src\");\n\t\t\tsearchSourceDiv.empty().append(new app.ui.JsonPretty({ obj: src }));\n\t\t\tif(typeof JSON !== \"undefined\") {\n\t\t\t\tvar showRawJSON = $({ tag: \"BUTTON\", type: \"button\", text: i18n.text(\"StructuredQuery.ShowRawJson\"), id: \"showRawJSON\", value: JSON.stringify(src), onclick: this._showRawJSON });\n\t\t\t\tsearchSourceDiv.append(showRawJSON);\n\t\t\t}\n\t\t\tsearchSourceDiv.show();\n\t\t},\n\t\t\n\t\t_main_template: function() {\n\t\t\treturn { tag: \"DIV\", cls: this._baseCls, children: [\n\t\t\t\tthis.selector,\n\t\t\t\t{ tag: \"DIV\", cls: \"uiStructuredQuery-body\" },\n\t\t\t\t{ tag: \"DIV\", cls: \"uiStructuredQuery-src\", css: { display: \"none\" } },\n\t\t\t\t{ tag: \"DIV\", cls: \"uiStructuredQuery-out\" }\n\t\t\t]};\n\t\t}\n\t});\n\n\tui.StructuredQuery = ui.Page.extend({\n\t\tinit: function() {\n\t\t\tthis.q = new StructuredQuery( this.config );\n\t\t\tthis.el = this.q.el;\n\t\t}\n\t});\n\n})( this.jQuery, this.app, this.i18n );\n"
  },
  {
    "path": "src/app/ui/table/table.css",
    "content": ".uiTable TABLE {\n\tborder-collapse: collapse;\n}\n\n.uiTable-body {\n\toverflow-y: scroll;\n\toverflow-x: auto;\n}\n\n.uiTable-headers {\n\toverflow-x: hidden;\n}\n\n.uiTable-body TD {\n\twhite-space: nowrap;\n}\n\n.uiTable-body .uiTable-header-row TH,\n.uiTable-body .uiTable-header-row TH DIV {\n\tpadding-top: 0;\n\tpadding-bottom: 0;\n}\n\n.uiTable-body .uiTable-header-cell > DIV {\n\theight: 0;\n\toverflow: hidden;\n}\n\n.uiTable-headercell-menu {\n\tfloat: right;\n}\n\n.uiTable-tools {\n\tpadding: 3px 4px;\n\theight: 14px;\n}\n\n.uiTable-header-row {\n\tbackground: #ddd;\n\tbackground: -moz-linear-gradient(top, #eee, #ccc);\n\tbackground: -webkit-linear-gradient(top, #eee, #ccc);\n}\n\n.uiTable-headercell-text {\n\tmargin-right: 20px;\n}\n\n.uiTable-headercell-menu {\n\tdisplay: none;\n}\n\n.uiTable-header-row TH {\n\tborder-right: 1px solid #bbb;\n\tpadding: 0;\n\ttext-align: left;\n}\n\n.uiTable-header-row TH > DIV {\n\tpadding: 3px 4px;\n\tborder-right: 1px solid #eee;\n}\n\n.uiTable-headerEndCap > DIV {\n\twidth: 19px;\n}\n\n.uiTable-header-row .uiTable-sort {\n\tbackground: #ccc;\n\tbackground: -moz-linear-gradient(top, #bebebe, #ccc);\n\tbackground: -webkit-linear-gradient(top, #bebebe, #ccc);\n}\n.uiTable-header-row TH.uiTable-sort > DIV {\n\tborder-right: 1px solid #ccc;\n}\n\n.uiTable-sort .uiTable-headercell-menu {\n\tdisplay: block;\n}\n\n.uiTable TABLE TD {\n\tborder-right: 1px solid transparent;\n\tpadding: 3px 4px;\n}\n\n.uiTable-body TABLE TR:nth-child(even) {\n\tbackground: #f3f3f3;\n}\n\n.uiTable-body TABLE TR.selected {\n\tcolor: white;\n\tbackground: #6060f1;\n}\n"
  },
  {
    "path": "src/app/ui/table/table.js",
    "content": "( function( $, app ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.Table = ui.AbstractWidget.extend({\n\t\tdefaults: {\n\t\t\tstore: null, // (required) implements interface app.data.DataSourceInterface\n\t\t\theight: 0,\n\t\t\twidth: 0\n\t\t},\n\t\t_baseCls: \"uiTable\",\n\t\tinit: function(parent) {\n\t\t\tthis._super();\n\t\t\tthis.initElements(parent);\n\t\t\tthis.config.store.on(\"data\", this._data_handler);\n\t\t},\n\t\tattach: function(parent) {\n\t\t\tif(parent) {\n\t\t\t\tthis._super(parent);\n\t\t\t\tthis._reflow();\n\t\t\t}\n\t\t},\n\t\tinitElements: function(parent) {\n\t\t\tthis.el = $.joey(this._main_template());\n\t\t\tthis.body = this.el.find(\".uiTable-body\");\n\t\t\tthis.headers = this.el.find(\".uiTable-headers\");\n\t\t\tthis.tools = this.el.find(\".uiTable-tools\");\n\t\t\tthis.attach( parent );\n\t\t},\n\t\t_data_handler: function(store) {\n\t\t\tthis.tools.text(store.summary);\n\t\t\tthis.headers.empty().append(this._header_template(store.columns));\n\t\t\tthis.body.empty().append(this._body_template(store.data, store.columns));\n\t\t\tthis._reflow();\n\t\t},\n\t\t_reflow: function() {\n\t\t\tvar firstCol = this.body.find(\"TR:first TH.uiTable-header-cell > DIV\"),\n\t\t\t\t\theaders = this.headers.find(\"TR:first TH.uiTable-header-cell > DIV\");\n\t\t\tfor(var i = 0; i < headers.length; i++) {\n\t\t\t\t$(headers[i]).width( $(firstCol[i]).width() );\n\t\t\t}\n\t\t\tthis._scroll_handler();\n\t\t},\n\t\t_scroll_handler: function(ev) {\n\t\t\tthis.el.find(\".uiTable-headers\").scrollLeft(this.body.scrollLeft());\n\t\t},\n\t\t_dataClick_handler: function(ev) {\n\t\t\tvar row = $(ev.target).closest(\"TR\");\n\t\t\tif(row.length) {\n\t\t\t\tthis.fire(\"rowClick\", this, { row: row } );\n\t\t\t}\n\t\t},\n\t\t_headerClick_handler: function(ev) {\n\t\t\tvar header = $(ev.target).closest(\"TH.uiTable-header-cell\");\n\t\t\tif(header.length) {\n\t\t\t\tthis.fire(\"headerClick\", this, { header: header, column: header.data(\"column\"), dir: header.data(\"dir\") });\n\t\t\t}\n\t\t},\n\t\t_main_template: function() {\n\t\t\treturn { tag: \"DIV\", id: this.id(), css: { width: this.config.width + \"px\" }, cls: this._baseCls, children: [\n\t\t\t\t{ tag: \"DIV\", cls: \"uiTable-tools\" },\n\t\t\t\t{ tag: \"DIV\", cls: \"uiTable-headers\", onclick: this._headerClick_handler },\n\t\t\t\t{ tag: \"DIV\", cls: \"uiTable-body\",\n\t\t\t\t\tonclick: this._dataClick_handler,\n\t\t\t\t\tonscroll: this._scroll_handler,\n\t\t\t\t\tcss: { height: this.config.height + \"px\", width: this.config.width + \"px\" }\n\t\t\t\t}\n\t\t\t] };\n\t\t},\n\t\t_header_template: function(columns) {\n\t\t\tvar ret = { tag: \"TABLE\", children: [ this._headerRow_template(columns) ] };\n\t\t\tret.children[0].children.push(this._headerEndCap_template());\n\t\t\treturn ret;\n\t\t},\n\t\t_headerRow_template: function(columns) {\n\t\t\treturn { tag: \"TR\", cls: \"uiTable-header-row\", children: columns.map(function(column) {\n\t\t\t\tvar dir = ((this.config.store.sort.column === column) && this.config.store.sort.dir) || \"none\";\n\t\t\t\treturn { tag: \"TH\", data: { column: column, dir: dir }, cls: \"uiTable-header-cell\" + ((dir !== \"none\") ? \" uiTable-sort\" : \"\"), children: [\n\t\t\t\t\t{ tag: \"DIV\", children: [\n\t\t\t\t\t\t{ tag: \"DIV\", cls: \"uiTable-headercell-menu\", text: dir === \"asc\" ? \"\\u25b2\" : \"\\u25bc\" },\n\t\t\t\t\t\t{ tag: \"DIV\", cls: \"uiTable-headercell-text\", text: column }\n\t\t\t\t\t]}\n\t\t\t\t]};\n\t\t\t}, this)};\n\t\t},\n\t\t_headerEndCap_template: function() {\n\t\t\treturn { tag: \"TH\", cls: \"uiTable-headerEndCap\", children: [ { tag: \"DIV\" } ] };\n\t\t},\n\t\t_body_template: function(data, columns) {\n\t\t\treturn { tag: \"TABLE\", children: []\n\t\t\t\t.concat(this._headerRow_template(columns))\n\t\t\t\t.concat(data.map(function(row) {\n\t\t\t\t\treturn { tag: \"TR\", data: { row: row }, cls: \"uiTable-row\", children: columns.map(function(column){\n\t\t\t\t\t\treturn { tag: \"TD\", cls: \"uiTable-cell\", children: [ { tag: \"DIV\", text: (row[column] || \"\").toString() } ] };\n\t\t\t\t\t})};\n\t\t\t\t}))\n\t\t\t};\n\t\t}\n\n\t});\n\n})( this.jQuery, this.app );\n"
  },
  {
    "path": "src/app/ui/textField/textField.js",
    "content": "(function( app ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.TextField = ui.AbstractField.extend({\n\t\tinit: function() {\n\t\t\tthis._super();\n\t\t},\n\t\t_keyup_handler: function() {\n\t\t\tthis.fire(\"change\", this );\n\t\t},\n\t\t_main_template: function() {\n\t\t\treturn { tag: \"DIV\", id: this.id(), cls: \"uiField uiTextField\", children: [\n\t\t\t\t{ tag: \"INPUT\",\n\t\t\t\t\ttype: \"text\",\n\t\t\t\t\tname: this.config.name,\n\t\t\t\t\tplaceholder: this.config.placeholder,\n\t\t\t\t\tonkeyup: this._keyup_handler\n\t\t\t\t}\n\t\t\t]};\n\t\t}\n\t});\n\n})( this.app );\n"
  },
  {
    "path": "src/app/ui/textField/textFieldDemo.js",
    "content": "$( function() {\n\n\tvar ui = window.app.ns(\"ui\");\n\n\twindow.builder = function() { return (\n\t\t{ tag: \"DIV\", children: [\n\t\t\tnew ui.TextField({}),\n\t\t\tnew ui.TextField({ placeholder: \"placeholder\" }),\n\t\t\tnew ui.TextField({ onchange: function( tf ) { console.log( tf.val() ); } })\n\t\t] }\n\t); };\n\n});"
  },
  {
    "path": "src/app/ui/toolbar/toolbar.css",
    "content": ".uiToolbar {\n\theight: 28px;\n\tbackground: #fdfefe;\n\tbackground: -moz-linear-gradient(top, #fdfefe, #eaedef);\n\tbackground: -webkit-linear-gradient(top, #fdfefe, #eaedef);\n\tborder-bottom: 1px solid #d2d5d7;\n\tpadding: 3px 10px;\n}\n\n.uiToolbar H2 {\n\tdisplay: inline-block;\n\tfont-size: 120%;\n\tmargin: 0;\n\tpadding: 5px 20px 5px 0;\n}\n\n.uiToolbar .uiTextField {\n\tdisplay: inline-block;\n}\n\n.uiToolbar .uiTextField INPUT {\n\tpadding-top: 2px;\n\tpadding-bottom: 5px;\n}"
  },
  {
    "path": "src/app/ui/toolbar/toolbar.js",
    "content": "(function( $, app ) {\n\n\tvar ui = app.ns(\"ui\");\n\n\tui.Toolbar = ui.AbstractWidget.extend({\n\t\tdefaults: {\n\t\t\tlabel: \"\",\n\t\t\tleft: [],\n\t\t\tright: []\n\t\t},\n\t\tinit: function(parent) {\n\t\t\tthis._super();\n\t\t\tthis.el = $.joey(this._main_template());\n\t\t},\n\t\t_main_template: function() {\n\t\t\treturn { tag: \"DIV\", cls: \"uiToolbar\", children: [\n\t\t\t\t{ tag: \"DIV\", cls: \"pull-left\", children: [\n\t\t\t\t\t{ tag: \"H2\", text: this.config.label }\n\t\t\t\t].concat(this.config.left) },\n\t\t\t\t{ tag: \"DIV\", cls: \"pull-right\", children: this.config.right }\n\t\t\t]};\n\t\t}\n\t});\n\n})( this.jQuery, this.app );\n"
  },
  {
    "path": "src/app/ux/class.js",
    "content": "/**\n * base class for creating inheritable classes\n * based on resigs 'Simple Javascript Inheritance Class' (based on base2 and prototypejs)\n * modified with static super and auto config\n * @name Class\n * @constructor\n */\n(function( $, app ){\n\n\tvar ux = app.ns(\"ux\");\n\n\tvar initializing = false, fnTest = /\\b_super\\b/;\n\n\tux.Class = function(){};\n\n\tux.Class.extend = function(prop) {\n\t\tfunction Class() {\n\t\t\tif(!initializing) {\n\t\t\t\tvar args = Array.prototype.slice.call(arguments);\n\t\t\t\tthis.config = $.extend( function(t) { // automatically construct a config object based on defaults and last item passed into the constructor\n\t\t\t\t\treturn $.extend(t._proto && t._proto() && arguments.callee(t._proto()) || {}, t.defaults);\n\t\t\t\t} (this) , args.pop() );\n\t\t\t\tthis.init && this.init.apply(this, args); // automatically run the init function when class created\n\t\t\t}\n\t\t}\n\n\t\tinitializing = true;\n\t\tvar prototype = new this();\n\t\tinitializing = false;\n\t\t\n\t\tvar _super = this.prototype;\n\t\tprototype._proto = function() {\n\t\t\treturn _super;\n\t\t};\n\n\t\tfor(var name in prop) {\n\t\t\tprototype[name] = typeof prop[name] === \"function\" && typeof _super[name] === \"function\" && fnTest.test(prop[name]) ?\n\t\t\t\t(function(name, fn){\n\t\t\t\t\treturn function() { this._super = _super[name]; return fn.apply(this, arguments); };\n\t\t\t\t})(name, prop[name]) : prop[name];\n\t\t}\n\n\t\tClass.prototype = prototype;\n\t\tClass.constructor = Class;\n\n\t\tClass.extend = arguments.callee; // make class extendable\n\n\t\treturn Class;\n\t};\n})( this.jQuery, this.app );\n"
  },
  {
    "path": "src/app/ux/dragdrop.js",
    "content": "(function( $, app ) {\n\n\tvar ux = app.ns(\"ux\");\n\n\t/**\n\t * Provides drag and drop functionality<br>\n\t * a DragDrop instance is created for each usage pattern and then used over and over again<br>\n\t * first a dragObj is defined - this is the jquery node that will be dragged around<br>\n\t * second, the event callbacks are defined - these allow you control the ui during dragging and run functions when successfully dropping<br>\n\t * thirdly drop targets are defined - this is a list of DOM nodes, the constructor works in one of two modes:\n\t * <li>without targets - objects can be picked up and dragged around, dragStart and dragStop events fire</li>\n\t * <li>with targets - as objects are dragged over targets dragOver, dragOut and DragDrop events fire\n\t * to start dragging call the DragDrop.pickup_handler() function, dragging stops when the mouse is released.\n\t * @constructor\n\t * The following options are supported\n\t * <dt>targetSelector</dt>\n\t *   <dd>an argument passed directly to jquery to create a list of targets, as such it can be a CSS style selector, or an array of DOM nodes<br>if target selector is null the DragDrop does Drag only and will not fire dragOver dragOut and dragDrop events</dd>\n\t * <dt>pickupSelector</dt>\n\t *   <dd>a jquery selector. The pickup_handler is automatically bound to matched elements (eg clicking on these elements starts the drag). if pickupSelector is null, the pickup_handler must be manually bound <code>$(el).bind(\"mousedown\", dragdrop.pickup_handler)</code></dd>\n\t * <dt>dragObj</dt>\n\t *   <dd>the jQuery element to drag around when pickup is called. If not defined, dragObj must be set in onDragStart</dd>\n\t * <dt>draggingClass</dt>\n\t *   <dd>the class(es) added to items when they are being dragged</dd>\n\t * The following observables are supported\n\t * <dt>dragStart</dt>\n\t *   <dd>a callback when start to drag<br><code>function(jEv)</code></dd>\n\t * <dt>dragOver</dt>\n\t *   <dd>a callback when we drag into a target<br><code>function(jEl)</code></dd>\n\t * <dt>dragOut</dt>\n\t *   <dd>a callback when we drag out of a target, or when we drop over a target<br><code>function(jEl)</code></dd>\n\t * <dt>dragDrop</dt>\n\t *   <dd>a callback when we drop on a target<br><code>function(jEl)</code></dd>\n\t * <dt>dragStop</dt>\n\t *   <dd>a callback when we stop dragging<br><code>function(jEv)</code></dd>\n\t */\n\tux.DragDrop = ux.Observable.extend({\n\t\tdefaults : {\n\t\t\ttargetsSelector : null,\n\t\t\tpickupSelector:   null,\n\t\t\tdragObj :         null,\n\t\t\tdraggingClass :   \"dragging\"\n\t\t},\n\n\t\tinit: function(options) {\n\t\t\tthis._super(); // call the class initialiser\n\t\t\n\t\t\tthis.drag_handler = this.drag.bind(this);\n\t\t\tthis.drop_handler = this.drop.bind(this);\n\t\t\tthis.pickup_handler = this.pickup.bind(this);\n\t\t\tthis.targets = [];\n\t\t\tthis.dragObj = null;\n\t\t\tthis.dragObjOffset = null;\n\t\t\tthis.currentTarget = null;\n\t\t\tif(this.config.pickupSelector) {\n\t\t\t\t$(this.config.pickupSelector).bind(\"mousedown\", this.pickup_handler);\n\t\t\t}\n\t\t},\n\n\t\tdrag : function(jEv) {\n\t\t\tjEv.preventDefault();\n\t\t\tvar mloc = acx.vector( this.lockX || jEv.pageX, this.lockY || jEv.pageY );\n\t\t\tthis.dragObj.css(mloc.add(this.dragObjOffset).asOffset());\n\t\t\tif(this.targets.length === 0) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif(this.currentTarget !== null && mloc.within(this.currentTarget[1], this.currentTarget[2])) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif(this.currentTarget !== null) {\n\t\t\t\tthis.fire('dragOut', this.currentTarget[0]);\n\t\t\t\tthis.currentTarget = null;\n\t\t\t}\n\t\t\tfor(var i = 0; i < this.targets.length; i++) {\n\t\t\t\tif(mloc.within(this.targets[i][1], this.targets[i][2])) {\n\t\t\t\t\tthis.currentTarget = this.targets[i];\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(this.currentTarget !== null) {\n\t\t\t\tthis.fire('dragOver', this.currentTarget[0]);\n\t\t\t}\n\t\t},\n\t\t\n\t\tdrop : function(jEv) {\n\t\t\t$(document).unbind(\"mousemove\", this.drag_handler);\n\t\t\t$(document).unbind(\"mouseup\", this.drop_handler);\n\t\t\tthis.dragObj.removeClass(this.config.draggingClass);\n\t\t\tif(this.currentTarget !== null) {\n\t\t\t\tthis.fire('dragOut', this.currentTarget[0]);\n\t\t\t\tthis.fire('dragDrop', this.currentTarget[0]);\n\t\t\t}\n\t\t\tthis.fire('dragStop', jEv);\n\t\t\tthis.dragObj = null;\n\t\t},\n\t\t\n\t\tpickup : function(jEv, opts) {\n\t\t\t$.extend(this.config, opts);\n\t\t\tthis.fire('dragStart', jEv);\n\t\t\tthis.dragObj = this.dragObj || this.config.dragObj;\n\t\t\tthis.dragObjOffset = this.config.dragObjOffset || acx.vector(this.dragObj.offset()).sub(jEv.pageX, jEv.pageY);\n\t\t\tthis.lockX = this.config.lockX ? jEv.pageX : 0;\n\t\t\tthis.lockY = this.config.lockY ? jEv.pageY : 0;\n\t\t\tthis.dragObj.addClass(this.config.draggingClass);\n\t\t\tif(!this.dragObj.get(0).parentNode || this.dragObj.get(0).parentNode.nodeType === 11) { // 11 = document fragment\n\t\t\t\t$(document.body).append(this.dragObj);\n\t\t\t}\n\t\t\tif(this.config.targetsSelector) {\n\t\t\t\tthis.currentTarget = null;\n\t\t\t\tvar targets = ( this.targets = [] );\n\t\t\t\t// create an array of elements optimised for rapid collision detection calculation\n\t\t\t\t$(this.config.targetsSelector).each(function(i, el) {\n\t\t\t\t\tvar jEl = $(el);\n\t\t\t\t\tvar tl = acx.vector(jEl.offset());\n\t\t\t\t\tvar br = tl.add(jEl.width(), jEl.height());\n\t\t\t\t\ttargets.push([jEl, tl, br]);\n\t\t\t\t});\n\t\t\t}\n\t\t\t$(document).bind(\"mousemove\", this.drag_handler);\n\t\t\t$(document).bind(\"mouseup\", this.drop_handler);\n\t\t\tthis.drag_handler(jEv);\n\t\t}\n\t});\n\n})( this.jQuery, this.app );\n"
  },
  {
    "path": "src/app/ux/fieldCollection.js",
    "content": "(function( app ) {\n\n\tvar ux = app.ns(\"ux\");\n\n\tux.FieldCollection = ux.Observable.extend({\n\t\tdefaults: {\n\t\t\tfields: []\t// the collection of fields\n\t\t},\n\t\tinit: function() {\n\t\t\tthis._super();\n\t\t\tthis.fields = this.config.fields;\n\t\t},\n\t\tvalidate: function() {\n\t\t\treturn this.fields.reduce(function(r, field) {\n\t\t\t\treturn r && field.validate();\n\t\t\t}, true);\n\t\t},\n\t\tgetData: function(type) {\n\t\t\treturn this.fields.reduce(function(r, field) {\n\t\t\t\tr[field.name] = field.val(); return r;\n\t\t\t}, {});\n\t\t}\n\t});\n\n})( this.app );\n"
  },
  {
    "path": "src/app/ux/observable.js",
    "content": "(function( app ) {\n\n\tvar ux = app.ns(\"ux\");\n\n\tux.Observable = ux.Class.extend((function() {\n\t\treturn {\n\t\t\tinit: function() {\n\t\t\t\tthis.observers = {};\n\t\t\t\tfor( var opt in this.config ) { // automatically install observers that are defined in the configuration\n\t\t\t\t\tif( opt.indexOf( 'on' ) === 0 ) {\n\t\t\t\t\t\tthis.on( opt.substring(2) , this.config[ opt ] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\t_getObs: function( type ) {\n\t\t\t\treturn ( this.observers[ type.toLowerCase() ] || ( this.observers[ type.toLowerCase() ] = [] ) );\n\t\t\t},\n\t\t\ton: function( type, fn, params, thisp ) {\n\t\t\t\tthis._getObs( type ).push( { \"cb\" : fn, \"args\" : params || [] , \"cx\" : thisp || this } );\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tfire: function( type ) {\n\t\t\t\tvar params = Array.prototype.slice.call( arguments, 1 );\n\t\t\t\tthis._getObs( type ).slice().forEach( function( ob ) {\n\t\t\t\t\tob[\"cb\"].apply( ob[\"cx\"], ob[\"args\"].concat( params ) );\n\t\t\t\t} );\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tremoveAllObservers: function() {\n\t\t\t\tthis.observers = {};\n\t\t\t},\n\t\t\tremoveObserver: function( type, fn ) {\n\t\t\t\tvar obs = this._getObs( type ),\n\t\t\t\t\tindex = obs.reduce( function(p, t, i) { return (t.cb === fn) ? i : p; }, -1 );\n\t\t\t\tif(index !== -1) {\n\t\t\t\t\tobs.splice( index, 1 );\n\t\t\t\t}\n\t\t\t\treturn this; // make observable functions chainable\n\t\t\t},\n\t\t\thasObserver: function( type ) {\n\t\t\t\treturn !! this._getObs( type ).length;\n\t\t\t}\n\t\t};\n\t})());\n\n})( this.app );"
  },
  {
    "path": "src/app/ux/singleton.js",
    "content": "(function( app ) {\n\n\tvar ux = app.ns(\"ux\");\n\n\tvar extend = ux.Observable.extend;\n\tvar instance = function() {\n\t\tif( ! (\"me\" in this) ) {\n\t\t\tthis.me = new this();\n\t\t}\n\t\treturn this.me;\n\t};\n\n\tux.Singleton = ux.Observable.extend({});\n\n\tux.Singleton.extend = function() {\n\t\tvar Self = extend.apply( this, arguments );\n\t\tSelf.instance = instance;\n\t\treturn Self;\n\t};\n\n})( this.app );\n"
  },
  {
    "path": "src/app/ux/singletonSpec.js",
    "content": "describe(\"app.ux.singleton\", function(){\n\nvar Singleton = window.app.ux.Singleton;\n\n\tdescribe(\"creating a singleton\", function() {\n\t\tvar X = Singleton.extend({\n\t\t\tfoo: function() {\n\t\t\t\treturn \"bar\";\n\t\t\t}\n\t\t});\n\n\t\tvar Y = Singleton.extend({\n\t\t\tbar: function() {\n\t\t\t\treturn \"baz\";\n\t\t\t}\n\t\t});\n\n\t\tit(\"should have properties like a normal class\", function() {\n\t\t\tvar a = X.instance();\n\n\t\t\texpect( a instanceof X ).toBe( true );\n\t\t\texpect( a.foo() ).toBe( \"bar\" );\n\t\t});\n\n\t\tit(\"should return single instance each time instance() is called\", function() {\n\t\t\tvar a = X.instance();\n\t\t\tvar b = X.instance();\n\n\t\t\texpect( a ).toBe( b );\n\t\t});\n\n\t\tit(\"should not share instances with different singletons\", function() {\n\t\t\tvar a = X.instance();\n\t\t\tvar c = Y.instance();\n\n\t\t\texpect( a ).not.toBe( c );\n\t\t});\n\n\t});\n\n});\n"
  },
  {
    "path": "src/app/ux/table.css",
    "content": "TABLE.table {\n\tborder-collapse: collapse;\n}\n\n\nTABLE.table TH {\n\tfont-weight: normal;\n\ttext-align: left;\n\tvertical-align: middle;\n}\n\nTABLE.table TBODY.striped TR:nth-child(odd) {\n\tbackground: #eee;\n}\n\nTABLE.table H3 {\n\tmargin: 0;\n\tfont-weight: bold;\n\tfont-size: 140%;\n}\n"
  },
  {
    "path": "src/app/ux/templates/templateSpec.js",
    "content": "describe(\"app.ut.byteSize_template\", function() {\n\n\tdescribe(\"byteSize_template()\", function() {\n\t\tvar byteSize_template = window.app.ut.byteSize_template;\n\n\t\tit(\"should postfix with a B and have not decimal for number less than 1000\", function() {\n\t\t\texpect( byteSize_template( 0 ) ).toBe( \"0B\" );\n\t\t\texpect( byteSize_template( 1 ) ).toBe( \"1B\" );\n\t\t\texpect( byteSize_template( 10 ) ).toBe( \"10B\" );\n\t\t\texpect( byteSize_template( 100 ) ).toBe( \"100B\" );\n\t\t\texpect( byteSize_template( 999 ) ).toBe( \"999B\" );\n\t\t});\n\n\t\tit(\"should have 0.xxX for values between 1000 and 1023\", function() {\n\t\t\texpect( byteSize_template( 1000  ) ).toBe( \"0.98ki\" );\n\t\t\texpect( byteSize_template( 1024 * 1000 ) ).toBe( \"0.98Mi\" );\n\t\t});\n\n\t\tit(\"should always have three significant digits\", function() {\n\t\t\texpect( byteSize_template( 1023  ) ).toBe( \"1.00ki\" );\n\t\t\texpect( byteSize_template( 1024  ) ).toBe( \"1.00ki\" );\n\t\t\texpect( byteSize_template( 1025  ) ).toBe( \"1.00ki\" );\n\t\t\texpect( byteSize_template( 1024 * 5 ) ).toBe( \"5.00ki\" );\n\t\t\texpect( byteSize_template( 1024 * 55 ) ).toBe( \"55.0ki\" );\n\t\t\texpect( byteSize_template( 1024 * 555 ) ).toBe( \"555ki\" );\n\t\t});\n\n\t\tit(\"should have the correct postfix\", function() {\n\t\t\texpect( byteSize_template( 3 * Math.pow( 1024, 1) ) ).toBe( \"3.00ki\" );\n\t\t\texpect( byteSize_template( 3 * Math.pow( 1024, 2) ) ).toBe( \"3.00Mi\" );\n\t\t\texpect( byteSize_template( 3 * Math.pow( 1024, 3) ) ).toBe( \"3.00Gi\" );\n\t\t\texpect( byteSize_template( 3 * Math.pow( 1024, 4) ) ).toBe( \"3.00Ti\" );\n\t\t\texpect( byteSize_template( 3 * Math.pow( 1024, 5) ) ).toBe( \"3.00Pi\" );\n\t\t\texpect( byteSize_template( 3 * Math.pow( 1024, 6) ) ).toBe( \"3.00Ei\" );\n\t\t\texpect( byteSize_template( 3 * Math.pow( 1024, 7) ) ).toBe( \"3.00Zi\" );\n\t\t\texpect( byteSize_template( 3 * Math.pow( 1024, 8) ) ).toBe( \"3.00Yi\" );\n\t\t});\n\n\t\tit(\"should show an overflow for stupidly big numbers\", function() {\n\t\t\texpect( byteSize_template( 3 * Math.pow( 1024, 10) ) ).toBe( \"3.00..E\" );\n\t\t});\n\t});\n\n\tdescribe(\"count_template()\", function() {\n\t\tvar count_template = window.app.ut.count_template;\n\n\t\tit(\"should not postfix and not decimal for number less than 1000\", function() {\n\t\t\texpect( count_template( 0 ) ).toBe( \"0\" );\n\t\t\texpect( count_template( 1 ) ).toBe( \"1\" );\n\t\t\texpect( count_template( 10 ) ).toBe( \"10\" );\n\t\t\texpect( count_template( 100 ) ).toBe( \"100\" );\n\t\t\texpect( count_template( 999 ) ).toBe( \"999\" );\n\t\t});\n\n\t\tit(\"should always have three significant digits\", function() {\n\t\t\texpect( count_template( 1000  ) ).toBe( \"1.00k\" );\n\t\t\texpect( count_template( 1005  ) ).toBe( \"1.00k\" );\n\t\t\texpect( count_template( 1055  ) ).toBe( \"1.05k\" );\n\t\t\texpect( count_template( 1000 * 5 ) ).toBe( \"5.00k\" );\n\t\t\texpect( count_template( 1000 * 55 ) ).toBe( \"55.0k\" );\n\t\t\texpect( count_template( 1000 * 555 ) ).toBe( \"555k\" );\n\t\t});\n\n\t\tit(\"should have the correct postfix\", function() {\n\t\t\texpect( count_template( 3 * Math.pow( 1000, 1) ) ).toBe( \"3.00k\" );\n\t\t\texpect( count_template( 3 * Math.pow( 1000, 2) ) ).toBe( \"3.00M\" );\n\t\t\texpect( count_template( 3 * Math.pow( 1000, 3) ) ).toBe( \"3.00G\" );\n\t\t\texpect( count_template( 3 * Math.pow( 1000, 4) ) ).toBe( \"3.00T\" );\n\t\t\texpect( count_template( 3 * Math.pow( 1000, 5) ) ).toBe( \"3.00P\" );\n\t\t\texpect( count_template( 3 * Math.pow( 1000, 6) ) ).toBe( \"3.00E\" );\n\t\t\texpect( count_template( 3 * Math.pow( 1000, 7) ) ).toBe( \"3.00Z\" );\n\t\t\texpect( count_template( 3 * Math.pow( 1000, 8) ) ).toBe( \"3.00Y\" );\n\t\t});\n\n\t\tit(\"should show an overflow for stupidly big numbers\", function() {\n\t\t\texpect( count_template( 3 * Math.pow( 1000, 10) ) ).toBe( \"3.00..E\" );\n\t\t});\n\t});\n\n\n});\n"
  },
  {
    "path": "src/app/ux/templates/templates.js",
    "content": "(function( app ) {\n\n\tvar ut = app.ns(\"ut\");\n\n\tut.option_template = function(v) { return { tag: \"OPTION\", value: v, text: v }; };\n\n\tut.require_template = function(f) { return f.require ? { tag: \"SPAN\", cls: \"require\", text: \"*\" } : null; };\n\n\n\tvar sib_prefix = ['B','ki','Mi', 'Gi', 'Ti', 'Pi', 'Ei', 'Zi', 'Yi'];\n\n\tut.byteSize_template = function(n) {\n\t\tvar i = 0;\n\t\twhile( n >= 1000 ) {\n\t\t\ti++;\n\t\t\tn /= 1024;\n\t\t}\n\t\treturn (i === 0 ? n.toString() : n.toFixed( 3 - parseInt(n,10).toString().length )) + ( sib_prefix[ i ] || \"..E\" );\n\t};\n\n\tvar sid_prefix = ['','k','M', 'G', 'T', 'P', 'E', 'Z', 'Y'];\n\n\tut.count_template = function(n) {\n\t\tvar i = 0;\n\t\twhile( n >= 1000 ) {\n\t\t\ti++;\n\t\t\tn /= 1000;\n\t\t}\n\t\treturn i === 0 ? n.toString() : ( n.toFixed( 3 - parseInt(n,10).toString().length ) + ( sid_prefix[ i ] || \"..E\" ) );\n\t};\n\n})( this.app );\n"
  },
  {
    "path": "src/chrome_ext/background.js",
    "content": "chrome.browserAction.onClicked.addListener(function (tab) {\n    chrome.tabs.create({'url': chrome.extension.getURL('index.html')}, function (tab) {\n    });\n});\n"
  },
  {
    "path": "src/chrome_ext/manifest.json",
    "content": "{  \n    \"manifest_version\": 2,\n    \"name\": \"elasticsearch-head\",  \n    \"version\": \"1.0.8\",\n    \"background\": { \n      \"scripts\": [\"background.js\"],\n      \"persistent\": false\n    },\n    \"icons\": {\n      \"16\": \"base/favicon.png\"\n    },\n    \"content_security_policy\": \"script-src 'self' 'sha256-Rpn+rjJuXCjZBPOPhhVloRXuzAUBRnAas+6gKVDohs0=' 'unsafe-eval'; object-src 'self';\",\n    \"description\": \"Chrome Extension containing the excellent ElasticSearch Head application.\",  \n    \"browser_action\": {  \n      \"default_icon\": \"base/favicon.png\" ,\n      \"default_title\": \"es-head\"\n    },\n    \"content_scripts\":[{\n        \"all_frames\": false,\n        \"matches\":[\"*://*/\"],\n        \"js\":[\"background.js\"],\n        \"run_at\": \"document_end\"\n    }]\n} \n"
  },
  {
    "path": "src/vendor/dateRangeParser/date-range-parser.js",
    "content": "/*!\n * date-range-parser.js\n * Contributed to the Apache Software Foundation by:\n *    Ben Birch - Aconex\n * fork me at https://github.com/mobz/date-range-parser\n\nLicensed to the Apache Software Foundation (ASF) under one\nor more contributor license agreements.  See the NOTICE file\ndistributed with this work for additional information\nregarding copyright ownership.  The ASF licenses this file\nto you under the Apache License, Version 2.0 (the\n\"License\"); you may not use this file except in compliance\nwith the License.  You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing,\nsoftware distributed under the License is distributed on an\n\"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\nKIND, either express or implied.  See the License for the\nspecific language governing permissions and limitations\nunder the License.\n\n*/\n\n(function() {\n\n\tvar drp = window.dateRangeParser = {};\n\n\tdrp.defaultRange = 1000 * 60 * 60 * 24;\n\n\tdrp.now = null; // set a different value for now than the time at function invocation\n\n\tdrp.parse = function(v) {\n\t\ttry {\n\t\t\tvar r = drp._parse(v);\n\t\t\tr.end && r.end--; // remove 1 millisecond from the final end range\n\t\t} catch(e) {\n\t\t\tr = null;\n\t\t}\n\t\treturn r;\n\t};\n\n\tdrp.print = function(t, p) {\n\t\tvar format = [\"\", \"-\", \"-\", \" \", \":\", \":\", \".\"];\n\t\tvar da = makeArray(t);\n\t\tvar str = \"\";\n\t\tfor(var i = 0; i <= p; i++) {\n\t\t\tstr += format[i] + (da[i] < 10 ? \"0\" : \"\") + da[i];\n\t\t}\n\t\treturn str;\n\t};\n\n\t(function() {\n\t\tdrp._relTokens = {};\n\n\t\tvar values = {\n\t\t\t\"yr\"  : 365*24*60*60*1000,\n\t\t\t\"mon\" : 31*24*60*60*1000,\n\t\t\t\"day\" : 24*60*60*1000,\n\t\t\t\"hr\"  : 60*60*1000,\n\t\t\t\"min\" : 60*1000,\n\t\t\t\"sec\" : 1000\n\t\t};\n\n\t\tvar alias_lu = {\n\t\t\t\"yr\" : \"y,yr,yrs,year,years\",\n\t\t\t\"mon\" : \"mo,mon,mos,mons,month,months\",\n\t\t\t\"day\" : \"d,dy,dys,day,days\",\n\t\t\t\"hr\" : \"h,hr,hrs,hour,hours\",\n\t\t\t\"min\" : \"m,min,mins,minute,minutes\",\n\t\t\t\"sec\" : \"s,sec,secs,second,seconds\"\n\t\t};\n\n\t\tfor(var key in alias_lu) {\n\t\t\tif(alias_lu.hasOwnProperty(key)) {\n\t\t\t\tvar aliases = alias_lu[key].split(\",\");\n\t\t\t\tfor(var i = 0; i < aliases.length; i++) {\n\t\t\t\t\tdrp._relTokens[aliases[i]] = values[key];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t})();\n\n\tfunction makeArray(d) {\n\t\tvar da = new Date(d);\n\t\treturn [ da.getUTCFullYear(), da.getUTCMonth()+1, da.getUTCDate(), da.getUTCHours(), da.getUTCMinutes(), da.getUTCSeconds(), da.getUTCMilliseconds() ];\n\t}\n\n\tfunction fromArray(a) {\n\t\tvar d = [].concat(a); d[1]--;\n\t\treturn Date.UTC.apply(null, d);\n\t}\n\n\tdrp._parse = function parse(v) {\n\t\tvar now = this.now || new Date().getTime();\n\n\t\tfunction precArray(d, p, offset) {\n\t\t\tvar tn = makeArray(d);\n\t\t\ttn[p] += offset || 0;\n\t\t\tfor(var i = p+1; i < 7; i++) {\n\t\t\t\ttn[i] = i < 3 ? 1 : 0;\n\t\t\t}\n\t\t\treturn tn;\n\t\t}\n\t\tfunction makePrecRange(dt, p, r) {\n\t\t\tvar ret = { };\n\t\t\tret.start = fromArray(dt);\n\t\t\tdt[p] += r || 1;\n\t\t\tret.end = fromArray(dt);\n\t\t\treturn ret;\n\t\t}\n\t\tfunction procTerm(term) {\n\t\t\tvar m = term.replace(/\\s/g, \"\").toLowerCase().match(/^([a-z ]+)$|^([ 0-9:-]+)$|^(\\d+[a-z]+)$/);\n\t\t\tif(m[1]) {\t// matches ([a-z ]+)\n\t\t\t\tfunction dra(p, o, r) {\n\t\t\t\t\tvar dt = precArray(now, p, o);\n\t\t\t\t\tif(r) {\n\t\t\t\t\t\tdt[2] -= new Date(fromArray(dt)).getUTCDay();\n\t\t\t\t\t}\n\t\t\t\t\treturn makePrecRange(dt, p, r);\n\t\t\t\t}\n\t\t\t\tswitch( m[1]) {\n\t\t\t\t\tcase \"now\" : return { start: now, end: now, now: now };\n\t\t\t\t\tcase \"today\" : return dra( 2, 0 );\n\t\t\t\t\tcase \"thisweek\" : return dra( 2, 0, 7 );\n\t\t\t\t\tcase \"thismonth\" : return dra( 1, 0 );\n\t\t\t\t\tcase \"thisyear\" : return dra( 0, 0 );\n\t\t\t\t\tcase \"yesterday\" : return dra( 2, -1 );\n\t\t\t\t\tcase \"lastweek\" : return dra( 2, -7, 7 );\n\t\t\t\t\tcase \"lastmonth\" : return dra( 1, -1 );\n\t\t\t\t\tcase \"lastyear\" : return dra( 0, -1 );\n\t\t\t\t\tcase \"tomorrow\" : return dra( 2, 1 );\n\t\t\t\t\tcase \"nextweek\" : return dra( 2, 7, 7 );\n\t\t\t\t\tcase \"nextmonth\" : return dra( 1, 1 );\n\t\t\t\t\tcase \"nextyear\" : return dra(0, 1 );\n\t\t\t\t}\n\t\t\t\tthrow \"unknown token \" +  m[1];\n\t\t\t} else if(m[2]) { // matches ([ 0-9:-]+)\n\t\t\t\tdn = makeArray(now);\n\t\t\t\tvar dt = m[2].match(/^(?:(\\d{4})(?:\\-(\\d\\d))?(?:\\-(\\d\\d))?)? ?(?:(\\d{1,2})(?:\\:(\\d\\d)(?:\\:(\\d\\d))?)?)?$/);\n\t\t\t\tdt.shift();\n\t\t\t\tfor(var p = 0, z = false, i = 0; i < 7; i++) {\n\t\t\t\t\tif(dt[i]) {\n\t\t\t\t\t\tdn[i] = parseInt(dt[i], 10);\n\t\t\t\t\t\tp = i;\n\t\t\t\t\t\tz = true;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif(z)\n\t\t\t\t\t\t\tdn[i] = i < 3 ? 1 : 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn makePrecRange(dn, p);\n\t\t\t} else if(m[3]) { // matches (\\d+[a-z]{1,4})\n\t\t\t\tvar dr = m[3].match(/(\\d+)\\s*([a-z]+)/i);\n\t\t\t\tvar n = parseInt(dr[1], 10);\n\t\t\t\treturn { rel: n * drp._relTokens[dr[2]] };\n\t\t\t}\n\t\t\tthrow \"unknown term \" + term;\n\t\t}\n\n\t\tif(!v) {\n\t\t\treturn { start: null, end: null };\n\t\t}\n\t\tvar terms = v.split(/\\s*([^<>]*[^<>-])?\\s*(->|<>|<)?\\s*([^<>]+)?\\s*/);\n\n\t\tvar term1 = terms[1] ? procTerm(terms[1]) : null;\n\t\tvar op = terms[2] || \"\";\n\t\tvar term2 = terms[3] ? procTerm(terms[3]) : null;\n\n\t\tif(op === \"<\" || op === \"->\" ) {\n\t\t\tif(term1 && !term2) {\n\t\t\t\treturn { start: term1.start, end: null };\n\t\t\t} else if(!term1 && term2) {\n\t\t\t\treturn { start: null, end: term2.end };\n\t\t\t} else {\n\t\t\t\tif(term2.rel) {\n\t\t\t\t\treturn { start: term1.start, end: term1.end + term2.rel };\n\t\t\t\t} else if(term1.rel) {\n\t\t\t\t\treturn { start: term2.start - term1.rel, end: term2.end };\n\t\t\t\t} else {\n\t\t\t\t\treturn { start: term1.start, end: term2.end };\n\t\t\t\t}\n\t\t\t}\n\t\t} else if(op === \"<>\") {\n\t\t\tif(!term2) {\n\t\t\t\treturn { start: term1.start - drp.defaultRange, end: term1.end + drp.defaultRange }\n\t\t\t} else {\n\t\t\t\tif(! (\"rel\" in term2)) throw \"second term did not hav a range\";\n\t\t\t\treturn { start: term1.start - term2.rel, end: term1.end + term2.rel };\n\t\t\t}\n\t\t} else {\n\t\t\tif(term1.rel) {\n\t\t\t\treturn { start: now - term1.rel, end: now + term1.rel };\n\t\t\t} else if(term1.now) {\n\t\t\t\treturn { start: term1.now - drp.defaultRange, end: term1.now + drp.defaultRange };\n\t\t\t} else {\n\t\t\t\treturn { start: term1.start, end: term1.end };\n\t\t\t}\n\t\t}\n\t\tthrow \"could not process value \" + v;\n\t};\n})();"
  },
  {
    "path": "src/vendor/font-awesome/css/font-awesome.css",
    "content": "/*!\n *  Font Awesome 4.0.3 by @davegandy - http://fontawesome.io - @fontawesome\n *  License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)\n */\n/* FONT PATH\n * -------------------------- */\n@font-face {\n  font-family: 'FontAwesome';\n  src: url('fonts/fontawesome-webfont.eot?v=4.0.3');\n  src: url('fonts/fontawesome-webfont.eot?#iefix&v=4.0.3') format('embedded-opentype'), url('fonts/fontawesome-webfont.woff?v=4.0.3') format('woff'), url('fonts/fontawesome-webfont.ttf?v=4.0.3') format('truetype'), url('fonts/fontawesome-webfont.svg?v=4.0.3#fontawesomeregular') format('svg');\n  font-weight: normal;\n  font-style: normal;\n}\n.fa {\n  display: inline-block;\n  font-family: FontAwesome;\n  font-style: normal;\n  font-weight: normal;\n  line-height: 1;\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n/* makes the font 33% larger relative to the icon container */\n.fa-lg {\n  font-size: 1.3333333333333333em;\n  line-height: 0.75em;\n  vertical-align: -15%;\n}\n.fa-2x {\n  font-size: 2em;\n}\n.fa-3x {\n  font-size: 3em;\n}\n.fa-4x {\n  font-size: 4em;\n}\n.fa-5x {\n  font-size: 5em;\n}\n.fa-fw {\n  width: 1.2857142857142858em;\n  text-align: center;\n}\n.fa-ul {\n  padding-left: 0;\n  margin-left: 2.142857142857143em;\n  list-style-type: none;\n}\n.fa-ul > li {\n  position: relative;\n}\n.fa-li {\n  position: absolute;\n  left: -2.142857142857143em;\n  width: 2.142857142857143em;\n  top: 0.14285714285714285em;\n  text-align: center;\n}\n.fa-li.fa-lg {\n  left: -1.8571428571428572em;\n}\n.fa-border {\n  padding: .2em .25em .15em;\n  border: solid 0.08em #eeeeee;\n  border-radius: .1em;\n}\n.pull-right {\n  float: right;\n}\n.pull-left {\n  float: left;\n}\n.fa.pull-left {\n  margin-right: .3em;\n}\n.fa.pull-right {\n  margin-left: .3em;\n}\n.fa-spin {\n  -webkit-animation: spin 2s infinite linear;\n  -moz-animation: spin 2s infinite linear;\n  -o-animation: spin 2s infinite linear;\n  animation: spin 2s infinite linear;\n}\n@-moz-keyframes spin {\n  0% {\n    -moz-transform: rotate(0deg);\n  }\n  100% {\n    -moz-transform: rotate(359deg);\n  }\n}\n@-webkit-keyframes spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n  }\n  100% {\n    -webkit-transform: rotate(359deg);\n  }\n}\n@-o-keyframes spin {\n  0% {\n    -o-transform: rotate(0deg);\n  }\n  100% {\n    -o-transform: rotate(359deg);\n  }\n}\n@-ms-keyframes spin {\n  0% {\n    -ms-transform: rotate(0deg);\n  }\n  100% {\n    -ms-transform: rotate(359deg);\n  }\n}\n@keyframes spin {\n  0% {\n    transform: rotate(0deg);\n  }\n  100% {\n    transform: rotate(359deg);\n  }\n}\n.fa-rotate-90 {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1);\n  -webkit-transform: rotate(90deg);\n  -moz-transform: rotate(90deg);\n  -ms-transform: rotate(90deg);\n  -o-transform: rotate(90deg);\n  transform: rotate(90deg);\n}\n.fa-rotate-180 {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2);\n  -webkit-transform: rotate(180deg);\n  -moz-transform: rotate(180deg);\n  -ms-transform: rotate(180deg);\n  -o-transform: rotate(180deg);\n  transform: rotate(180deg);\n}\n.fa-rotate-270 {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);\n  -webkit-transform: rotate(270deg);\n  -moz-transform: rotate(270deg);\n  -ms-transform: rotate(270deg);\n  -o-transform: rotate(270deg);\n  transform: rotate(270deg);\n}\n.fa-flip-horizontal {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);\n  -webkit-transform: scale(-1, 1);\n  -moz-transform: scale(-1, 1);\n  -ms-transform: scale(-1, 1);\n  -o-transform: scale(-1, 1);\n  transform: scale(-1, 1);\n}\n.fa-flip-vertical {\n  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);\n  -webkit-transform: scale(1, -1);\n  -moz-transform: scale(1, -1);\n  -ms-transform: scale(1, -1);\n  -o-transform: scale(1, -1);\n  transform: scale(1, -1);\n}\n.fa-stack {\n  position: relative;\n  display: inline-block;\n  width: 2em;\n  height: 2em;\n  line-height: 2em;\n  vertical-align: middle;\n}\n.fa-stack-1x,\n.fa-stack-2x {\n  position: absolute;\n  left: 0;\n  width: 100%;\n  text-align: center;\n}\n.fa-stack-1x {\n  line-height: inherit;\n}\n.fa-stack-2x {\n  font-size: 2em;\n}\n.fa-inverse {\n  color: #ffffff;\n}\n/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen\n   readers do not read off random characters that represent icons */\n.fa-glass:before {\n  content: \"\\f000\";\n}\n.fa-music:before {\n  content: \"\\f001\";\n}\n.fa-search:before {\n  content: \"\\f002\";\n}\n.fa-envelope-o:before {\n  content: \"\\f003\";\n}\n.fa-heart:before {\n  content: \"\\f004\";\n}\n.fa-star:before {\n  content: \"\\f005\";\n}\n.fa-star-o:before {\n  content: \"\\f006\";\n}\n.fa-user:before {\n  content: \"\\f007\";\n}\n.fa-film:before {\n  content: \"\\f008\";\n}\n.fa-th-large:before {\n  content: \"\\f009\";\n}\n.fa-th:before {\n  content: \"\\f00a\";\n}\n.fa-th-list:before {\n  content: \"\\f00b\";\n}\n.fa-check:before {\n  content: \"\\f00c\";\n}\n.fa-times:before {\n  content: \"\\f00d\";\n}\n.fa-search-plus:before {\n  content: \"\\f00e\";\n}\n.fa-search-minus:before {\n  content: \"\\f010\";\n}\n.fa-power-off:before {\n  content: \"\\f011\";\n}\n.fa-signal:before {\n  content: \"\\f012\";\n}\n.fa-gear:before,\n.fa-cog:before {\n  content: \"\\f013\";\n}\n.fa-trash-o:before {\n  content: \"\\f014\";\n}\n.fa-home:before {\n  content: \"\\f015\";\n}\n.fa-file-o:before {\n  content: \"\\f016\";\n}\n.fa-clock-o:before {\n  content: \"\\f017\";\n}\n.fa-road:before {\n  content: \"\\f018\";\n}\n.fa-download:before {\n  content: \"\\f019\";\n}\n.fa-arrow-circle-o-down:before {\n  content: \"\\f01a\";\n}\n.fa-arrow-circle-o-up:before {\n  content: \"\\f01b\";\n}\n.fa-inbox:before {\n  content: \"\\f01c\";\n}\n.fa-play-circle-o:before {\n  content: \"\\f01d\";\n}\n.fa-rotate-right:before,\n.fa-repeat:before {\n  content: \"\\f01e\";\n}\n.fa-refresh:before {\n  content: \"\\f021\";\n}\n.fa-list-alt:before {\n  content: \"\\f022\";\n}\n.fa-lock:before {\n  content: \"\\f023\";\n}\n.fa-flag:before {\n  content: \"\\f024\";\n}\n.fa-headphones:before {\n  content: \"\\f025\";\n}\n.fa-volume-off:before {\n  content: \"\\f026\";\n}\n.fa-volume-down:before {\n  content: \"\\f027\";\n}\n.fa-volume-up:before {\n  content: \"\\f028\";\n}\n.fa-qrcode:before {\n  content: \"\\f029\";\n}\n.fa-barcode:before {\n  content: \"\\f02a\";\n}\n.fa-tag:before {\n  content: \"\\f02b\";\n}\n.fa-tags:before {\n  content: \"\\f02c\";\n}\n.fa-book:before {\n  content: \"\\f02d\";\n}\n.fa-bookmark:before {\n  content: \"\\f02e\";\n}\n.fa-print:before {\n  content: \"\\f02f\";\n}\n.fa-camera:before {\n  content: \"\\f030\";\n}\n.fa-font:before {\n  content: \"\\f031\";\n}\n.fa-bold:before {\n  content: \"\\f032\";\n}\n.fa-italic:before {\n  content: \"\\f033\";\n}\n.fa-text-height:before {\n  content: \"\\f034\";\n}\n.fa-text-width:before {\n  content: \"\\f035\";\n}\n.fa-align-left:before {\n  content: \"\\f036\";\n}\n.fa-align-center:before {\n  content: \"\\f037\";\n}\n.fa-align-right:before {\n  content: \"\\f038\";\n}\n.fa-align-justify:before {\n  content: \"\\f039\";\n}\n.fa-list:before {\n  content: \"\\f03a\";\n}\n.fa-dedent:before,\n.fa-outdent:before {\n  content: \"\\f03b\";\n}\n.fa-indent:before {\n  content: \"\\f03c\";\n}\n.fa-video-camera:before {\n  content: \"\\f03d\";\n}\n.fa-picture-o:before {\n  content: \"\\f03e\";\n}\n.fa-pencil:before {\n  content: \"\\f040\";\n}\n.fa-map-marker:before {\n  content: \"\\f041\";\n}\n.fa-adjust:before {\n  content: \"\\f042\";\n}\n.fa-tint:before {\n  content: \"\\f043\";\n}\n.fa-edit:before,\n.fa-pencil-square-o:before {\n  content: \"\\f044\";\n}\n.fa-share-square-o:before {\n  content: \"\\f045\";\n}\n.fa-check-square-o:before {\n  content: \"\\f046\";\n}\n.fa-arrows:before {\n  content: \"\\f047\";\n}\n.fa-step-backward:before {\n  content: \"\\f048\";\n}\n.fa-fast-backward:before {\n  content: \"\\f049\";\n}\n.fa-backward:before {\n  content: \"\\f04a\";\n}\n.fa-play:before {\n  content: \"\\f04b\";\n}\n.fa-pause:before {\n  content: \"\\f04c\";\n}\n.fa-stop:before {\n  content: \"\\f04d\";\n}\n.fa-forward:before {\n  content: \"\\f04e\";\n}\n.fa-fast-forward:before {\n  content: \"\\f050\";\n}\n.fa-step-forward:before {\n  content: \"\\f051\";\n}\n.fa-eject:before {\n  content: \"\\f052\";\n}\n.fa-chevron-left:before {\n  content: \"\\f053\";\n}\n.fa-chevron-right:before {\n  content: \"\\f054\";\n}\n.fa-plus-circle:before {\n  content: \"\\f055\";\n}\n.fa-minus-circle:before {\n  content: \"\\f056\";\n}\n.fa-times-circle:before {\n  content: \"\\f057\";\n}\n.fa-check-circle:before {\n  content: \"\\f058\";\n}\n.fa-question-circle:before {\n  content: \"\\f059\";\n}\n.fa-info-circle:before {\n  content: \"\\f05a\";\n}\n.fa-crosshairs:before {\n  content: \"\\f05b\";\n}\n.fa-times-circle-o:before {\n  content: \"\\f05c\";\n}\n.fa-check-circle-o:before {\n  content: \"\\f05d\";\n}\n.fa-ban:before {\n  content: \"\\f05e\";\n}\n.fa-arrow-left:before {\n  content: \"\\f060\";\n}\n.fa-arrow-right:before {\n  content: \"\\f061\";\n}\n.fa-arrow-up:before {\n  content: \"\\f062\";\n}\n.fa-arrow-down:before {\n  content: \"\\f063\";\n}\n.fa-mail-forward:before,\n.fa-share:before {\n  content: \"\\f064\";\n}\n.fa-expand:before {\n  content: \"\\f065\";\n}\n.fa-compress:before {\n  content: \"\\f066\";\n}\n.fa-plus:before {\n  content: \"\\f067\";\n}\n.fa-minus:before {\n  content: \"\\f068\";\n}\n.fa-asterisk:before {\n  content: \"\\f069\";\n}\n.fa-exclamation-circle:before {\n  content: \"\\f06a\";\n}\n.fa-gift:before {\n  content: \"\\f06b\";\n}\n.fa-leaf:before {\n  content: \"\\f06c\";\n}\n.fa-fire:before {\n  content: \"\\f06d\";\n}\n.fa-eye:before {\n  content: \"\\f06e\";\n}\n.fa-eye-slash:before {\n  content: \"\\f070\";\n}\n.fa-warning:before,\n.fa-exclamation-triangle:before {\n  content: \"\\f071\";\n}\n.fa-plane:before {\n  content: \"\\f072\";\n}\n.fa-calendar:before {\n  content: \"\\f073\";\n}\n.fa-random:before {\n  content: \"\\f074\";\n}\n.fa-comment:before {\n  content: \"\\f075\";\n}\n.fa-magnet:before {\n  content: \"\\f076\";\n}\n.fa-chevron-up:before {\n  content: \"\\f077\";\n}\n.fa-chevron-down:before {\n  content: \"\\f078\";\n}\n.fa-retweet:before {\n  content: \"\\f079\";\n}\n.fa-shopping-cart:before {\n  content: \"\\f07a\";\n}\n.fa-folder:before {\n  content: \"\\f07b\";\n}\n.fa-folder-open:before {\n  content: \"\\f07c\";\n}\n.fa-arrows-v:before {\n  content: \"\\f07d\";\n}\n.fa-arrows-h:before {\n  content: \"\\f07e\";\n}\n.fa-bar-chart-o:before {\n  content: \"\\f080\";\n}\n.fa-twitter-square:before {\n  content: \"\\f081\";\n}\n.fa-facebook-square:before {\n  content: \"\\f082\";\n}\n.fa-camera-retro:before {\n  content: \"\\f083\";\n}\n.fa-key:before {\n  content: \"\\f084\";\n}\n.fa-gears:before,\n.fa-cogs:before {\n  content: \"\\f085\";\n}\n.fa-comments:before {\n  content: \"\\f086\";\n}\n.fa-thumbs-o-up:before {\n  content: \"\\f087\";\n}\n.fa-thumbs-o-down:before {\n  content: \"\\f088\";\n}\n.fa-star-half:before {\n  content: \"\\f089\";\n}\n.fa-heart-o:before {\n  content: \"\\f08a\";\n}\n.fa-sign-out:before {\n  content: \"\\f08b\";\n}\n.fa-linkedin-square:before {\n  content: \"\\f08c\";\n}\n.fa-thumb-tack:before {\n  content: \"\\f08d\";\n}\n.fa-external-link:before {\n  content: \"\\f08e\";\n}\n.fa-sign-in:before {\n  content: \"\\f090\";\n}\n.fa-trophy:before {\n  content: \"\\f091\";\n}\n.fa-github-square:before {\n  content: \"\\f092\";\n}\n.fa-upload:before {\n  content: \"\\f093\";\n}\n.fa-lemon-o:before {\n  content: \"\\f094\";\n}\n.fa-phone:before {\n  content: \"\\f095\";\n}\n.fa-square-o:before {\n  content: \"\\f096\";\n}\n.fa-bookmark-o:before {\n  content: \"\\f097\";\n}\n.fa-phone-square:before {\n  content: \"\\f098\";\n}\n.fa-twitter:before {\n  content: \"\\f099\";\n}\n.fa-facebook:before {\n  content: \"\\f09a\";\n}\n.fa-github:before {\n  content: \"\\f09b\";\n}\n.fa-unlock:before {\n  content: \"\\f09c\";\n}\n.fa-credit-card:before {\n  content: \"\\f09d\";\n}\n.fa-rss:before {\n  content: \"\\f09e\";\n}\n.fa-hdd-o:before {\n  content: \"\\f0a0\";\n}\n.fa-bullhorn:before {\n  content: \"\\f0a1\";\n}\n.fa-bell:before {\n  content: \"\\f0f3\";\n}\n.fa-certificate:before {\n  content: \"\\f0a3\";\n}\n.fa-hand-o-right:before {\n  content: \"\\f0a4\";\n}\n.fa-hand-o-left:before {\n  content: \"\\f0a5\";\n}\n.fa-hand-o-up:before {\n  content: \"\\f0a6\";\n}\n.fa-hand-o-down:before {\n  content: \"\\f0a7\";\n}\n.fa-arrow-circle-left:before {\n  content: \"\\f0a8\";\n}\n.fa-arrow-circle-right:before {\n  content: \"\\f0a9\";\n}\n.fa-arrow-circle-up:before {\n  content: \"\\f0aa\";\n}\n.fa-arrow-circle-down:before {\n  content: \"\\f0ab\";\n}\n.fa-globe:before {\n  content: \"\\f0ac\";\n}\n.fa-wrench:before {\n  content: \"\\f0ad\";\n}\n.fa-tasks:before {\n  content: \"\\f0ae\";\n}\n.fa-filter:before {\n  content: \"\\f0b0\";\n}\n.fa-briefcase:before {\n  content: \"\\f0b1\";\n}\n.fa-arrows-alt:before {\n  content: \"\\f0b2\";\n}\n.fa-group:before,\n.fa-users:before {\n  content: \"\\f0c0\";\n}\n.fa-chain:before,\n.fa-link:before {\n  content: \"\\f0c1\";\n}\n.fa-cloud:before {\n  content: \"\\f0c2\";\n}\n.fa-flask:before {\n  content: \"\\f0c3\";\n}\n.fa-cut:before,\n.fa-scissors:before {\n  content: \"\\f0c4\";\n}\n.fa-copy:before,\n.fa-files-o:before {\n  content: \"\\f0c5\";\n}\n.fa-paperclip:before {\n  content: \"\\f0c6\";\n}\n.fa-save:before,\n.fa-floppy-o:before {\n  content: \"\\f0c7\";\n}\n.fa-square:before {\n  content: \"\\f0c8\";\n}\n.fa-bars:before {\n  content: \"\\f0c9\";\n}\n.fa-list-ul:before {\n  content: \"\\f0ca\";\n}\n.fa-list-ol:before {\n  content: \"\\f0cb\";\n}\n.fa-strikethrough:before {\n  content: \"\\f0cc\";\n}\n.fa-underline:before {\n  content: \"\\f0cd\";\n}\n.fa-table:before {\n  content: \"\\f0ce\";\n}\n.fa-magic:before {\n  content: \"\\f0d0\";\n}\n.fa-truck:before {\n  content: \"\\f0d1\";\n}\n.fa-pinterest:before {\n  content: \"\\f0d2\";\n}\n.fa-pinterest-square:before {\n  content: \"\\f0d3\";\n}\n.fa-google-plus-square:before {\n  content: \"\\f0d4\";\n}\n.fa-google-plus:before {\n  content: \"\\f0d5\";\n}\n.fa-money:before {\n  content: \"\\f0d6\";\n}\n.fa-caret-down:before {\n  content: \"\\f0d7\";\n}\n.fa-caret-up:before {\n  content: \"\\f0d8\";\n}\n.fa-caret-left:before {\n  content: \"\\f0d9\";\n}\n.fa-caret-right:before {\n  content: \"\\f0da\";\n}\n.fa-columns:before {\n  content: \"\\f0db\";\n}\n.fa-unsorted:before,\n.fa-sort:before {\n  content: \"\\f0dc\";\n}\n.fa-sort-down:before,\n.fa-sort-asc:before {\n  content: \"\\f0dd\";\n}\n.fa-sort-up:before,\n.fa-sort-desc:before {\n  content: \"\\f0de\";\n}\n.fa-envelope:before {\n  content: \"\\f0e0\";\n}\n.fa-linkedin:before {\n  content: \"\\f0e1\";\n}\n.fa-rotate-left:before,\n.fa-undo:before {\n  content: \"\\f0e2\";\n}\n.fa-legal:before,\n.fa-gavel:before {\n  content: \"\\f0e3\";\n}\n.fa-dashboard:before,\n.fa-tachometer:before {\n  content: \"\\f0e4\";\n}\n.fa-comment-o:before {\n  content: \"\\f0e5\";\n}\n.fa-comments-o:before {\n  content: \"\\f0e6\";\n}\n.fa-flash:before,\n.fa-bolt:before {\n  content: \"\\f0e7\";\n}\n.fa-sitemap:before {\n  content: \"\\f0e8\";\n}\n.fa-umbrella:before {\n  content: \"\\f0e9\";\n}\n.fa-paste:before,\n.fa-clipboard:before {\n  content: \"\\f0ea\";\n}\n.fa-lightbulb-o:before {\n  content: \"\\f0eb\";\n}\n.fa-exchange:before {\n  content: \"\\f0ec\";\n}\n.fa-cloud-download:before {\n  content: \"\\f0ed\";\n}\n.fa-cloud-upload:before {\n  content: \"\\f0ee\";\n}\n.fa-user-md:before {\n  content: \"\\f0f0\";\n}\n.fa-stethoscope:before {\n  content: \"\\f0f1\";\n}\n.fa-suitcase:before {\n  content: \"\\f0f2\";\n}\n.fa-bell-o:before {\n  content: \"\\f0a2\";\n}\n.fa-coffee:before {\n  content: \"\\f0f4\";\n}\n.fa-cutlery:before {\n  content: \"\\f0f5\";\n}\n.fa-file-text-o:before {\n  content: \"\\f0f6\";\n}\n.fa-building-o:before {\n  content: \"\\f0f7\";\n}\n.fa-hospital-o:before {\n  content: \"\\f0f8\";\n}\n.fa-ambulance:before {\n  content: \"\\f0f9\";\n}\n.fa-medkit:before {\n  content: \"\\f0fa\";\n}\n.fa-fighter-jet:before {\n  content: \"\\f0fb\";\n}\n.fa-beer:before {\n  content: \"\\f0fc\";\n}\n.fa-h-square:before {\n  content: \"\\f0fd\";\n}\n.fa-plus-square:before {\n  content: \"\\f0fe\";\n}\n.fa-angle-double-left:before {\n  content: \"\\f100\";\n}\n.fa-angle-double-right:before {\n  content: \"\\f101\";\n}\n.fa-angle-double-up:before {\n  content: \"\\f102\";\n}\n.fa-angle-double-down:before {\n  content: \"\\f103\";\n}\n.fa-angle-left:before {\n  content: \"\\f104\";\n}\n.fa-angle-right:before {\n  content: \"\\f105\";\n}\n.fa-angle-up:before {\n  content: \"\\f106\";\n}\n.fa-angle-down:before {\n  content: \"\\f107\";\n}\n.fa-desktop:before {\n  content: \"\\f108\";\n}\n.fa-laptop:before {\n  content: \"\\f109\";\n}\n.fa-tablet:before {\n  content: \"\\f10a\";\n}\n.fa-mobile-phone:before,\n.fa-mobile:before {\n  content: \"\\f10b\";\n}\n.fa-circle-o:before {\n  content: \"\\f10c\";\n}\n.fa-quote-left:before {\n  content: \"\\f10d\";\n}\n.fa-quote-right:before {\n  content: \"\\f10e\";\n}\n.fa-spinner:before {\n  content: \"\\f110\";\n}\n.fa-circle:before {\n  content: \"\\f111\";\n}\n.fa-mail-reply:before,\n.fa-reply:before {\n  content: \"\\f112\";\n}\n.fa-github-alt:before {\n  content: \"\\f113\";\n}\n.fa-folder-o:before {\n  content: \"\\f114\";\n}\n.fa-folder-open-o:before {\n  content: \"\\f115\";\n}\n.fa-smile-o:before {\n  content: \"\\f118\";\n}\n.fa-frown-o:before {\n  content: \"\\f119\";\n}\n.fa-meh-o:before {\n  content: \"\\f11a\";\n}\n.fa-gamepad:before {\n  content: \"\\f11b\";\n}\n.fa-keyboard-o:before {\n  content: \"\\f11c\";\n}\n.fa-flag-o:before {\n  content: \"\\f11d\";\n}\n.fa-flag-checkered:before {\n  content: \"\\f11e\";\n}\n.fa-terminal:before {\n  content: \"\\f120\";\n}\n.fa-code:before {\n  content: \"\\f121\";\n}\n.fa-reply-all:before {\n  content: \"\\f122\";\n}\n.fa-mail-reply-all:before {\n  content: \"\\f122\";\n}\n.fa-star-half-empty:before,\n.fa-star-half-full:before,\n.fa-star-half-o:before {\n  content: \"\\f123\";\n}\n.fa-location-arrow:before {\n  content: \"\\f124\";\n}\n.fa-crop:before {\n  content: \"\\f125\";\n}\n.fa-code-fork:before {\n  content: \"\\f126\";\n}\n.fa-unlink:before,\n.fa-chain-broken:before {\n  content: \"\\f127\";\n}\n.fa-question:before {\n  content: \"\\f128\";\n}\n.fa-info:before {\n  content: \"\\f129\";\n}\n.fa-exclamation:before {\n  content: \"\\f12a\";\n}\n.fa-superscript:before {\n  content: \"\\f12b\";\n}\n.fa-subscript:before {\n  content: \"\\f12c\";\n}\n.fa-eraser:before {\n  content: \"\\f12d\";\n}\n.fa-puzzle-piece:before {\n  content: \"\\f12e\";\n}\n.fa-microphone:before {\n  content: \"\\f130\";\n}\n.fa-microphone-slash:before {\n  content: \"\\f131\";\n}\n.fa-shield:before {\n  content: \"\\f132\";\n}\n.fa-calendar-o:before {\n  content: \"\\f133\";\n}\n.fa-fire-extinguisher:before {\n  content: \"\\f134\";\n}\n.fa-rocket:before {\n  content: \"\\f135\";\n}\n.fa-maxcdn:before {\n  content: \"\\f136\";\n}\n.fa-chevron-circle-left:before {\n  content: \"\\f137\";\n}\n.fa-chevron-circle-right:before {\n  content: \"\\f138\";\n}\n.fa-chevron-circle-up:before {\n  content: \"\\f139\";\n}\n.fa-chevron-circle-down:before {\n  content: \"\\f13a\";\n}\n.fa-html5:before {\n  content: \"\\f13b\";\n}\n.fa-css3:before {\n  content: \"\\f13c\";\n}\n.fa-anchor:before {\n  content: \"\\f13d\";\n}\n.fa-unlock-alt:before {\n  content: \"\\f13e\";\n}\n.fa-bullseye:before {\n  content: \"\\f140\";\n}\n.fa-ellipsis-h:before {\n  content: \"\\f141\";\n}\n.fa-ellipsis-v:before {\n  content: \"\\f142\";\n}\n.fa-rss-square:before {\n  content: \"\\f143\";\n}\n.fa-play-circle:before {\n  content: \"\\f144\";\n}\n.fa-ticket:before {\n  content: \"\\f145\";\n}\n.fa-minus-square:before {\n  content: \"\\f146\";\n}\n.fa-minus-square-o:before {\n  content: \"\\f147\";\n}\n.fa-level-up:before {\n  content: \"\\f148\";\n}\n.fa-level-down:before {\n  content: \"\\f149\";\n}\n.fa-check-square:before {\n  content: \"\\f14a\";\n}\n.fa-pencil-square:before {\n  content: \"\\f14b\";\n}\n.fa-external-link-square:before {\n  content: \"\\f14c\";\n}\n.fa-share-square:before {\n  content: \"\\f14d\";\n}\n.fa-compass:before {\n  content: \"\\f14e\";\n}\n.fa-toggle-down:before,\n.fa-caret-square-o-down:before {\n  content: \"\\f150\";\n}\n.fa-toggle-up:before,\n.fa-caret-square-o-up:before {\n  content: \"\\f151\";\n}\n.fa-toggle-right:before,\n.fa-caret-square-o-right:before {\n  content: \"\\f152\";\n}\n.fa-euro:before,\n.fa-eur:before {\n  content: \"\\f153\";\n}\n.fa-gbp:before {\n  content: \"\\f154\";\n}\n.fa-dollar:before,\n.fa-usd:before {\n  content: \"\\f155\";\n}\n.fa-rupee:before,\n.fa-inr:before {\n  content: \"\\f156\";\n}\n.fa-cny:before,\n.fa-rmb:before,\n.fa-yen:before,\n.fa-jpy:before {\n  content: \"\\f157\";\n}\n.fa-ruble:before,\n.fa-rouble:before,\n.fa-rub:before {\n  content: \"\\f158\";\n}\n.fa-won:before,\n.fa-krw:before {\n  content: \"\\f159\";\n}\n.fa-bitcoin:before,\n.fa-btc:before {\n  content: \"\\f15a\";\n}\n.fa-file:before {\n  content: \"\\f15b\";\n}\n.fa-file-text:before {\n  content: \"\\f15c\";\n}\n.fa-sort-alpha-asc:before {\n  content: \"\\f15d\";\n}\n.fa-sort-alpha-desc:before {\n  content: \"\\f15e\";\n}\n.fa-sort-amount-asc:before {\n  content: \"\\f160\";\n}\n.fa-sort-amount-desc:before {\n  content: \"\\f161\";\n}\n.fa-sort-numeric-asc:before {\n  content: \"\\f162\";\n}\n.fa-sort-numeric-desc:before {\n  content: \"\\f163\";\n}\n.fa-thumbs-up:before {\n  content: \"\\f164\";\n}\n.fa-thumbs-down:before {\n  content: \"\\f165\";\n}\n.fa-youtube-square:before {\n  content: \"\\f166\";\n}\n.fa-youtube:before {\n  content: \"\\f167\";\n}\n.fa-xing:before {\n  content: \"\\f168\";\n}\n.fa-xing-square:before {\n  content: \"\\f169\";\n}\n.fa-youtube-play:before {\n  content: \"\\f16a\";\n}\n.fa-dropbox:before {\n  content: \"\\f16b\";\n}\n.fa-stack-overflow:before {\n  content: \"\\f16c\";\n}\n.fa-instagram:before {\n  content: \"\\f16d\";\n}\n.fa-flickr:before {\n  content: \"\\f16e\";\n}\n.fa-adn:before {\n  content: \"\\f170\";\n}\n.fa-bitbucket:before {\n  content: \"\\f171\";\n}\n.fa-bitbucket-square:before {\n  content: \"\\f172\";\n}\n.fa-tumblr:before {\n  content: \"\\f173\";\n}\n.fa-tumblr-square:before {\n  content: \"\\f174\";\n}\n.fa-long-arrow-down:before {\n  content: \"\\f175\";\n}\n.fa-long-arrow-up:before {\n  content: \"\\f176\";\n}\n.fa-long-arrow-left:before {\n  content: \"\\f177\";\n}\n.fa-long-arrow-right:before {\n  content: \"\\f178\";\n}\n.fa-apple:before {\n  content: \"\\f179\";\n}\n.fa-windows:before {\n  content: \"\\f17a\";\n}\n.fa-android:before {\n  content: \"\\f17b\";\n}\n.fa-linux:before {\n  content: \"\\f17c\";\n}\n.fa-dribbble:before {\n  content: \"\\f17d\";\n}\n.fa-skype:before {\n  content: \"\\f17e\";\n}\n.fa-foursquare:before {\n  content: \"\\f180\";\n}\n.fa-trello:before {\n  content: \"\\f181\";\n}\n.fa-female:before {\n  content: \"\\f182\";\n}\n.fa-male:before {\n  content: \"\\f183\";\n}\n.fa-gittip:before {\n  content: \"\\f184\";\n}\n.fa-sun-o:before {\n  content: \"\\f185\";\n}\n.fa-moon-o:before {\n  content: \"\\f186\";\n}\n.fa-archive:before {\n  content: \"\\f187\";\n}\n.fa-bug:before {\n  content: \"\\f188\";\n}\n.fa-vk:before {\n  content: \"\\f189\";\n}\n.fa-weibo:before {\n  content: \"\\f18a\";\n}\n.fa-renren:before {\n  content: \"\\f18b\";\n}\n.fa-pagelines:before {\n  content: \"\\f18c\";\n}\n.fa-stack-exchange:before {\n  content: \"\\f18d\";\n}\n.fa-arrow-circle-o-right:before {\n  content: \"\\f18e\";\n}\n.fa-arrow-circle-o-left:before {\n  content: \"\\f190\";\n}\n.fa-toggle-left:before,\n.fa-caret-square-o-left:before {\n  content: \"\\f191\";\n}\n.fa-dot-circle-o:before {\n  content: \"\\f192\";\n}\n.fa-wheelchair:before {\n  content: \"\\f193\";\n}\n.fa-vimeo-square:before {\n  content: \"\\f194\";\n}\n.fa-turkish-lira:before,\n.fa-try:before {\n  content: \"\\f195\";\n}\n.fa-plus-square-o:before {\n  content: \"\\f196\";\n}\n"
  },
  {
    "path": "src/vendor/graphael/g.raphael.standalone.js",
    "content": "/*!\n * Raphael 1.5.2 - JavaScript Vector Library\n *\n * Copyright (c) 2010 Dmitry Baranovskiy (http://raphaeljs.com)\n * Licensed under the MIT (http://raphaeljs.com/license.html) license.\n * from fork at git@github.com:mobz/g.raphael.git\n */\n(function () {\n    function R() {\n        if (R.is(arguments[0], array)) {\n            var a = arguments[0],\n                cnv = create[apply](R, a.splice(0, 3 + R.is(a[0], nu))),\n                res = cnv.set();\n            for (var i = 0, ii = a[length]; i < ii; i++) {\n                var j = a[i] || {};\n                elements[has](j.type) && res[push](cnv[j.type]().attr(j));\n            }\n            return res;\n        }\n        return create[apply](R, arguments);\n    }\n    R.version = \"1.5.2\";\n    var separator = /[, ]+/,\n        elements = {circle: 1, rect: 1, path: 1, ellipse: 1, text: 1, image: 1},\n        formatrg = /\\{(\\d+)\\}/g,\n        proto = \"prototype\",\n        has = \"hasOwnProperty\",\n        doc = document,\n        win = window,\n        oldRaphael = {\n            was: Object[proto][has].call(win, \"Raphael\"),\n            is: win.Raphael\n        },\n        Paper = function () {\n            this.customAttributes = {};\n        },\n        paperproto,\n        appendChild = \"appendChild\",\n        apply = \"apply\",\n        concat = \"concat\",\n        supportsTouch = \"createTouch\" in doc,\n        E = \"\",\n        S = \" \",\n        Str = String,\n        split = \"split\",\n        events = \"click dblclick mousedown mousemove mouseout mouseover mouseup touchstart touchmove touchend orientationchange touchcancel gesturestart gesturechange gestureend\"[split](S),\n        touchMap = {\n            mousedown: \"touchstart\",\n            mousemove: \"touchmove\",\n            mouseup: \"touchend\"\n        },\n        join = \"join\",\n        length = \"length\",\n        lowerCase = Str[proto].toLowerCase,\n        math = Math,\n        mmax = math.max,\n        mmin = math.min,\n        abs = math.abs,\n        pow = math.pow,\n        PI = math.PI,\n        nu = \"number\",\n        string = \"string\",\n        array = \"array\",\n        toString = \"toString\",\n        fillString = \"fill\",\n        objectToString = Object[proto][toString],\n        paper = {},\n        push = \"push\",\n        ISURL = /^url\\(['\"]?([^\\)]+?)['\"]?\\)$/i,\n        colourRegExp = /^\\s*((#[a-f\\d]{6})|(#[a-f\\d]{3})|rgba?\\(\\s*([\\d\\.]+%?\\s*,\\s*[\\d\\.]+%?\\s*,\\s*[\\d\\.]+(?:%?\\s*,\\s*[\\d\\.]+)?)%?\\s*\\)|hsba?\\(\\s*([\\d\\.]+(?:deg|\\xb0|%)?\\s*,\\s*[\\d\\.]+%?\\s*,\\s*[\\d\\.]+(?:%?\\s*,\\s*[\\d\\.]+)?)%?\\s*\\)|hsla?\\(\\s*([\\d\\.]+(?:deg|\\xb0|%)?\\s*,\\s*[\\d\\.]+%?\\s*,\\s*[\\d\\.]+(?:%?\\s*,\\s*[\\d\\.]+)?)%?\\s*\\))\\s*$/i,\n        isnan = {\"NaN\": 1, \"Infinity\": 1, \"-Infinity\": 1},\n        bezierrg = /^(?:cubic-)?bezier\\(([^,]+),([^,]+),([^,]+),([^\\)]+)\\)/,\n        round = math.round,\n        setAttribute = \"setAttribute\",\n        toFloat = parseFloat,\n        toInt = parseInt,\n        ms = \" progid:DXImageTransform.Microsoft\",\n        upperCase = Str[proto].toUpperCase,\n        availableAttrs = {blur: 0, \"clip-rect\": \"0 0 1e9 1e9\", cursor: \"default\", cx: 0, cy: 0, fill: \"#fff\", \"fill-opacity\": 1, font: '10px \"Arial\"', \"font-family\": '\"Arial\"', \"font-size\": \"10\", \"font-style\": \"normal\", \"font-weight\": 400, gradient: 0, height: 0, href: \"http://raphaeljs.com/\", opacity: 1, path: \"M0,0\", r: 0, rotation: 0, rx: 0, ry: 0, scale: \"1 1\", src: \"\", stroke: \"#000\", \"stroke-dasharray\": \"\", \"stroke-linecap\": \"butt\", \"stroke-linejoin\": \"butt\", \"stroke-miterlimit\": 0, \"stroke-opacity\": 1, \"stroke-width\": 1, target: \"_blank\", \"text-anchor\": \"middle\", title: \"Raphael\", translation: \"0 0\", width: 0, x: 0, y: 0},\n        availableAnimAttrs = {along: \"along\", blur: nu, \"clip-rect\": \"csv\", cx: nu, cy: nu, fill: \"colour\", \"fill-opacity\": nu, \"font-size\": nu, height: nu, opacity: nu, path: \"path\", r: nu, rotation: \"csv\", rx: nu, ry: nu, scale: \"csv\", stroke: \"colour\", \"stroke-opacity\": nu, \"stroke-width\": nu, translation: \"csv\", width: nu, x: nu, y: nu},\n        rp = \"replace\",\n        animKeyFrames= /^(from|to|\\d+%?)$/,\n        commaSpaces = /\\s*,\\s*/,\n        hsrg = {hs: 1, rg: 1},\n        p2s = /,?([achlmqrstvxz]),?/gi,\n        pathCommand = /([achlmqstvz])[\\s,]*((-?\\d*\\.?\\d*(?:e[-+]?\\d+)?\\s*,?\\s*)+)/ig,\n        pathValues = /(-?\\d*\\.?\\d*(?:e[-+]?\\d+)?)\\s*,?\\s*/ig,\n        radial_gradient = /^r(?:\\(([^,]+?)\\s*,\\s*([^\\)]+?)\\))?/,\n        sortByKey = function (a, b) {\n            return a.key - b.key;\n        };\n\n    R.type = (win.SVGAngle || doc.implementation.hasFeature(\"http://www.w3.org/TR/SVG11/feature#BasicStructure\", \"1.1\") ? \"SVG\" : \"VML\");\n    if (R.type == \"VML\") {\n        var d = doc.createElement(\"div\"),\n            b;\n        d.innerHTML = '<v:shape adj=\"1\"/>';\n        b = d.firstChild;\n        b.style.behavior = \"url(#default#VML)\";\n        if (!(b && typeof b.adj == \"object\")) {\n            return R.type = null;\n        }\n        d = null;\n    }\n    R.svg = !(R.vml = R.type == \"VML\");\n    Paper[proto] = R[proto];\n    paperproto = Paper[proto];\n    R._id = 0;\n    R._oid = 0;\n    R.fn = {};\n    R.is = function (o, type) {\n        type = lowerCase.call(type);\n        if (type == \"finite\") {\n            return !isnan[has](+o);\n        }\n        return  (type == \"null\" && o === null) ||\n                (type == typeof o) ||\n                (type == \"object\" && o === Object(o)) ||\n                (type == \"array\" && Array.isArray && Array.isArray(o)) ||\n                objectToString.call(o).slice(8, -1).toLowerCase() == type;\n    };\n    R.angle = function (x1, y1, x2, y2, x3, y3) {\n        if (x3 == null) {\n            var x = x1 - x2,\n                y = y1 - y2;\n            if (!x && !y) {\n                return 0;\n            }\n            return ((x < 0) * 180 + math.atan(-y / -x) * 180 / PI + 360) % 360;\n        } else {\n            return R.angle(x1, y1, x3, y3) - R.angle(x2, y2, x3, y3);\n        }\n    };\n    R.rad = function (deg) {\n        return deg % 360 * PI / 180;\n    };\n    R.deg = function (rad) {\n        return rad * 180 / PI % 360;\n    };\n    R.snapTo = function (values, value, tolerance) {\n        tolerance = R.is(tolerance, \"finite\") ? tolerance : 10;\n        if (R.is(values, array)) {\n            var i = values.length;\n            while (i--) if (abs(values[i] - value) <= tolerance) {\n                return values[i];\n            }\n        } else {\n            values = +values;\n            var rem = value % values;\n            if (rem < tolerance) {\n                return value - rem;\n            }\n            if (rem > values - tolerance) {\n                return value - rem + values;\n            }\n        }\n        return value;\n    };\n    function createUUID() {\n        // http://www.ietf.org/rfc/rfc4122.txt\n        var s = [],\n            i = 0;\n        for (; i < 32; i++) {\n            s[i] = (~~(math.random() * 16))[toString](16);\n        }\n        s[12] = 4;  // bits 12-15 of the time_hi_and_version field to 0010\n        s[16] = ((s[16] & 3) | 8)[toString](16);  // bits 6-7 of the clock_seq_hi_and_reserved to 01\n        return \"r-\" + s[join](\"\");\n    }\n\n    R.setWindow = function (newwin) {\n        win = newwin;\n        doc = win.document;\n    };\n    // colour utilities\n    var toHex = function (color) {\n        if (R.vml) {\n            // http://dean.edwards.name/weblog/2009/10/convert-any-colour-value-to-hex-in-msie/\n            var trim = /^\\s+|\\s+$/g;\n            var bod;\n            try {\n                var docum = new ActiveXObject(\"htmlfile\");\n                docum.write(\"<body>\");\n                docum.close();\n                bod = docum.body;\n            } catch(e) {\n                bod = createPopup().document.body;\n            }\n            var range = bod.createTextRange();\n            toHex = cacher(function (color) {\n                try {\n                    bod.style.color = Str(color)[rp](trim, E);\n                    var value = range.queryCommandValue(\"ForeColor\");\n                    value = ((value & 255) << 16) | (value & 65280) | ((value & 16711680) >>> 16);\n                    return \"#\" + (\"000000\" + value[toString](16)).slice(-6);\n                } catch(e) {\n                    return \"none\";\n                }\n            });\n        } else {\n            var i = doc.createElement(\"i\");\n            i.title = \"Rapha\\xebl Colour Picker\";\n            i.style.display = \"none\";\n            doc.body[appendChild](i);\n            toHex = cacher(function (color) {\n                i.style.color = color;\n                return doc.defaultView.getComputedStyle(i, E).getPropertyValue(\"color\");\n            });\n        }\n        return toHex(color);\n    },\n    hsbtoString = function () {\n        return \"hsb(\" + [this.h, this.s, this.b] + \")\";\n    },\n    hsltoString = function () {\n        return \"hsl(\" + [this.h, this.s, this.l] + \")\";\n    },\n    rgbtoString = function () {\n        return this.hex;\n    };\n    R.hsb2rgb = function (h, s, b, o) {\n        if (R.is(h, \"object\") && \"h\" in h && \"s\" in h && \"b\" in h) {\n            b = h.b;\n            s = h.s;\n            h = h.h;\n            o = h.o;\n        }\n        return R.hsl2rgb(h, s, b / 2, o);\n    };\n    R.hsl2rgb = function (h, s, l, o) {\n        if (R.is(h, \"object\") && \"h\" in h && \"s\" in h && \"l\" in h) {\n            l = h.l;\n            s = h.s;\n            h = h.h;\n        }\n        if (h > 1 || s > 1 || l > 1) {\n            h /= 360;\n            s /= 100;\n            l /= 100;\n        }\n        var rgb = {},\n            channels = [\"r\", \"g\", \"b\"],\n            t2, t1, t3, r, g, b;\n        if (!s) {\n            rgb = {\n                r: l,\n                g: l,\n                b: l\n            };\n        } else {\n            if (l < .5) {\n                t2 = l * (1 + s);\n            } else {\n                t2 = l + s - l * s;\n            }\n            t1 = 2 * l - t2;\n            for (var i = 0; i < 3; i++) {\n                t3 = h + 1 / 3 * -(i - 1);\n                t3 < 0 && t3++;\n                t3 > 1 && t3--;\n                if (t3 * 6 < 1) {\n                    rgb[channels[i]] = t1 + (t2 - t1) * 6 * t3;\n                } else if (t3 * 2 < 1) {\n                    rgb[channels[i]] = t2;\n                } else if (t3 * 3 < 2) {\n                    rgb[channels[i]] = t1 + (t2 - t1) * (2 / 3 - t3) * 6;\n                } else {\n                    rgb[channels[i]] = t1;\n                }\n            }\n        }\n        rgb.r *= 255;\n        rgb.g *= 255;\n        rgb.b *= 255;\n        rgb.hex = \"#\" + (16777216 | rgb.b | (rgb.g << 8) | (rgb.r << 16)).toString(16).slice(1);\n        R.is(o, \"finite\") && (rgb.opacity = o);\n        rgb.toString = rgbtoString;\n        return rgb;\n    };\n    R.rgb2hsb = function (red, green, blue) {\n        if (green == null && R.is(red, \"object\") && \"r\" in red && \"g\" in red && \"b\" in red) {\n            blue = red.b;\n            green = red.g;\n            red = red.r;\n        }\n        if (green == null && R.is(red, string)) {\n            var clr = R.getRGB(red);\n            red = clr.r;\n            green = clr.g;\n            blue = clr.b;\n        }\n        if (red > 1 || green > 1 || blue > 1) {\n            red /= 255;\n            green /= 255;\n            blue /= 255;\n        }\n        var max = mmax(red, green, blue),\n            min = mmin(red, green, blue),\n            hue,\n            saturation,\n            brightness = max;\n        if (min == max) {\n            return {h: 0, s: 0, b: max, toString: hsbtoString};\n        } else {\n            var delta = (max - min);\n            saturation = delta / max;\n            if (red == max) {\n                hue = (green - blue) / delta;\n            } else if (green == max) {\n                hue = 2 + ((blue - red) / delta);\n            } else {\n                hue = 4 + ((red - green) / delta);\n            }\n            hue /= 6;\n            hue < 0 && hue++;\n            hue > 1 && hue--;\n        }\n        return {h: hue, s: saturation, b: brightness, toString: hsbtoString};\n    };\n    R.rgb2hsl = function (red, green, blue) {\n        if (green == null && R.is(red, \"object\") && \"r\" in red && \"g\" in red && \"b\" in red) {\n            blue = red.b;\n            green = red.g;\n            red = red.r;\n        }\n        if (green == null && R.is(red, string)) {\n            var clr = R.getRGB(red);\n            red = clr.r;\n            green = clr.g;\n            blue = clr.b;\n        }\n        if (red > 1 || green > 1 || blue > 1) {\n            red /= 255;\n            green /= 255;\n            blue /= 255;\n        }\n        var max = mmax(red, green, blue),\n            min = mmin(red, green, blue),\n            h,\n            s,\n            l = (max + min) / 2,\n            hsl;\n        if (min == max) {\n            hsl =  {h: 0, s: 0, l: l};\n        } else {\n            var delta = max - min;\n            s = l < .5 ? delta / (max + min) : delta / (2 - max - min);\n            if (red == max) {\n                h = (green - blue) / delta;\n            } else if (green == max) {\n                h = 2 + (blue - red) / delta;\n            } else {\n                h = 4 + (red - green) / delta;\n            }\n            h /= 6;\n            h < 0 && h++;\n            h > 1 && h--;\n            hsl = {h: h, s: s, l: l};\n        }\n        hsl.toString = hsltoString;\n        return hsl;\n    };\n    R._path2string = function () {\n        return this.join(\",\")[rp](p2s, \"$1\");\n    };\n    function cacher(f, scope, postprocessor) {\n        function newf() {\n            var arg = Array[proto].slice.call(arguments, 0),\n                args = arg[join](\"\\u25ba\"),\n                cache = newf.cache = newf.cache || {},\n                count = newf.count = newf.count || [];\n            if (cache[has](args)) {\n                return postprocessor ? postprocessor(cache[args]) : cache[args];\n            }\n            count[length] >= 1e3 && delete cache[count.shift()];\n            count[push](args);\n            cache[args] = f[apply](scope, arg);\n            return postprocessor ? postprocessor(cache[args]) : cache[args];\n        }\n        return newf;\n    }\n \n    R.getRGB = cacher(function (colour) {\n        if (!colour || !!((colour = Str(colour)).indexOf(\"-\") + 1)) {\n            return {r: -1, g: -1, b: -1, hex: \"none\", error: 1};\n        }\n        if (colour == \"none\") {\n            return {r: -1, g: -1, b: -1, hex: \"none\"};\n        }\n        !(hsrg[has](colour.toLowerCase().substring(0, 2)) || colour.charAt() == \"#\") && (colour = toHex(colour));\n        var res,\n            red,\n            green,\n            blue,\n            opacity,\n            t,\n            values,\n            rgb = colour.match(colourRegExp);\n        if (rgb) {\n            if (rgb[2]) {\n                blue = toInt(rgb[2].substring(5), 16);\n                green = toInt(rgb[2].substring(3, 5), 16);\n                red = toInt(rgb[2].substring(1, 3), 16);\n            }\n            if (rgb[3]) {\n                blue = toInt((t = rgb[3].charAt(3)) + t, 16);\n                green = toInt((t = rgb[3].charAt(2)) + t, 16);\n                red = toInt((t = rgb[3].charAt(1)) + t, 16);\n            }\n            if (rgb[4]) {\n                values = rgb[4][split](commaSpaces);\n                red = toFloat(values[0]);\n                values[0].slice(-1) == \"%\" && (red *= 2.55);\n                green = toFloat(values[1]);\n                values[1].slice(-1) == \"%\" && (green *= 2.55);\n                blue = toFloat(values[2]);\n                values[2].slice(-1) == \"%\" && (blue *= 2.55);\n                rgb[1].toLowerCase().slice(0, 4) == \"rgba\" && (opacity = toFloat(values[3]));\n                values[3] && values[3].slice(-1) == \"%\" && (opacity /= 100);\n            }\n            if (rgb[5]) {\n                values = rgb[5][split](commaSpaces);\n                red = toFloat(values[0]);\n                values[0].slice(-1) == \"%\" && (red *= 2.55);\n                green = toFloat(values[1]);\n                values[1].slice(-1) == \"%\" && (green *= 2.55);\n                blue = toFloat(values[2]);\n                values[2].slice(-1) == \"%\" && (blue *= 2.55);\n                (values[0].slice(-3) == \"deg\" || values[0].slice(-1) == \"\\xb0\") && (red /= 360);\n                rgb[1].toLowerCase().slice(0, 4) == \"hsba\" && (opacity = toFloat(values[3]));\n                values[3] && values[3].slice(-1) == \"%\" && (opacity /= 100);\n                return R.hsb2rgb(red, green, blue, opacity);\n            }\n            if (rgb[6]) {\n                values = rgb[6][split](commaSpaces);\n                red = toFloat(values[0]);\n                values[0].slice(-1) == \"%\" && (red *= 2.55);\n                green = toFloat(values[1]);\n                values[1].slice(-1) == \"%\" && (green *= 2.55);\n                blue = toFloat(values[2]);\n                values[2].slice(-1) == \"%\" && (blue *= 2.55);\n                (values[0].slice(-3) == \"deg\" || values[0].slice(-1) == \"\\xb0\") && (red /= 360);\n                rgb[1].toLowerCase().slice(0, 4) == \"hsla\" && (opacity = toFloat(values[3]));\n                values[3] && values[3].slice(-1) == \"%\" && (opacity /= 100);\n                return R.hsl2rgb(red, green, blue, opacity);\n            }\n            rgb = {r: red, g: green, b: blue};\n            rgb.hex = \"#\" + (16777216 | blue | (green << 8) | (red << 16)).toString(16).slice(1);\n            R.is(opacity, \"finite\") && (rgb.opacity = opacity);\n            return rgb;\n        }\n        return {r: -1, g: -1, b: -1, hex: \"none\", error: 1};\n    }, R);\n    R.getColor = function (value) {\n        var start = this.getColor.start = this.getColor.start || {h: 0, s: 1, b: value || .75},\n            rgb = this.hsb2rgb(start.h, start.s, start.b);\n        start.h += .075;\n        if (start.h > 1) {\n            start.h = 0;\n            start.s -= .2;\n            start.s <= 0 && (this.getColor.start = {h: 0, s: 1, b: start.b});\n        }\n        return rgb.hex;\n    };\n    R.getColor.reset = function () {\n        delete this.start;\n    };\n    // path utilities\n    R.parsePathString = cacher(function (pathString) {\n        if (!pathString) {\n            return null;\n        }\n        var paramCounts = {a: 7, c: 6, h: 1, l: 2, m: 2, q: 4, s: 4, t: 2, v: 1, z: 0},\n            data = [];\n        if (R.is(pathString, array) && R.is(pathString[0], array)) { // rough assumption\n            data = pathClone(pathString);\n        }\n        if (!data[length]) {\n            Str(pathString)[rp](pathCommand, function (a, b, c) {\n                var params = [],\n                    name = lowerCase.call(b);\n                c[rp](pathValues, function (a, b) {\n                    b && params[push](+b);\n                });\n                if (name == \"m\" && params[length] > 2) {\n                    data[push]([b][concat](params.splice(0, 2)));\n                    name = \"l\";\n                    b = b == \"m\" ? \"l\" : \"L\";\n                }\n                while (params[length] >= paramCounts[name]) {\n                    data[push]([b][concat](params.splice(0, paramCounts[name])));\n                    if (!paramCounts[name]) {\n                        break;\n                    }\n                }\n            });\n        }\n        data[toString] = R._path2string;\n        return data;\n    });\n    R.findDotsAtSegment = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) {\n        var t1 = 1 - t,\n            x = pow(t1, 3) * p1x + pow(t1, 2) * 3 * t * c1x + t1 * 3 * t * t * c2x + pow(t, 3) * p2x,\n            y = pow(t1, 3) * p1y + pow(t1, 2) * 3 * t * c1y + t1 * 3 * t * t * c2y + pow(t, 3) * p2y,\n            mx = p1x + 2 * t * (c1x - p1x) + t * t * (c2x - 2 * c1x + p1x),\n            my = p1y + 2 * t * (c1y - p1y) + t * t * (c2y - 2 * c1y + p1y),\n            nx = c1x + 2 * t * (c2x - c1x) + t * t * (p2x - 2 * c2x + c1x),\n            ny = c1y + 2 * t * (c2y - c1y) + t * t * (p2y - 2 * c2y + c1y),\n            ax = (1 - t) * p1x + t * c1x,\n            ay = (1 - t) * p1y + t * c1y,\n            cx = (1 - t) * c2x + t * p2x,\n            cy = (1 - t) * c2y + t * p2y,\n            alpha = (90 - math.atan((mx - nx) / (my - ny)) * 180 / PI);\n        (mx > nx || my < ny) && (alpha += 180);\n        return {x: x, y: y, m: {x: mx, y: my}, n: {x: nx, y: ny}, start: {x: ax, y: ay}, end: {x: cx, y: cy}, alpha: alpha};\n    };\n    var pathDimensions = cacher(function (path) {\n        if (!path) {\n            return {x: 0, y: 0, width: 0, height: 0};\n        }\n        path = path2curve(path);\n        var x = 0, \n            y = 0,\n            X = [],\n            Y = [],\n            p;\n        for (var i = 0, ii = path[length]; i < ii; i++) {\n            p = path[i];\n            if (p[0] == \"M\") {\n                x = p[1];\n                y = p[2];\n                X[push](x);\n                Y[push](y);\n            } else {\n                var dim = curveDim(x, y, p[1], p[2], p[3], p[4], p[5], p[6]);\n                X = X[concat](dim.min.x, dim.max.x);\n                Y = Y[concat](dim.min.y, dim.max.y);\n                x = p[5];\n                y = p[6];\n            }\n        }\n        var xmin = mmin[apply](0, X),\n            ymin = mmin[apply](0, Y);\n        return {\n            x: xmin,\n            y: ymin,\n            width: mmax[apply](0, X) - xmin,\n            height: mmax[apply](0, Y) - ymin\n        };\n    }),\n        pathClone = function (pathArray) {\n            var res = [];\n            if (!R.is(pathArray, array) || !R.is(pathArray && pathArray[0], array)) { // rough assumption\n                pathArray = R.parsePathString(pathArray);\n            }\n            for (var i = 0, ii = pathArray[length]; i < ii; i++) {\n                res[i] = [];\n                for (var j = 0, jj = pathArray[i][length]; j < jj; j++) {\n                    res[i][j] = pathArray[i][j];\n                }\n            }\n            res[toString] = R._path2string;\n            return res;\n        },\n        pathToRelative = cacher(function (pathArray) {\n            if (!R.is(pathArray, array) || !R.is(pathArray && pathArray[0], array)) { // rough assumption\n                pathArray = R.parsePathString(pathArray);\n            }\n            var res = [],\n                x = 0,\n                y = 0,\n                mx = 0,\n                my = 0,\n                start = 0;\n            if (pathArray[0][0] == \"M\") {\n                x = pathArray[0][1];\n                y = pathArray[0][2];\n                mx = x;\n                my = y;\n                start++;\n                res[push]([\"M\", x, y]);\n            }\n            for (var i = start, ii = pathArray[length]; i < ii; i++) {\n                var r = res[i] = [],\n                    pa = pathArray[i];\n                if (pa[0] != lowerCase.call(pa[0])) {\n                    r[0] = lowerCase.call(pa[0]);\n                    switch (r[0]) {\n                        case \"a\":\n                            r[1] = pa[1];\n                            r[2] = pa[2];\n                            r[3] = pa[3];\n                            r[4] = pa[4];\n                            r[5] = pa[5];\n                            r[6] = +(pa[6] - x).toFixed(3);\n                            r[7] = +(pa[7] - y).toFixed(3);\n                            break;\n                        case \"v\":\n                            r[1] = +(pa[1] - y).toFixed(3);\n                            break;\n                        case \"m\":\n                            mx = pa[1];\n                            my = pa[2];\n                        default:\n                            for (var j = 1, jj = pa[length]; j < jj; j++) {\n                                r[j] = +(pa[j] - ((j % 2) ? x : y)).toFixed(3);\n                            }\n                    }\n                } else {\n                    r = res[i] = [];\n                    if (pa[0] == \"m\") {\n                        mx = pa[1] + x;\n                        my = pa[2] + y;\n                    }\n                    for (var k = 0, kk = pa[length]; k < kk; k++) {\n                        res[i][k] = pa[k];\n                    }\n                }\n                var len = res[i][length];\n                switch (res[i][0]) {\n                    case \"z\":\n                        x = mx;\n                        y = my;\n                        break;\n                    case \"h\":\n                        x += +res[i][len - 1];\n                        break;\n                    case \"v\":\n                        y += +res[i][len - 1];\n                        break;\n                    default:\n                        x += +res[i][len - 2];\n                        y += +res[i][len - 1];\n                }\n            }\n            res[toString] = R._path2string;\n            return res;\n        }, 0, pathClone),\n        pathToAbsolute = cacher(function (pathArray) {\n            if (!R.is(pathArray, array) || !R.is(pathArray && pathArray[0], array)) { // rough assumption\n                pathArray = R.parsePathString(pathArray);\n            }\n            var res = [],\n                x = 0,\n                y = 0,\n                mx = 0,\n                my = 0,\n                start = 0;\n            if (pathArray[0][0] == \"M\") {\n                x = +pathArray[0][1];\n                y = +pathArray[0][2];\n                mx = x;\n                my = y;\n                start++;\n                res[0] = [\"M\", x, y];\n            }\n            for (var i = start, ii = pathArray[length]; i < ii; i++) {\n                var r = res[i] = [],\n                    pa = pathArray[i];\n                if (pa[0] != upperCase.call(pa[0])) {\n                    r[0] = upperCase.call(pa[0]);\n                    switch (r[0]) {\n                        case \"A\":\n                            r[1] = pa[1];\n                            r[2] = pa[2];\n                            r[3] = pa[3];\n                            r[4] = pa[4];\n                            r[5] = pa[5];\n                            r[6] = +(pa[6] + x);\n                            r[7] = +(pa[7] + y);\n                            break;\n                        case \"V\":\n                            r[1] = +pa[1] + y;\n                            break;\n                        case \"H\":\n                            r[1] = +pa[1] + x;\n                            break;\n                        case \"M\":\n                            mx = +pa[1] + x;\n                            my = +pa[2] + y;\n                        default:\n                            for (var j = 1, jj = pa[length]; j < jj; j++) {\n                                r[j] = +pa[j] + ((j % 2) ? x : y);\n                            }\n                    }\n                } else {\n                    for (var k = 0, kk = pa[length]; k < kk; k++) {\n                        res[i][k] = pa[k];\n                    }\n                }\n                switch (r[0]) {\n                    case \"Z\":\n                        x = mx;\n                        y = my;\n                        break;\n                    case \"H\":\n                        x = r[1];\n                        break;\n                    case \"V\":\n                        y = r[1];\n                        break;\n                    case \"M\":\n                        mx = res[i][res[i][length] - 2];\n                        my = res[i][res[i][length] - 1];\n                    default:\n                        x = res[i][res[i][length] - 2];\n                        y = res[i][res[i][length] - 1];\n                }\n            }\n            res[toString] = R._path2string;\n            return res;\n        }, null, pathClone),\n        l2c = function (x1, y1, x2, y2) {\n            return [x1, y1, x2, y2, x2, y2];\n        },\n        q2c = function (x1, y1, ax, ay, x2, y2) {\n            var _13 = 1 / 3,\n                _23 = 2 / 3;\n            return [\n                    _13 * x1 + _23 * ax,\n                    _13 * y1 + _23 * ay,\n                    _13 * x2 + _23 * ax,\n                    _13 * y2 + _23 * ay,\n                    x2,\n                    y2\n                ];\n        },\n        a2c = function (x1, y1, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2, recursive) {\n            // for more information of where this math came from visit:\n            // http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes\n            var _120 = PI * 120 / 180,\n                rad = PI / 180 * (+angle || 0),\n                res = [],\n                xy,\n                rotate = cacher(function (x, y, rad) {\n                    var X = x * math.cos(rad) - y * math.sin(rad),\n                        Y = x * math.sin(rad) + y * math.cos(rad);\n                    return {x: X, y: Y};\n                });\n            if (!recursive) {\n                xy = rotate(x1, y1, -rad);\n                x1 = xy.x;\n                y1 = xy.y;\n                xy = rotate(x2, y2, -rad);\n                x2 = xy.x;\n                y2 = xy.y;\n                var cos = math.cos(PI / 180 * angle),\n                    sin = math.sin(PI / 180 * angle),\n                    x = (x1 - x2) / 2,\n                    y = (y1 - y2) / 2;\n                var h = (x * x) / (rx * rx) + (y * y) / (ry * ry);\n                if (h > 1) {\n                    h = math.sqrt(h);\n                    rx = h * rx;\n                    ry = h * ry;\n                }\n                var rx2 = rx * rx,\n                    ry2 = ry * ry,\n                    k = (large_arc_flag == sweep_flag ? -1 : 1) *\n                        math.sqrt(abs((rx2 * ry2 - rx2 * y * y - ry2 * x * x) / (rx2 * y * y + ry2 * x * x))),\n                    cx = k * rx * y / ry + (x1 + x2) / 2,\n                    cy = k * -ry * x / rx + (y1 + y2) / 2,\n                    f1 = math.asin(((y1 - cy) / ry).toFixed(9)),\n                    f2 = math.asin(((y2 - cy) / ry).toFixed(9));\n\n                f1 = x1 < cx ? PI - f1 : f1;\n                f2 = x2 < cx ? PI - f2 : f2;\n                f1 < 0 && (f1 = PI * 2 + f1);\n                f2 < 0 && (f2 = PI * 2 + f2);\n                if (sweep_flag && f1 > f2) {\n                    f1 = f1 - PI * 2;\n                }\n                if (!sweep_flag && f2 > f1) {\n                    f2 = f2 - PI * 2;\n                }\n            } else {\n                f1 = recursive[0];\n                f2 = recursive[1];\n                cx = recursive[2];\n                cy = recursive[3];\n            }\n            var df = f2 - f1;\n            if (abs(df) > _120) {\n                var f2old = f2,\n                    x2old = x2,\n                    y2old = y2;\n                f2 = f1 + _120 * (sweep_flag && f2 > f1 ? 1 : -1);\n                x2 = cx + rx * math.cos(f2);\n                y2 = cy + ry * math.sin(f2);\n                res = a2c(x2, y2, rx, ry, angle, 0, sweep_flag, x2old, y2old, [f2, f2old, cx, cy]);\n            }\n            df = f2 - f1;\n            var c1 = math.cos(f1),\n                s1 = math.sin(f1),\n                c2 = math.cos(f2),\n                s2 = math.sin(f2),\n                t = math.tan(df / 4),\n                hx = 4 / 3 * rx * t,\n                hy = 4 / 3 * ry * t,\n                m1 = [x1, y1],\n                m2 = [x1 + hx * s1, y1 - hy * c1],\n                m3 = [x2 + hx * s2, y2 - hy * c2],\n                m4 = [x2, y2];\n            m2[0] = 2 * m1[0] - m2[0];\n            m2[1] = 2 * m1[1] - m2[1];\n            if (recursive) {\n                return [m2, m3, m4][concat](res);\n            } else {\n                res = [m2, m3, m4][concat](res)[join]()[split](\",\");\n                var newres = [];\n                for (var i = 0, ii = res[length]; i < ii; i++) {\n                    newres[i] = i % 2 ? rotate(res[i - 1], res[i], rad).y : rotate(res[i], res[i + 1], rad).x;\n                }\n                return newres;\n            }\n        },\n        findDotAtSegment = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) {\n            var t1 = 1 - t;\n            return {\n                x: pow(t1, 3) * p1x + pow(t1, 2) * 3 * t * c1x + t1 * 3 * t * t * c2x + pow(t, 3) * p2x,\n                y: pow(t1, 3) * p1y + pow(t1, 2) * 3 * t * c1y + t1 * 3 * t * t * c2y + pow(t, 3) * p2y\n            };\n        },\n        curveDim = cacher(function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y) {\n            var a = (c2x - 2 * c1x + p1x) - (p2x - 2 * c2x + c1x),\n                b = 2 * (c1x - p1x) - 2 * (c2x - c1x),\n                c = p1x - c1x,\n                t1 = (-b + math.sqrt(b * b - 4 * a * c)) / 2 / a,\n                t2 = (-b - math.sqrt(b * b - 4 * a * c)) / 2 / a,\n                y = [p1y, p2y],\n                x = [p1x, p2x],\n                dot;\n            abs(t1) > \"1e12\" && (t1 = .5);\n            abs(t2) > \"1e12\" && (t2 = .5);\n            if (t1 > 0 && t1 < 1) {\n                dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t1);\n                x[push](dot.x);\n                y[push](dot.y);\n            }\n            if (t2 > 0 && t2 < 1) {\n                dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t2);\n                x[push](dot.x);\n                y[push](dot.y);\n            }\n            a = (c2y - 2 * c1y + p1y) - (p2y - 2 * c2y + c1y);\n            b = 2 * (c1y - p1y) - 2 * (c2y - c1y);\n            c = p1y - c1y;\n            t1 = (-b + math.sqrt(b * b - 4 * a * c)) / 2 / a;\n            t2 = (-b - math.sqrt(b * b - 4 * a * c)) / 2 / a;\n            abs(t1) > \"1e12\" && (t1 = .5);\n            abs(t2) > \"1e12\" && (t2 = .5);\n            if (t1 > 0 && t1 < 1) {\n                dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t1);\n                x[push](dot.x);\n                y[push](dot.y);\n            }\n            if (t2 > 0 && t2 < 1) {\n                dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t2);\n                x[push](dot.x);\n                y[push](dot.y);\n            }\n            return {\n                min: {x: mmin[apply](0, x), y: mmin[apply](0, y)},\n                max: {x: mmax[apply](0, x), y: mmax[apply](0, y)}\n            };\n        }),\n        path2curve = cacher(function (path, path2) {\n            var p = pathToAbsolute(path),\n                p2 = path2 && pathToAbsolute(path2),\n                attrs = {x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null},\n                attrs2 = {x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null},\n                processPath = function (path, d) {\n                    var nx, ny;\n                    if (!path) {\n                        return [\"C\", d.x, d.y, d.x, d.y, d.x, d.y];\n                    }\n                    !(path[0] in {T:1, Q:1}) && (d.qx = d.qy = null);\n                    switch (path[0]) {\n                        case \"M\":\n                            d.X = path[1];\n                            d.Y = path[2];\n                            break;\n                        case \"A\":\n                            path = [\"C\"][concat](a2c[apply](0, [d.x, d.y][concat](path.slice(1))));\n                            break;\n                        case \"S\":\n                            nx = d.x + (d.x - (d.bx || d.x));\n                            ny = d.y + (d.y - (d.by || d.y));\n                            path = [\"C\", nx, ny][concat](path.slice(1));\n                            break;\n                        case \"T\":\n                            d.qx = d.x + (d.x - (d.qx || d.x));\n                            d.qy = d.y + (d.y - (d.qy || d.y));\n                            path = [\"C\"][concat](q2c(d.x, d.y, d.qx, d.qy, path[1], path[2]));\n                            break;\n                        case \"Q\":\n                            d.qx = path[1];\n                            d.qy = path[2];\n                            path = [\"C\"][concat](q2c(d.x, d.y, path[1], path[2], path[3], path[4]));\n                            break;\n                        case \"L\":\n                            path = [\"C\"][concat](l2c(d.x, d.y, path[1], path[2]));\n                            break;\n                        case \"H\":\n                            path = [\"C\"][concat](l2c(d.x, d.y, path[1], d.y));\n                            break;\n                        case \"V\":\n                            path = [\"C\"][concat](l2c(d.x, d.y, d.x, path[1]));\n                            break;\n                        case \"Z\":\n                            path = [\"C\"][concat](l2c(d.x, d.y, d.X, d.Y));\n                            break;\n                    }\n                    return path;\n                },\n                fixArc = function (pp, i) {\n                    if (pp[i][length] > 7) {\n                        pp[i].shift();\n                        var pi = pp[i];\n                        while (pi[length]) {\n                            pp.splice(i++, 0, [\"C\"][concat](pi.splice(0, 6)));\n                        }\n                        pp.splice(i, 1);\n                        ii = mmax(p[length], p2 && p2[length] || 0);\n                    }\n                },\n                fixM = function (path1, path2, a1, a2, i) {\n                    if (path1 && path2 && path1[i][0] == \"M\" && path2[i][0] != \"M\") {\n                        path2.splice(i, 0, [\"M\", a2.x, a2.y]);\n                        a1.bx = 0;\n                        a1.by = 0;\n                        a1.x = path1[i][1];\n                        a1.y = path1[i][2];\n                        ii = mmax(p[length], p2 && p2[length] || 0);\n                    }\n                };\n            for (var i = 0, ii = mmax(p[length], p2 && p2[length] || 0); i < ii; i++) {\n                p[i] = processPath(p[i], attrs);\n                fixArc(p, i);\n                p2 && (p2[i] = processPath(p2[i], attrs2));\n                p2 && fixArc(p2, i);\n                fixM(p, p2, attrs, attrs2, i);\n                fixM(p2, p, attrs2, attrs, i);\n                var seg = p[i],\n                    seg2 = p2 && p2[i],\n                    seglen = seg[length],\n                    seg2len = p2 && seg2[length];\n                attrs.x = seg[seglen - 2];\n                attrs.y = seg[seglen - 1];\n                attrs.bx = toFloat(seg[seglen - 4]) || attrs.x;\n                attrs.by = toFloat(seg[seglen - 3]) || attrs.y;\n                attrs2.bx = p2 && (toFloat(seg2[seg2len - 4]) || attrs2.x);\n                attrs2.by = p2 && (toFloat(seg2[seg2len - 3]) || attrs2.y);\n                attrs2.x = p2 && seg2[seg2len - 2];\n                attrs2.y = p2 && seg2[seg2len - 1];\n            }\n            return p2 ? [p, p2] : p;\n        }, null, pathClone),\n        parseDots = cacher(function (gradient) {\n            var dots = [];\n            for (var i = 0, ii = gradient[length]; i < ii; i++) {\n                var dot = {},\n                    par = gradient[i].match(/^([^:]*):?([\\d\\.]*)/);\n                dot.color = R.getRGB(par[1]);\n                if (dot.color.error) {\n                    return null;\n                }\n                dot.color = dot.color.hex;\n                par[2] && (dot.offset = par[2] + \"%\");\n                dots[push](dot);\n            }\n            for (i = 1, ii = dots[length] - 1; i < ii; i++) {\n                if (!dots[i].offset) {\n                    var start = toFloat(dots[i - 1].offset || 0),\n                        end = 0;\n                    for (var j = i + 1; j < ii; j++) {\n                        if (dots[j].offset) {\n                            end = dots[j].offset;\n                            break;\n                        }\n                    }\n                    if (!end) {\n                        end = 100;\n                        j = ii;\n                    }\n                    end = toFloat(end);\n                    var d = (end - start) / (j - i + 1);\n                    for (; i < j; i++) {\n                        start += d;\n                        dots[i].offset = start + \"%\";\n                    }\n                }\n            }\n            return dots;\n        }),\n        getContainer = function (x, y, w, h) {\n            var container;\n            if (R.is(x, string) || R.is(x, \"object\")) {\n                container = R.is(x, string) ? doc.getElementById(x) : x;\n                if (container.tagName) {\n                    if (y == null) {\n                        return {\n                            container: container,\n                            width: container.style.pixelWidth || container.offsetWidth,\n                            height: container.style.pixelHeight || container.offsetHeight\n                        };\n                    } else {\n                        return {container: container, width: y, height: w};\n                    }\n                }\n            } else {\n                return {container: 1, x: x, y: y, width: w, height: h};\n            }\n        },\n        plugins = function (con, add) {\n            var that = this;\n            for (var prop in add) {\n                if (add[has](prop) && !(prop in con)) {\n                    switch (typeof add[prop]) {\n                        case \"function\":\n                            (function (f) {\n                                con[prop] = con === that ? f : function () { return f[apply](that, arguments); };\n                            })(add[prop]);\n                        break;\n                        case \"object\":\n                            con[prop] = con[prop] || {};\n                            plugins.call(this, con[prop], add[prop]);\n                        break;\n                        default:\n                            con[prop] = add[prop];\n                        break;\n                    }\n                }\n            }\n        },\n        tear = function (el, paper) {\n            el == paper.top && (paper.top = el.prev);\n            el == paper.bottom && (paper.bottom = el.next);\n            el.next && (el.next.prev = el.prev);\n            el.prev && (el.prev.next = el.next);\n        },\n        tofront = function (el, paper) {\n            if (paper.top === el) {\n                return;\n            }\n            tear(el, paper);\n            el.next = null;\n            el.prev = paper.top;\n            paper.top.next = el;\n            paper.top = el;\n        },\n        toback = function (el, paper) {\n            if (paper.bottom === el) {\n                return;\n            }\n            tear(el, paper);\n            el.next = paper.bottom;\n            el.prev = null;\n            paper.bottom.prev = el;\n            paper.bottom = el;\n        },\n        insertafter = function (el, el2, paper) {\n            tear(el, paper);\n            el2 == paper.top && (paper.top = el);\n            el2.next && (el2.next.prev = el);\n            el.next = el2.next;\n            el.prev = el2;\n            el2.next = el;\n        },\n        insertbefore = function (el, el2, paper) {\n            tear(el, paper);\n            el2 == paper.bottom && (paper.bottom = el);\n            el2.prev && (el2.prev.next = el);\n            el.prev = el2.prev;\n            el2.prev = el;\n            el.next = el2;\n        },\n        removed = function (methodname) {\n            return function () {\n                throw new Error(\"Rapha\\xebl: you are calling to method \\u201c\" + methodname + \"\\u201d of removed object\");\n            };\n        };\n    R.pathToRelative = pathToRelative;\n    // SVG\n    if (R.svg) {\n        paperproto.svgns = \"http://www.w3.org/2000/svg\";\n        paperproto.xlink = \"http://www.w3.org/1999/xlink\";\n        round = function (num) {\n            return +num + (~~num === num) * .5;\n        };\n        var $ = function (el, attr) {\n            if (attr) {\n                for (var key in attr) {\n                    if (attr[has](key)) {\n                        el[setAttribute](key, Str(attr[key]));\n                    }\n                }\n            } else {\n                el = doc.createElementNS(paperproto.svgns, el);\n                el.style.webkitTapHighlightColor = \"rgba(0,0,0,0)\";\n                return el;\n            }\n        };\n        R[toString] = function () {\n            return  \"Your browser supports SVG.\\nYou are running Rapha\\xebl \" + this.version;\n        };\n        var thePath = function (pathString, SVG) {\n            var el = $(\"path\");\n            SVG.canvas && SVG.canvas[appendChild](el);\n            var p = new Element(el, SVG);\n            p.type = \"path\";\n            setFillAndStroke(p, {fill: \"none\", stroke: \"#000\", path: pathString});\n            return p;\n        };\n        var addGradientFill = function (o, gradient, SVG) {\n            var type = \"linear\",\n                fx = .5, fy = .5,\n                s = o.style;\n            gradient = Str(gradient)[rp](radial_gradient, function (all, _fx, _fy) {\n                type = \"radial\";\n                if (_fx && _fy) {\n                    fx = toFloat(_fx);\n                    fy = toFloat(_fy);\n                    var dir = ((fy > .5) * 2 - 1);\n                    pow(fx - .5, 2) + pow(fy - .5, 2) > .25 &&\n                        (fy = math.sqrt(.25 - pow(fx - .5, 2)) * dir + .5) &&\n                        fy != .5 &&\n                        (fy = fy.toFixed(5) - 1e-5 * dir);\n                }\n                return E;\n            });\n            gradient = gradient[split](/\\s*\\-\\s*/);\n            if (type == \"linear\") {\n                var angle = gradient.shift();\n                angle = -toFloat(angle);\n                if (isNaN(angle)) {\n                    return null;\n                }\n                var vector = [0, 0, math.cos(angle * PI / 180), math.sin(angle * PI / 180)],\n                    max = 1 / (mmax(abs(vector[2]), abs(vector[3])) || 1);\n                vector[2] *= max;\n                vector[3] *= max;\n                if (vector[2] < 0) {\n                    vector[0] = -vector[2];\n                    vector[2] = 0;\n                }\n                if (vector[3] < 0) {\n                    vector[1] = -vector[3];\n                    vector[3] = 0;\n                }\n            }\n            var dots = parseDots(gradient);\n            if (!dots) {\n                return null;\n            }\n            var id = o.getAttribute(fillString);\n            id = id.match(/^url\\(#(.*)\\)$/);\n            id && SVG.defs.removeChild(doc.getElementById(id[1]));\n\n            var el = $(type + \"Gradient\");\n            el.id = createUUID();\n            $(el, type == \"radial\" ? {fx: fx, fy: fy} : {x1: vector[0], y1: vector[1], x2: vector[2], y2: vector[3]});\n            SVG.defs[appendChild](el);\n            for (var i = 0, ii = dots[length]; i < ii; i++) {\n                var stop = $(\"stop\");\n                $(stop, {\n                    offset: dots[i].offset ? dots[i].offset : !i ? \"0%\" : \"100%\",\n                    \"stop-color\": dots[i].color || \"#fff\"\n                });\n                el[appendChild](stop);\n            }\n            $(o, {\n                fill: \"url(#\" + el.id + \")\",\n                opacity: 1,\n                \"fill-opacity\": 1\n            });\n            s.fill = E;\n            s.opacity = 1;\n            s.fillOpacity = 1;\n            return 1;\n        };\n        var updatePosition = function (o) {\n            var bbox = o.getBBox();\n            $(o.pattern, {patternTransform: R.format(\"translate({0},{1})\", bbox.x, bbox.y)});\n        };\n        var setFillAndStroke = function (o, params) {\n            var dasharray = {\n                    \"\": [0],\n                    \"none\": [0],\n                    \"-\": [3, 1],\n                    \".\": [1, 1],\n                    \"-.\": [3, 1, 1, 1],\n                    \"-..\": [3, 1, 1, 1, 1, 1],\n                    \". \": [1, 3],\n                    \"- \": [4, 3],\n                    \"--\": [8, 3],\n                    \"- .\": [4, 3, 1, 3],\n                    \"--.\": [8, 3, 1, 3],\n                    \"--..\": [8, 3, 1, 3, 1, 3]\n                },\n                node = o.node,\n                attrs = o.attrs,\n                rot = o.rotate(),\n                addDashes = function (o, value) {\n                    value = dasharray[lowerCase.call(value)];\n                    if (value) {\n                        var width = o.attrs[\"stroke-width\"] || \"1\",\n                            butt = {round: width, square: width, butt: 0}[o.attrs[\"stroke-linecap\"] || params[\"stroke-linecap\"]] || 0,\n                            dashes = [];\n                        var i = value[length];\n                        while (i--) {\n                            dashes[i] = value[i] * width + ((i % 2) ? 1 : -1) * butt;\n                        }\n                        $(node, {\"stroke-dasharray\": dashes[join](\",\")});\n                    }\n                };\n            params[has](\"rotation\") && (rot = params.rotation);\n            var rotxy = Str(rot)[split](separator);\n            if (!(rotxy.length - 1)) {\n                rotxy = null;\n            } else {\n                rotxy[1] = +rotxy[1];\n                rotxy[2] = +rotxy[2];\n            }\n            toFloat(rot) && o.rotate(0, true);\n            for (var att in params) {\n                if (params[has](att)) {\n                    if (!availableAttrs[has](att)) {\n                        continue;\n                    }\n                    var value = params[att];\n                    attrs[att] = value;\n                    switch (att) {\n                        case \"blur\":\n                            o.blur(value);\n                            break;\n                        case \"rotation\":\n                            o.rotate(value, true);\n                            break;\n                        case \"href\":\n                        case \"title\":\n                        case \"target\":\n                            var pn = node.parentNode;\n                            if (lowerCase.call(pn.tagName) != \"a\") {\n                                var hl = $(\"a\");\n                                pn.insertBefore(hl, node);\n                                hl[appendChild](node);\n                                pn = hl;\n                            }\n                            if (att == \"target\" && value == \"blank\") {\n                                pn.setAttributeNS(o.paper.xlink, \"show\", \"new\");\n                            } else {\n                                pn.setAttributeNS(o.paper.xlink, att, value);\n                            }\n                            break;\n                        case \"cursor\":\n                            node.style.cursor = value;\n                            break;\n                        case \"clip-rect\":\n                            var rect = Str(value)[split](separator);\n                            if (rect[length] == 4) {\n                                o.clip && o.clip.parentNode.parentNode.removeChild(o.clip.parentNode);\n                                var el = $(\"clipPath\"),\n                                    rc = $(\"rect\");\n                                el.id = createUUID();\n                                $(rc, {\n                                    x: rect[0],\n                                    y: rect[1],\n                                    width: rect[2],\n                                    height: rect[3]\n                                });\n                                el[appendChild](rc);\n                                o.paper.defs[appendChild](el);\n                                $(node, {\"clip-path\": \"url(#\" + el.id + \")\"});\n                                o.clip = rc;\n                            }\n                            if (!value) {\n                                var clip = doc.getElementById(node.getAttribute(\"clip-path\")[rp](/(^url\\(#|\\)$)/g, E));\n                                clip && clip.parentNode.removeChild(clip);\n                                $(node, {\"clip-path\": E});\n                                delete o.clip;\n                            }\n                        break;\n                        case \"path\":\n                            if (o.type == \"path\") {\n                                $(node, {d: value ? attrs.path = pathToAbsolute(value) : \"M0,0\"});\n                            }\n                            break;\n                        case \"width\":\n                            node[setAttribute](att, value);\n                            if (attrs.fx) {\n                                att = \"x\";\n                                value = attrs.x;\n                            } else {\n                                break;\n                            }\n                        case \"x\":\n                            if (attrs.fx) {\n                                value = -attrs.x - (attrs.width || 0);\n                            }\n                        case \"rx\":\n                            if (att == \"rx\" && o.type == \"rect\") {\n                                break;\n                            }\n                        case \"cx\":\n                            rotxy && (att == \"x\" || att == \"cx\") && (rotxy[1] += value - attrs[att]);\n                            node[setAttribute](att, value);\n                            o.pattern && updatePosition(o);\n                            break;\n                        case \"height\":\n                            node[setAttribute](att, value);\n                            if (attrs.fy) {\n                                att = \"y\";\n                                value = attrs.y;\n                            } else {\n                                break;\n                            }\n                        case \"y\":\n                            if (attrs.fy) {\n                                value = -attrs.y - (attrs.height || 0);\n                            }\n                        case \"ry\":\n                            if (att == \"ry\" && o.type == \"rect\") {\n                                break;\n                            }\n                        case \"cy\":\n                            rotxy && (att == \"y\" || att == \"cy\") && (rotxy[2] += value - attrs[att]);\n                            node[setAttribute](att, value);\n                            o.pattern && updatePosition(o);\n                            break;\n                        case \"r\":\n                            if (o.type == \"rect\") {\n                                $(node, {rx: value, ry: value});\n                            } else {\n                                node[setAttribute](att, value);\n                            }\n                            break;\n                        case \"src\":\n                            if (o.type == \"image\") {\n                                node.setAttributeNS(o.paper.xlink, \"href\", value);\n                            }\n                            break;\n                        case \"stroke-width\":\n                            node.style.strokeWidth = value;\n                            // Need following line for Firefox\n                            node[setAttribute](att, value);\n                            if (attrs[\"stroke-dasharray\"]) {\n                                addDashes(o, attrs[\"stroke-dasharray\"]);\n                            }\n                            break;\n                        case \"stroke-dasharray\":\n                            addDashes(o, value);\n                            break;\n                        case \"translation\":\n                            var xy = Str(value)[split](separator);\n                            xy[0] = +xy[0] || 0;\n                            xy[1] = +xy[1] || 0;\n                            if (rotxy) {\n                                rotxy[1] += xy[0];\n                                rotxy[2] += xy[1];\n                            }\n                            translate.call(o, xy[0], xy[1]);\n                            break;\n                        case \"scale\":\n                            xy = Str(value)[split](separator);\n                            o.scale(+xy[0] || 1, +xy[1] || +xy[0] || 1, isNaN(toFloat(xy[2])) ? null : +xy[2], isNaN(toFloat(xy[3])) ? null : +xy[3]);\n                            break;\n                        case fillString:\n                            var isURL = Str(value).match(ISURL);\n                            if (isURL) {\n                                el = $(\"pattern\");\n                                var ig = $(\"image\");\n                                el.id = createUUID();\n                                $(el, {x: 0, y: 0, patternUnits: \"userSpaceOnUse\", height: 1, width: 1});\n                                $(ig, {x: 0, y: 0});\n                                ig.setAttributeNS(o.paper.xlink, \"href\", isURL[1]);\n                                el[appendChild](ig);\n \n                                var img = doc.createElement(\"img\");\n                                img.style.cssText = \"position:absolute;left:-9999em;top-9999em\";\n                                img.onload = function () {\n                                    $(el, {width: this.offsetWidth, height: this.offsetHeight});\n                                    $(ig, {width: this.offsetWidth, height: this.offsetHeight});\n                                    doc.body.removeChild(this);\n                                    o.paper.safari();\n                                };\n                                doc.body[appendChild](img);\n                                img.src = isURL[1];\n                                o.paper.defs[appendChild](el);\n                                node.style.fill = \"url(#\" + el.id + \")\";\n                                $(node, {fill: \"url(#\" + el.id + \")\"});\n                                o.pattern = el;\n                                o.pattern && updatePosition(o);\n                                break;\n                            }\n                            var clr = R.getRGB(value);\n                            if (!clr.error) {\n                                delete params.gradient;\n                                delete attrs.gradient;\n                                !R.is(attrs.opacity, \"undefined\") &&\n                                    R.is(params.opacity, \"undefined\") &&\n                                    $(node, {opacity: attrs.opacity});\n                                !R.is(attrs[\"fill-opacity\"], \"undefined\") &&\n                                    R.is(params[\"fill-opacity\"], \"undefined\") &&\n                                    $(node, {\"fill-opacity\": attrs[\"fill-opacity\"]});\n                            } else if ((({circle: 1, ellipse: 1})[has](o.type) || Str(value).charAt() != \"r\") && addGradientFill(node, value, o.paper)) {\n                                attrs.gradient = value;\n                                attrs.fill = \"none\";\n                                break;\n                            }\n                            clr[has](\"opacity\") && $(node, {\"fill-opacity\": clr.opacity > 1 ? clr.opacity / 100 : clr.opacity});\n                        case \"stroke\":\n                            clr = R.getRGB(value);\n                            node[setAttribute](att, clr.hex);\n                            att == \"stroke\" && clr[has](\"opacity\") && $(node, {\"stroke-opacity\": clr.opacity > 1 ? clr.opacity / 100 : clr.opacity});\n                            break;\n                        case \"gradient\":\n                            (({circle: 1, ellipse: 1})[has](o.type) || Str(value).charAt() != \"r\") && addGradientFill(node, value, o.paper);\n                            break;\n                        case \"opacity\":\n                            if (attrs.gradient && !attrs[has](\"stroke-opacity\")) {\n                                $(node, {\"stroke-opacity\": value > 1 ? value / 100 : value});\n                            }\n                            // fall\n                        case \"fill-opacity\":\n                            if (attrs.gradient) {\n                                var gradient = doc.getElementById(node.getAttribute(fillString)[rp](/^url\\(#|\\)$/g, E));\n                                if (gradient) {\n                                    var stops = gradient.getElementsByTagName(\"stop\");\n                                    stops[stops[length] - 1][setAttribute](\"stop-opacity\", value);\n                                }\n                                break;\n                            }\n                        default:\n                            att == \"font-size\" && (value = toInt(value, 10) + \"px\");\n                            var cssrule = att[rp](/(\\-.)/g, function (w) {\n                                return upperCase.call(w.substring(1));\n                            });\n                            node.style[cssrule] = value;\n                            // Need following line for Firefox\n                            node[setAttribute](att, value);\n                            break;\n                    }\n                }\n            }\n            \n            tuneText(o, params);\n            if (rotxy) {\n                o.rotate(rotxy.join(S));\n            } else {\n                toFloat(rot) && o.rotate(rot, true);\n            }\n        };\n        var leading = 1.2,\n        tuneText = function (el, params) {\n            if (el.type != \"text\" || !(params[has](\"text\") || params[has](\"font\") || params[has](\"font-size\") || params[has](\"x\") || params[has](\"y\"))) {\n                return;\n            }\n            var a = el.attrs,\n                node = el.node,\n                fontSize = node.firstChild ? toInt(doc.defaultView.getComputedStyle(node.firstChild, E).getPropertyValue(\"font-size\"), 10) : 10;\n \n            if (params[has](\"text\")) {\n                a.text = params.text;\n                while (node.firstChild) {\n                    node.removeChild(node.firstChild);\n                }\n                var texts = Str(params.text)[split](\"\\n\");\n                for (var i = 0, ii = texts[length]; i < ii; i++) if (texts[i]) {\n                    var tspan = $(\"tspan\");\n                    i && $(tspan, {dy: fontSize * leading, x: a.x});\n                    tspan[appendChild](doc.createTextNode(texts[i]));\n                    node[appendChild](tspan);\n                }\n            } else {\n                texts = node.getElementsByTagName(\"tspan\");\n                for (i = 0, ii = texts[length]; i < ii; i++) {\n                    i && $(texts[i], {dy: fontSize * leading, x: a.x});\n                }\n            }\n            $(node, {y: a.y});\n            var bb = el.getBBox(),\n                dif = a.y - (bb.y + bb.height / 2);\n            dif && R.is(dif, \"finite\") && $(node, {y: a.y + dif});\n        },\n        Element = function (node, svg) {\n            var X = 0,\n                Y = 0;\n            this[0] = node;\n            this.id = R._oid++;\n            this.node = node;\n            node.raphael = this;\n            this.paper = svg;\n            this.attrs = this.attrs || {};\n            this.transformations = []; // rotate, translate, scale\n            this._ = {\n                tx: 0,\n                ty: 0,\n                rt: {deg: 0, cx: 0, cy: 0},\n                sx: 1,\n                sy: 1\n            };\n            !svg.bottom && (svg.bottom = this);\n            this.prev = svg.top;\n            svg.top && (svg.top.next = this);\n            svg.top = this;\n            this.next = null;\n        };\n        var elproto = Element[proto];\n        Element[proto].rotate = function (deg, cx, cy) {\n            if (this.removed) {\n                return this;\n            }\n            if (deg == null) {\n                if (this._.rt.cx) {\n                    return [this._.rt.deg, this._.rt.cx, this._.rt.cy][join](S);\n                }\n                return this._.rt.deg;\n            }\n            var bbox = this.getBBox();\n            deg = Str(deg)[split](separator);\n            if (deg[length] - 1) {\n                cx = toFloat(deg[1]);\n                cy = toFloat(deg[2]);\n            }\n            deg = toFloat(deg[0]);\n            if (cx != null && cx !== false) {\n                this._.rt.deg = deg;\n            } else {\n                this._.rt.deg += deg;\n            }\n            (cy == null) && (cx = null);\n            this._.rt.cx = cx;\n            this._.rt.cy = cy;\n            cx = cx == null ? bbox.x + bbox.width / 2 : cx;\n            cy = cy == null ? bbox.y + bbox.height / 2 : cy;\n            if (this._.rt.deg) {\n                this.transformations[0] = R.format(\"rotate({0} {1} {2})\", this._.rt.deg, cx, cy);\n                this.clip && $(this.clip, {transform: R.format(\"rotate({0} {1} {2})\", -this._.rt.deg, cx, cy)});\n            } else {\n                this.transformations[0] = E;\n                this.clip && $(this.clip, {transform: E});\n            }\n            $(this.node, {transform: this.transformations[join](S)});\n            return this;\n        };\n        Element[proto].hide = function () {\n            !this.removed && (this.node.style.display = \"none\");\n            return this;\n        };\n        Element[proto].show = function () {\n            !this.removed && (this.node.style.display = \"\");\n            return this;\n        };\n        Element[proto].remove = function () {\n            if (this.removed) {\n                return;\n            }\n            tear(this, this.paper);\n            this.node.parentNode.removeChild(this.node);\n            for (var i in this) {\n                delete this[i];\n            }\n            this.removed = true;\n        };\n        Element[proto].getBBox = function () {\n            if (this.removed) {\n                return this;\n            }\n            if (this.type == \"path\") {\n                return pathDimensions(this.attrs.path);\n            }\n            if (this.node.style.display == \"none\") {\n                this.show();\n                var hide = true;\n            }\n            var bbox = {};\n            try {\n                bbox = this.node.getBBox();\n            } catch(e) {\n                // Firefox 3.0.x plays badly here\n            } finally {\n                bbox = bbox || {};\n            }\n            if (this.type == \"text\") {\n                bbox = {x: bbox.x, y: Infinity, width: 0, height: 0};\n                for (var i = 0, ii = this.node.getNumberOfChars(); i < ii; i++) {\n                    var bb = this.node.getExtentOfChar(i);\n                    (bb.y < bbox.y) && (bbox.y = bb.y);\n                    (bb.y + bb.height - bbox.y > bbox.height) && (bbox.height = bb.y + bb.height - bbox.y);\n                    (bb.x + bb.width - bbox.x > bbox.width) && (bbox.width = bb.x + bb.width - bbox.x);\n                }\n            }\n            hide && this.hide();\n            return bbox;\n        };\n        Element[proto].attr = function (name, value) {\n            if (this.removed) {\n                return this;\n            }\n            if (name == null) {\n                var res = {};\n                for (var i in this.attrs) if (this.attrs[has](i)) {\n                    res[i] = this.attrs[i];\n                }\n                this._.rt.deg && (res.rotation = this.rotate());\n                (this._.sx != 1 || this._.sy != 1) && (res.scale = this.scale());\n                res.gradient && res.fill == \"none\" && (res.fill = res.gradient) && delete res.gradient;\n                return res;\n            }\n            if (value == null && R.is(name, string)) {\n                if (name == \"translation\") {\n                    return translate.call(this);\n                }\n                if (name == \"rotation\") {\n                    return this.rotate();\n                }\n                if (name == \"scale\") {\n                    return this.scale();\n                }\n                if (name == fillString && this.attrs.fill == \"none\" && this.attrs.gradient) {\n                    return this.attrs.gradient;\n                }\n                return this.attrs[name];\n            }\n            if (value == null && R.is(name, array)) {\n                var values = {};\n                for (var j = 0, jj = name.length; j < jj; j++) {\n                    values[name[j]] = this.attr(name[j]);\n                }\n                return values;\n            }\n            if (value != null) {\n                var params = {};\n                params[name] = value;\n            } else if (name != null && R.is(name, \"object\")) {\n                params = name;\n            }\n            for (var key in this.paper.customAttributes) if (this.paper.customAttributes[has](key) && params[has](key) && R.is(this.paper.customAttributes[key], \"function\")) {\n                var par = this.paper.customAttributes[key].apply(this, [][concat](params[key]));\n                this.attrs[key] = params[key];\n                for (var subkey in par) if (par[has](subkey)) {\n                    params[subkey] = par[subkey];\n                }\n            }\n            setFillAndStroke(this, params);\n            return this;\n        };\n        Element[proto].toFront = function () {\n            if (this.removed) {\n                return this;\n            }\n            this.node.parentNode[appendChild](this.node);\n            var svg = this.paper;\n            svg.top != this && tofront(this, svg);\n            return this;\n        };\n        Element[proto].toBack = function () {\n            if (this.removed) {\n                return this;\n            }\n            if (this.node.parentNode.firstChild != this.node) {\n                this.node.parentNode.insertBefore(this.node, this.node.parentNode.firstChild);\n                toback(this, this.paper);\n                var svg = this.paper;\n            }\n            return this;\n        };\n        Element[proto].insertAfter = function (element) {\n            if (this.removed) {\n                return this;\n            }\n            var node = element.node || element[element.length - 1].node;\n            if (node.nextSibling) {\n                node.parentNode.insertBefore(this.node, node.nextSibling);\n            } else {\n                node.parentNode[appendChild](this.node);\n            }\n            insertafter(this, element, this.paper);\n            return this;\n        };\n        Element[proto].insertBefore = function (element) {\n            if (this.removed) {\n                return this;\n            }\n            var node = element.node || element[0].node;\n            node.parentNode.insertBefore(this.node, node);\n            insertbefore(this, element, this.paper);\n            return this;\n        };\n        Element[proto].blur = function (size) {\n            // Experimental. No Safari support. Use it on your own risk.\n            var t = this;\n            if (+size !== 0) {\n                var fltr = $(\"filter\"),\n                    blur = $(\"feGaussianBlur\");\n                t.attrs.blur = size;\n                fltr.id = createUUID();\n                $(blur, {stdDeviation: +size || 1.5});\n                fltr.appendChild(blur);\n                t.paper.defs.appendChild(fltr);\n                t._blur = fltr;\n                $(t.node, {filter: \"url(#\" + fltr.id + \")\"});\n            } else {\n                if (t._blur) {\n                    t._blur.parentNode.removeChild(t._blur);\n                    delete t._blur;\n                    delete t.attrs.blur;\n                }\n                t.node.removeAttribute(\"filter\");\n            }\n        };\n        var theCircle = function (svg, x, y, r) {\n            var el = $(\"circle\");\n            svg.canvas && svg.canvas[appendChild](el);\n            var res = new Element(el, svg);\n            res.attrs = {cx: x, cy: y, r: r, fill: \"none\", stroke: \"#000\"};\n            res.type = \"circle\";\n            $(el, res.attrs);\n            return res;\n        },\n        theRect = function (svg, x, y, w, h, r) {\n            var el = $(\"rect\");\n            svg.canvas && svg.canvas[appendChild](el);\n            var res = new Element(el, svg);\n            res.attrs = {x: x, y: y, width: w, height: h, r: r || 0, rx: r || 0, ry: r || 0, fill: \"none\", stroke: \"#000\"};\n            res.type = \"rect\";\n            $(el, res.attrs);\n            return res;\n        },\n        theEllipse = function (svg, x, y, rx, ry) {\n            var el = $(\"ellipse\");\n            svg.canvas && svg.canvas[appendChild](el);\n            var res = new Element(el, svg);\n            res.attrs = {cx: x, cy: y, rx: rx, ry: ry, fill: \"none\", stroke: \"#000\"};\n            res.type = \"ellipse\";\n            $(el, res.attrs);\n            return res;\n        },\n        theImage = function (svg, src, x, y, w, h) {\n            var el = $(\"image\");\n            $(el, {x: x, y: y, width: w, height: h, preserveAspectRatio: \"none\"});\n            el.setAttributeNS(svg.xlink, \"href\", src);\n            svg.canvas && svg.canvas[appendChild](el);\n            var res = new Element(el, svg);\n            res.attrs = {x: x, y: y, width: w, height: h, src: src};\n            res.type = \"image\";\n            return res;\n        },\n        theText = function (svg, x, y, text) {\n            var el = $(\"text\");\n            $(el, {x: x, y: y, \"text-anchor\": \"middle\"});\n            svg.canvas && svg.canvas[appendChild](el);\n            var res = new Element(el, svg);\n            res.attrs = {x: x, y: y, \"text-anchor\": \"middle\", text: text, font: availableAttrs.font, stroke: \"none\", fill: \"#000\"};\n            res.type = \"text\";\n            setFillAndStroke(res, res.attrs);\n            return res;\n        },\n        setSize = function (width, height) {\n            this.width = width || this.width;\n            this.height = height || this.height;\n            this.canvas[setAttribute](\"width\", this.width);\n            this.canvas[setAttribute](\"height\", this.height);\n            return this;\n        },\n        create = function () {\n            var con = getContainer[apply](0, arguments),\n                container = con && con.container,\n                x = con.x,\n                y = con.y,\n                width = con.width,\n                height = con.height;\n            if (!container) {\n                throw new Error(\"SVG container not found.\");\n            }\n            var cnvs = $(\"svg\");\n            x = x || 0;\n            y = y || 0;\n            width = width || 512;\n            height = height || 342;\n            $(cnvs, {\n                xmlns: \"http://www.w3.org/2000/svg\",\n                version: 1.1,\n                width: width,\n                height: height\n            });\n            if (container == 1) {\n                cnvs.style.cssText = \"position:absolute;left:\" + x + \"px;top:\" + y + \"px\";\n                doc.body[appendChild](cnvs);\n            } else {\n                if (container.firstChild) {\n                    container.insertBefore(cnvs, container.firstChild);\n                } else {\n                    container[appendChild](cnvs);\n                }\n            }\n            container = new Paper;\n            container.width = width;\n            container.height = height;\n            container.canvas = cnvs;\n            plugins.call(container, container, R.fn);\n            container.clear();\n            return container;\n        };\n        paperproto.clear = function () {\n            var c = this.canvas;\n            while (c.firstChild) {\n                c.removeChild(c.firstChild);\n            }\n            this.bottom = this.top = null;\n            (this.desc = $(\"desc\"))[appendChild](doc.createTextNode(\"Created with Rapha\\xebl\"));\n            c[appendChild](this.desc);\n            c[appendChild](this.defs = $(\"defs\"));\n        };\n        paperproto.remove = function () {\n            this.canvas.parentNode && this.canvas.parentNode.removeChild(this.canvas);\n            for (var i in this) {\n                this[i] = removed(i);\n            }\n        };\n    }\n\n    // VML\n    if (R.vml) {\n        var map = {M: \"m\", L: \"l\", C: \"c\", Z: \"x\", m: \"t\", l: \"r\", c: \"v\", z: \"x\"},\n            bites = /([clmz]),?([^clmz]*)/gi,\n            blurregexp = / progid:\\S+Blur\\([^\\)]+\\)/g,\n            val = /-?[^,\\s-]+/g,\n            coordsize = 1e3 + S + 1e3,\n            zoom = 10,\n            pathlike = {path: 1, rect: 1},\n            path2vml = function (path) {\n                var total =  /[ahqstv]/ig,\n                    command = pathToAbsolute;\n                Str(path).match(total) && (command = path2curve);\n                total = /[clmz]/g;\n                if (command == pathToAbsolute && !Str(path).match(total)) {\n                    var res = Str(path)[rp](bites, function (all, command, args) {\n                        var vals = [],\n                            isMove = lowerCase.call(command) == \"m\",\n                            res = map[command];\n                        args[rp](val, function (value) {\n                            if (isMove && vals[length] == 2) {\n                                res += vals + map[command == \"m\" ? \"l\" : \"L\"];\n                                vals = [];\n                            }\n                            vals[push](round(value * zoom));\n                        });\n                        return res + vals;\n                    });\n                    return res;\n                }\n                var pa = command(path), p, r;\n                res = [];\n                for (var i = 0, ii = pa[length]; i < ii; i++) {\n                    p = pa[i];\n                    r = lowerCase.call(pa[i][0]);\n                    r == \"z\" && (r = \"x\");\n                    for (var j = 1, jj = p[length]; j < jj; j++) {\n                        r += round(p[j] * zoom) + (j != jj - 1 ? \",\" : E);\n                    }\n                    res[push](r);\n                }\n                return res[join](S);\n            };\n        \n        R[toString] = function () {\n            return  \"Your browser doesn\\u2019t support SVG. Falling down to VML.\\nYou are running Rapha\\xebl \" + this.version;\n        };\n        thePath = function (pathString, vml) {\n            var g = createNode(\"group\");\n            g.style.cssText = \"position:absolute;left:0;top:0;width:\" + vml.width + \"px;height:\" + vml.height + \"px\";\n            g.coordsize = vml.coordsize;\n            g.coordorigin = vml.coordorigin;\n            var el = createNode(\"shape\"), ol = el.style;\n            ol.width = vml.width + \"px\";\n            ol.height = vml.height + \"px\";\n            el.coordsize = coordsize;\n            el.coordorigin = vml.coordorigin;\n            g[appendChild](el);\n            var p = new Element(el, g, vml),\n                attr = {fill: \"none\", stroke: \"#000\"};\n            pathString && (attr.path = pathString);\n            p.type = \"path\";\n            p.path = [];\n            p.Path = E;\n            setFillAndStroke(p, attr);\n            vml.canvas[appendChild](g);\n            return p;\n        };\n        setFillAndStroke = function (o, params) {\n            o.attrs = o.attrs || {};\n            var node = o.node,\n                a = o.attrs,\n                s = node.style,\n                xy,\n                newpath = (params.x != a.x || params.y != a.y || params.width != a.width || params.height != a.height || params.r != a.r) && o.type == \"rect\",\n                res = o;\n\n            for (var par in params) if (params[has](par)) {\n                a[par] = params[par];\n            }\n            if (newpath) {\n                a.path = rectPath(a.x, a.y, a.width, a.height, a.r);\n                o.X = a.x;\n                o.Y = a.y;\n                o.W = a.width;\n                o.H = a.height;\n            }\n            params.href && (node.href = params.href);\n            params.title && (node.title = params.title);\n            params.target && (node.target = params.target);\n            params.cursor && (s.cursor = params.cursor);\n            \"blur\" in params && o.blur(params.blur);\n            if (params.path && o.type == \"path\" || newpath) {\n                node.path = path2vml(a.path);\n            }\n            if (params.rotation != null) {\n                o.rotate(params.rotation, true);\n            }\n            if (params.translation) {\n                xy = Str(params.translation)[split](separator);\n                translate.call(o, xy[0], xy[1]);\n                if (o._.rt.cx != null) {\n                    o._.rt.cx +=+ xy[0];\n                    o._.rt.cy +=+ xy[1];\n                    o.setBox(o.attrs, xy[0], xy[1]);\n                }\n            }\n            if (params.scale) {\n                xy = Str(params.scale)[split](separator);\n                o.scale(+xy[0] || 1, +xy[1] || +xy[0] || 1, +xy[2] || null, +xy[3] || null);\n            }\n            if (\"clip-rect\" in params) {\n                var rect = Str(params[\"clip-rect\"])[split](separator);\n                if (rect[length] == 4) {\n                    rect[2] = +rect[2] + (+rect[0]);\n                    rect[3] = +rect[3] + (+rect[1]);\n                    var div = node.clipRect || doc.createElement(\"div\"),\n                        dstyle = div.style,\n                        group = node.parentNode;\n                    dstyle.clip = R.format(\"rect({1}px {2}px {3}px {0}px)\", rect);\n                    if (!node.clipRect) {\n                        dstyle.position = \"absolute\";\n                        dstyle.top = 0;\n                        dstyle.left = 0;\n                        dstyle.width = o.paper.width + \"px\";\n                        dstyle.height = o.paper.height + \"px\";\n                        group.parentNode.insertBefore(div, group);\n                        div[appendChild](group);\n                        node.clipRect = div;\n                    }\n                }\n                if (!params[\"clip-rect\"]) {\n                    node.clipRect && (node.clipRect.style.clip = E);\n                }\n            }\n            if (o.type == \"image\" && params.src) {\n                node.src = params.src;\n            }\n            if (o.type == \"image\" && params.opacity) {\n                node.filterOpacity = ms + \".Alpha(opacity=\" + (params.opacity * 100) + \")\";\n                s.filter = (node.filterMatrix || E) + (node.filterOpacity || E);\n            }\n            params.font && (s.font = params.font);\n            params[\"font-family\"] && (s.fontFamily = '\"' + params[\"font-family\"][split](\",\")[0][rp](/^['\"]+|['\"]+$/g, E) + '\"');\n            params[\"font-size\"] && (s.fontSize = params[\"font-size\"]);\n            params[\"font-weight\"] && (s.fontWeight = params[\"font-weight\"]);\n            params[\"font-style\"] && (s.fontStyle = params[\"font-style\"]);\n            if (params.opacity != null || \n                params[\"stroke-width\"] != null ||\n                params.fill != null ||\n                params.stroke != null ||\n                params[\"stroke-width\"] != null ||\n                params[\"stroke-opacity\"] != null ||\n                params[\"fill-opacity\"] != null ||\n                params[\"stroke-dasharray\"] != null ||\n                params[\"stroke-miterlimit\"] != null ||\n                params[\"stroke-linejoin\"] != null ||\n                params[\"stroke-linecap\"] != null) {\n                node = o.shape || node;\n                var fill = (node.getElementsByTagName(fillString) && node.getElementsByTagName(fillString)[0]),\n                    newfill = false;\n                !fill && (newfill = fill = createNode(fillString));\n                if (\"fill-opacity\" in params || \"opacity\" in params) {\n                    var opacity = ((+a[\"fill-opacity\"] + 1 || 2) - 1) * ((+a.opacity + 1 || 2) - 1) * ((+R.getRGB(params.fill).o + 1 || 2) - 1);\n                    opacity = mmin(mmax(opacity, 0), 1);\n                    fill.opacity = opacity;\n                }\n                params.fill && (fill.on = true);\n                if (fill.on == null || params.fill == \"none\") {\n                    fill.on = false;\n                }\n                if (fill.on && params.fill) {\n                    var isURL = params.fill.match(ISURL);\n                    if (isURL) {\n                        fill.src = isURL[1];\n                        fill.type = \"tile\";\n                    } else {\n                        fill.color = R.getRGB(params.fill).hex;\n                        fill.src = E;\n                        fill.type = \"solid\";\n                        if (R.getRGB(params.fill).error && (res.type in {circle: 1, ellipse: 1} || Str(params.fill).charAt() != \"r\") && addGradientFill(res, params.fill)) {\n                            a.fill = \"none\";\n                            a.gradient = params.fill;\n                        }\n                    }\n                }\n                newfill && node[appendChild](fill);\n                var stroke = (node.getElementsByTagName(\"stroke\") && node.getElementsByTagName(\"stroke\")[0]),\n                newstroke = false;\n                !stroke && (newstroke = stroke = createNode(\"stroke\"));\n                if ((params.stroke && params.stroke != \"none\") ||\n                    params[\"stroke-width\"] ||\n                    params[\"stroke-opacity\"] != null ||\n                    params[\"stroke-dasharray\"] ||\n                    params[\"stroke-miterlimit\"] ||\n                    params[\"stroke-linejoin\"] ||\n                    params[\"stroke-linecap\"]) {\n                    stroke.on = true;\n                }\n                (params.stroke == \"none\" || stroke.on == null || params.stroke == 0 || params[\"stroke-width\"] == 0) && (stroke.on = false);\n                var strokeColor = R.getRGB(params.stroke);\n                stroke.on && params.stroke && (stroke.color = strokeColor.hex);\n                opacity = ((+a[\"stroke-opacity\"] + 1 || 2) - 1) * ((+a.opacity + 1 || 2) - 1) * ((+strokeColor.o + 1 || 2) - 1);\n                var width = (toFloat(params[\"stroke-width\"]) || 1) * .75;\n                opacity = mmin(mmax(opacity, 0), 1);\n                params[\"stroke-width\"] == null && (width = a[\"stroke-width\"]);\n                params[\"stroke-width\"] && (stroke.weight = width);\n                width && width < 1 && (opacity *= width) && (stroke.weight = 1);\n                stroke.opacity = opacity;\n                \n                params[\"stroke-linejoin\"] && (stroke.joinstyle = params[\"stroke-linejoin\"] || \"miter\");\n                stroke.miterlimit = params[\"stroke-miterlimit\"] || 8;\n                params[\"stroke-linecap\"] && (stroke.endcap = params[\"stroke-linecap\"] == \"butt\" ? \"flat\" : params[\"stroke-linecap\"] == \"square\" ? \"square\" : \"round\");\n                if (params[\"stroke-dasharray\"]) {\n                    var dasharray = {\n                        \"-\": \"shortdash\",\n                        \".\": \"shortdot\",\n                        \"-.\": \"shortdashdot\",\n                        \"-..\": \"shortdashdotdot\",\n                        \". \": \"dot\",\n                        \"- \": \"dash\",\n                        \"--\": \"longdash\",\n                        \"- .\": \"dashdot\",\n                        \"--.\": \"longdashdot\",\n                        \"--..\": \"longdashdotdot\"\n                    };\n                    stroke.dashstyle = dasharray[has](params[\"stroke-dasharray\"]) ? dasharray[params[\"stroke-dasharray\"]] : E;\n                }\n                newstroke && node[appendChild](stroke);\n            }\n            if (res.type == \"text\") {\n                s = res.paper.span.style;\n                a.font && (s.font = a.font);\n                a[\"font-family\"] && (s.fontFamily = a[\"font-family\"]);\n                a[\"font-size\"] && (s.fontSize = a[\"font-size\"]);\n                a[\"font-weight\"] && (s.fontWeight = a[\"font-weight\"]);\n                a[\"font-style\"] && (s.fontStyle = a[\"font-style\"]);\n                res.node.string && (res.paper.span.innerHTML = Str(res.node.string)[rp](/</g, \"&#60;\")[rp](/&/g, \"&#38;\")[rp](/\\n/g, \"<br>\"));\n                res.W = a.w = res.paper.span.offsetWidth;\n                res.H = a.h = res.paper.span.offsetHeight;\n                res.X = a.x;\n                res.Y = a.y + round(res.H / 2);\n \n                // text-anchor emulationm\n                switch (a[\"text-anchor\"]) {\n                    case \"start\":\n                        res.node.style[\"v-text-align\"] = \"left\";\n                        res.bbx = round(res.W / 2);\n                    break;\n                    case \"end\":\n                        res.node.style[\"v-text-align\"] = \"right\";\n                        res.bbx = -round(res.W / 2);\n                    break;\n                    default:\n                        res.node.style[\"v-text-align\"] = \"center\";\n                    break;\n                }\n            }\n        };\n        addGradientFill = function (o, gradient) {\n            o.attrs = o.attrs || {};\n            var attrs = o.attrs,\n                fill,\n                type = \"linear\",\n                fxfy = \".5 .5\";\n            o.attrs.gradient = gradient;\n            gradient = Str(gradient)[rp](radial_gradient, function (all, fx, fy) {\n                type = \"radial\";\n                if (fx && fy) {\n                    fx = toFloat(fx);\n                    fy = toFloat(fy);\n                    pow(fx - .5, 2) + pow(fy - .5, 2) > .25 && (fy = math.sqrt(.25 - pow(fx - .5, 2)) * ((fy > .5) * 2 - 1) + .5);\n                    fxfy = fx + S + fy;\n                }\n                return E;\n            });\n            gradient = gradient[split](/\\s*\\-\\s*/);\n            if (type == \"linear\") {\n                var angle = gradient.shift();\n                angle = -toFloat(angle);\n                if (isNaN(angle)) {\n                    return null;\n                }\n            }\n            var dots = parseDots(gradient);\n            if (!dots) {\n                return null;\n            }\n            o = o.shape || o.node;\n            fill = o.getElementsByTagName(fillString)[0] || createNode(fillString);\n            !fill.parentNode && o.appendChild(fill);\n            if (dots[length]) {\n                fill.on = true;\n                fill.method = \"none\";\n                fill.color = dots[0].color;\n                fill.color2 = dots[dots[length] - 1].color;\n                var clrs = [];\n                for (var i = 0, ii = dots[length]; i < ii; i++) {\n                    dots[i].offset && clrs[push](dots[i].offset + S + dots[i].color);\n                }\n                fill.colors && (fill.colors.value = clrs[length] ? clrs[join]() : \"0% \" + fill.color);\n                if (type == \"radial\") {\n                    fill.type = \"gradientradial\";\n                    fill.focus = \"100%\";\n                    fill.focussize = fxfy;\n                    fill.focusposition = fxfy;\n                } else {\n                    fill.type = \"gradient\";\n                    fill.angle = (270 - angle) % 360;\n                }\n            }\n            return 1;\n        };\n        Element = function (node, group, vml) {\n            var Rotation = 0,\n                RotX = 0,\n                RotY = 0,\n                Scale = 1;\n            this[0] = node;\n            this.id = R._oid++;\n            this.node = node;\n            node.raphael = this;\n            this.X = 0;\n            this.Y = 0;\n            this.attrs = {};\n            this.Group = group;\n            this.paper = vml;\n            this._ = {\n                tx: 0,\n                ty: 0,\n                rt: {deg:0},\n                sx: 1,\n                sy: 1\n            };\n            !vml.bottom && (vml.bottom = this);\n            this.prev = vml.top;\n            vml.top && (vml.top.next = this);\n            vml.top = this;\n            this.next = null;\n        };\n        elproto = Element[proto];\n        elproto.rotate = function (deg, cx, cy) {\n            if (this.removed) {\n                return this;\n            }\n            if (deg == null) {\n                if (this._.rt.cx) {\n                    return [this._.rt.deg, this._.rt.cx, this._.rt.cy][join](S);\n                }\n                return this._.rt.deg;\n            }\n            deg = Str(deg)[split](separator);\n            if (deg[length] - 1) {\n                cx = toFloat(deg[1]);\n                cy = toFloat(deg[2]);\n            }\n            deg = toFloat(deg[0]);\n            if (cx != null) {\n                this._.rt.deg = deg;\n            } else {\n                this._.rt.deg += deg;\n            }\n            cy == null && (cx = null);\n            this._.rt.cx = cx;\n            this._.rt.cy = cy;\n            this.setBox(this.attrs, cx, cy);\n            this.Group.style.rotation = this._.rt.deg;\n            // gradient fix for rotation. TODO\n            // var fill = (this.shape || this.node).getElementsByTagName(fillString);\n            // fill = fill[0] || {};\n            // var b = ((360 - this._.rt.deg) - 270) % 360;\n            // !R.is(fill.angle, \"undefined\") && (fill.angle = b);\n            return this;\n        };\n        elproto.setBox = function (params, cx, cy) {\n            if (this.removed) {\n                return this;\n            }\n            var gs = this.Group.style,\n                os = (this.shape && this.shape.style) || this.node.style;\n            params = params || {};\n            for (var i in params) if (params[has](i)) {\n                this.attrs[i] = params[i];\n            }\n            cx = cx || this._.rt.cx;\n            cy = cy || this._.rt.cy;\n            var attr = this.attrs,\n                x,\n                y,\n                w,\n                h;\n            switch (this.type) {\n                case \"circle\":\n                    x = attr.cx - attr.r;\n                    y = attr.cy - attr.r;\n                    w = h = attr.r * 2;\n                    break;\n                case \"ellipse\":\n                    x = attr.cx - attr.rx;\n                    y = attr.cy - attr.ry;\n                    w = attr.rx * 2;\n                    h = attr.ry * 2;\n                    break;\n                case \"image\":\n                    x = +attr.x;\n                    y = +attr.y;\n                    w = attr.width || 0;\n                    h = attr.height || 0;\n                    break;\n                case \"text\":\n                    this.textpath.v = [\"m\", round(attr.x), \", \", round(attr.y - 2), \"l\", round(attr.x) + 1, \", \", round(attr.y - 2)][join](E);\n                    x = attr.x - round(this.W / 2);\n                    y = attr.y - this.H / 2;\n                    w = this.W;\n                    h = this.H;\n                    break;\n                case \"rect\":\n                case \"path\":\n                    if (!this.attrs.path) {\n                        x = 0;\n                        y = 0;\n                        w = this.paper.width;\n                        h = this.paper.height;\n                    } else {\n                        var dim = pathDimensions(this.attrs.path);\n                        x = dim.x;\n                        y = dim.y;\n                        w = dim.width;\n                        h = dim.height;\n                    }\n                    break;\n                default:\n                    x = 0;\n                    y = 0;\n                    w = this.paper.width;\n                    h = this.paper.height;\n                    break;\n            }\n            cx = (cx == null) ? x + w / 2 : cx;\n            cy = (cy == null) ? y + h / 2 : cy;\n            var left = cx - this.paper.width / 2,\n                top = cy - this.paper.height / 2, t;\n            gs.left != (t = left + \"px\") && (gs.left = t);\n            gs.top != (t = top + \"px\") && (gs.top = t);\n            this.X = pathlike[has](this.type) ? -left : x;\n            this.Y = pathlike[has](this.type) ? -top : y;\n            this.W = w;\n            this.H = h;\n            if (pathlike[has](this.type)) {\n                os.left != (t = -left * zoom + \"px\") && (os.left = t);\n                os.top != (t = -top * zoom + \"px\") && (os.top = t);\n            } else if (this.type == \"text\") {\n                os.left != (t = -left + \"px\") && (os.left = t);\n                os.top != (t = -top + \"px\") && (os.top = t);\n            } else {\n                gs.width != (t = this.paper.width + \"px\") && (gs.width = t);\n                gs.height != (t = this.paper.height + \"px\") && (gs.height = t);\n                os.left != (t = x - left + \"px\") && (os.left = t);\n                os.top != (t = y - top + \"px\") && (os.top = t);\n                os.width != (t = w + \"px\") && (os.width = t);\n                os.height != (t = h + \"px\") && (os.height = t);\n            }\n        };\n        elproto.hide = function () {\n            !this.removed && (this.Group.style.display = \"none\");\n            return this;\n        };\n        elproto.show = function () {\n            !this.removed && (this.Group.style.display = \"block\");\n            return this;\n        };\n        elproto.getBBox = function () {\n            if (this.removed) {\n                return this;\n            }\n            if (pathlike[has](this.type)) {\n                return pathDimensions(this.attrs.path);\n            }\n            return {\n                x: this.X + (this.bbx || 0),\n                y: this.Y,\n                width: this.W,\n                height: this.H\n            };\n        };\n        elproto.remove = function () {\n            if (this.removed) {\n                return;\n            }\n            tear(this, this.paper);\n            this.node.parentNode.removeChild(this.node);\n            this.Group.parentNode.removeChild(this.Group);\n            this.shape && this.shape.parentNode.removeChild(this.shape);\n            for (var i in this) {\n                delete this[i];\n            }\n            this.removed = true;\n        };\n        elproto.attr = function (name, value) {\n            if (this.removed) {\n                return this;\n            }\n            if (name == null) {\n                var res = {};\n                for (var i in this.attrs) if (this.attrs[has](i)) {\n                    res[i] = this.attrs[i];\n                }\n                this._.rt.deg && (res.rotation = this.rotate());\n                (this._.sx != 1 || this._.sy != 1) && (res.scale = this.scale());\n                res.gradient && res.fill == \"none\" && (res.fill = res.gradient) && delete res.gradient;\n                return res;\n            }\n            if (value == null && R.is(name, \"string\")) {\n                if (name == \"translation\") {\n                    return translate.call(this);\n                }\n                if (name == \"rotation\") {\n                    return this.rotate();\n                }\n                if (name == \"scale\") {\n                    return this.scale();\n                }\n                if (name == fillString && this.attrs.fill == \"none\" && this.attrs.gradient) {\n                    return this.attrs.gradient;\n                }\n                return this.attrs[name];\n            }\n            if (this.attrs && value == null && R.is(name, array)) {\n                var ii, values = {};\n                for (i = 0, ii = name[length]; i < ii; i++) {\n                    values[name[i]] = this.attr(name[i]);\n                }\n                return values;\n            }\n            var params;\n            if (value != null) {\n                params = {};\n                params[name] = value;\n            }\n            value == null && R.is(name, \"object\") && (params = name);\n            if (params) {\n                for (var key in this.paper.customAttributes) if (this.paper.customAttributes[has](key) && params[has](key) && R.is(this.paper.customAttributes[key], \"function\")) {\n                    var par = this.paper.customAttributes[key].apply(this, [][concat](params[key]));\n                    this.attrs[key] = params[key];\n                    for (var subkey in par) if (par[has](subkey)) {\n                        params[subkey] = par[subkey];\n                    }\n                }\n                if (params.text && this.type == \"text\") {\n                    this.node.string = params.text;\n                }\n                setFillAndStroke(this, params);\n                if (params.gradient && (({circle: 1, ellipse: 1})[has](this.type) || Str(params.gradient).charAt() != \"r\")) {\n                    addGradientFill(this, params.gradient);\n                }\n                (!pathlike[has](this.type) || this._.rt.deg) && this.setBox(this.attrs);\n            }\n            return this;\n        };\n        elproto.toFront = function () {\n            !this.removed && this.Group.parentNode[appendChild](this.Group);\n            this.paper.top != this && tofront(this, this.paper);\n            return this;\n        };\n        elproto.toBack = function () {\n            if (this.removed) {\n                return this;\n            }\n            if (this.Group.parentNode.firstChild != this.Group) {\n                this.Group.parentNode.insertBefore(this.Group, this.Group.parentNode.firstChild);\n                toback(this, this.paper);\n            }\n            return this;\n        };\n        elproto.insertAfter = function (element) {\n            if (this.removed) {\n                return this;\n            }\n            if (element.constructor == Set) {\n                element = element[element.length - 1];\n            }\n            if (element.Group.nextSibling) {\n                element.Group.parentNode.insertBefore(this.Group, element.Group.nextSibling);\n            } else {\n                element.Group.parentNode[appendChild](this.Group);\n            }\n            insertafter(this, element, this.paper);\n            return this;\n        };\n        elproto.insertBefore = function (element) {\n            if (this.removed) {\n                return this;\n            }\n            if (element.constructor == Set) {\n                element = element[0];\n            }\n            element.Group.parentNode.insertBefore(this.Group, element.Group);\n            insertbefore(this, element, this.paper);\n            return this;\n        };\n        elproto.blur = function (size) {\n            var s = this.node.runtimeStyle,\n                f = s.filter;\n            f = f.replace(blurregexp, E);\n            if (+size !== 0) {\n                this.attrs.blur = size;\n                s.filter = f + S + ms + \".Blur(pixelradius=\" + (+size || 1.5) + \")\";\n                s.margin = R.format(\"-{0}px 0 0 -{0}px\", round(+size || 1.5));\n            } else {\n                s.filter = f;\n                s.margin = 0;\n                delete this.attrs.blur;\n            }\n        };\n \n        theCircle = function (vml, x, y, r) {\n            var g = createNode(\"group\"),\n                o = createNode(\"oval\"),\n                ol = o.style;\n            g.style.cssText = \"position:absolute;left:0;top:0;width:\" + vml.width + \"px;height:\" + vml.height + \"px\";\n            g.coordsize = coordsize;\n            g.coordorigin = vml.coordorigin;\n            g[appendChild](o);\n            var res = new Element(o, g, vml);\n            res.type = \"circle\";\n            setFillAndStroke(res, {stroke: \"#000\", fill: \"none\"});\n            res.attrs.cx = x;\n            res.attrs.cy = y;\n            res.attrs.r = r;\n            res.setBox({x: x - r, y: y - r, width: r * 2, height: r * 2});\n            vml.canvas[appendChild](g);\n            return res;\n        };\n        function rectPath(x, y, w, h, r) {\n            if (r) {\n                return R.format(\"M{0},{1}l{2},0a{3},{3},0,0,1,{3},{3}l0,{5}a{3},{3},0,0,1,{4},{3}l{6},0a{3},{3},0,0,1,{4},{4}l0,{7}a{3},{3},0,0,1,{3},{4}z\", x + r, y, w - r * 2, r, -r, h - r * 2, r * 2 - w, r * 2 - h);\n            } else {\n                return R.format(\"M{0},{1}l{2},0,0,{3},{4},0z\", x, y, w, h, -w);\n            }\n        }\n        theRect = function (vml, x, y, w, h, r) {\n            var path = rectPath(x, y, w, h, r),\n                res = vml.path(path),\n                a = res.attrs;\n            res.X = a.x = x;\n            res.Y = a.y = y;\n            res.W = a.width = w;\n            res.H = a.height = h;\n            a.r = r;\n            a.path = path;\n            res.type = \"rect\";\n            return res;\n        };\n        theEllipse = function (vml, x, y, rx, ry) {\n            var g = createNode(\"group\"),\n                o = createNode(\"oval\"),\n                ol = o.style;\n            g.style.cssText = \"position:absolute;left:0;top:0;width:\" + vml.width + \"px;height:\" + vml.height + \"px\";\n            g.coordsize = coordsize;\n            g.coordorigin = vml.coordorigin;\n            g[appendChild](o);\n            var res = new Element(o, g, vml);\n            res.type = \"ellipse\";\n            setFillAndStroke(res, {stroke: \"#000\"});\n            res.attrs.cx = x;\n            res.attrs.cy = y;\n            res.attrs.rx = rx;\n            res.attrs.ry = ry;\n            res.setBox({x: x - rx, y: y - ry, width: rx * 2, height: ry * 2});\n            vml.canvas[appendChild](g);\n            return res;\n        };\n        theImage = function (vml, src, x, y, w, h) {\n            var g = createNode(\"group\"),\n                o = createNode(\"image\");\n            g.style.cssText = \"position:absolute;left:0;top:0;width:\" + vml.width + \"px;height:\" + vml.height + \"px\";\n            g.coordsize = coordsize;\n            g.coordorigin = vml.coordorigin;\n            o.src = src;\n            g[appendChild](o);\n            var res = new Element(o, g, vml);\n            res.type = \"image\";\n            res.attrs.src = src;\n            res.attrs.x = x;\n            res.attrs.y = y;\n            res.attrs.w = w;\n            res.attrs.h = h;\n            res.setBox({x: x, y: y, width: w, height: h});\n            vml.canvas[appendChild](g);\n            return res;\n        };\n        theText = function (vml, x, y, text) {\n            var g = createNode(\"group\"),\n                el = createNode(\"shape\"),\n                ol = el.style,\n                path = createNode(\"path\"),\n                ps = path.style,\n                o = createNode(\"textpath\");\n            g.style.cssText = \"position:absolute;left:0;top:0;width:\" + vml.width + \"px;height:\" + vml.height + \"px\";\n            g.coordsize = coordsize;\n            g.coordorigin = vml.coordorigin;\n            path.v = R.format(\"m{0},{1}l{2},{1}\", round(x * 10), round(y * 10), round(x * 10) + 1);\n            path.textpathok = true;\n            ol.width = vml.width;\n            ol.height = vml.height;\n            o.string = Str(text);\n            o.on = true;\n            el[appendChild](o);\n            el[appendChild](path);\n            g[appendChild](el);\n            var res = new Element(o, g, vml);\n            res.shape = el;\n            res.textpath = path;\n            res.type = \"text\";\n            res.attrs.text = text;\n            res.attrs.x = x;\n            res.attrs.y = y;\n            res.attrs.w = 1;\n            res.attrs.h = 1;\n            setFillAndStroke(res, {font: availableAttrs.font, stroke: \"none\", fill: \"#000\"});\n            res.setBox();\n            vml.canvas[appendChild](g);\n            return res;\n        };\n        setSize = function (width, height) {\n            var cs = this.canvas.style;\n            width == +width && (width += \"px\");\n            height == +height && (height += \"px\");\n            cs.width = width;\n            cs.height = height;\n            cs.clip = \"rect(0 \" + width + \" \" + height + \" 0)\";\n            return this;\n        };\n        var createNode;\n        doc.createStyleSheet().addRule(\".rvml\", \"behavior:url(#default#VML)\");\n        try {\n            !doc.namespaces.rvml && doc.namespaces.add(\"rvml\", \"urn:schemas-microsoft-com:vml\");\n            createNode = function (tagName) {\n                return doc.createElement('<rvml:' + tagName + ' class=\"rvml\">');\n            };\n        } catch (e) {\n            createNode = function (tagName) {\n                return doc.createElement('<' + tagName + ' xmlns=\"urn:schemas-microsoft.com:vml\" class=\"rvml\">');\n            };\n        }\n        create = function () {\n            var con = getContainer[apply](0, arguments),\n                container = con.container,\n                height = con.height,\n                s,\n                width = con.width,\n                x = con.x,\n                y = con.y;\n            if (!container) {\n                throw new Error(\"VML container not found.\");\n            }\n            var res = new Paper,\n                c = res.canvas = doc.createElement(\"div\"),\n                cs = c.style;\n            x = x || 0;\n            y = y || 0;\n            width = width || 512;\n            height = height || 342;\n            width == +width && (width += \"px\");\n            height == +height && (height += \"px\");\n            res.width = 1e3;\n            res.height = 1e3;\n            res.coordsize = zoom * 1e3 + S + zoom * 1e3;\n            res.coordorigin = \"0 0\";\n            res.span = doc.createElement(\"span\");\n            res.span.style.cssText = \"position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;\";\n            c[appendChild](res.span);\n            cs.cssText = R.format(\"top:0;left:0;width:{0};height:{1};display:inline-block;position:relative;clip:rect(0 {0} {1} 0);overflow:hidden\", width, height);\n            if (container == 1) {\n                doc.body[appendChild](c);\n                cs.left = x + \"px\";\n                cs.top = y + \"px\";\n                cs.position = \"absolute\";\n            } else {\n                if (container.firstChild) {\n                    container.insertBefore(c, container.firstChild);\n                } else {\n                    container[appendChild](c);\n                }\n            }\n            plugins.call(res, res, R.fn);\n            return res;\n        };\n        paperproto.clear = function () {\n            this.canvas.innerHTML = E;\n            this.span = doc.createElement(\"span\");\n            this.span.style.cssText = \"position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;\";\n            this.canvas[appendChild](this.span);\n            this.bottom = this.top = null;\n        };\n        paperproto.remove = function () {\n            this.canvas.parentNode.removeChild(this.canvas);\n            for (var i in this) {\n                this[i] = removed(i);\n            }\n            return true;\n        };\n    }\n \n    // rest\n    // WebKit rendering bug workaround method\n    var version = navigator.userAgent.match(/Version\\/(.*?)\\s/);\n    if ((navigator.vendor == \"Apple Computer, Inc.\") && (version && version[1] < 4 || navigator.platform.slice(0, 2) == \"iP\")) {\n        paperproto.safari = function () {\n            var rect = this.rect(-99, -99, this.width + 99, this.height + 99).attr({stroke: \"none\"});\n            win.setTimeout(function () {rect.remove();});\n        };\n    } else {\n        paperproto.safari = function () {};\n    }\n \n    // Events\n    var preventDefault = function () {\n        this.returnValue = false;\n    },\n    preventTouch = function () {\n        return this.originalEvent.preventDefault();\n    },\n    stopPropagation = function () {\n        this.cancelBubble = true;\n    },\n    stopTouch = function () {\n        return this.originalEvent.stopPropagation();\n    },\n    addEvent = (function () {\n        if (doc.addEventListener) {\n            return function (obj, type, fn, element) {\n                var realName = supportsTouch && touchMap[type] ? touchMap[type] : type;\n                var f = function (e) {\n                    if (supportsTouch && touchMap[has](type)) {\n                        for (var i = 0, ii = e.targetTouches && e.targetTouches.length; i < ii; i++) {\n                            if (e.targetTouches[i].target == obj) {\n                                var olde = e;\n                                e = e.targetTouches[i];\n                                e.originalEvent = olde;\n                                e.preventDefault = preventTouch;\n                                e.stopPropagation = stopTouch;\n                                break;\n                            }\n                        }\n                    }\n                    return fn.call(element, e);\n                };\n                obj.addEventListener(realName, f, false);\n                return function () {\n                    obj.removeEventListener(realName, f, false);\n                    return true;\n                };\n            };\n        } else if (doc.attachEvent) {\n            return function (obj, type, fn, element) {\n                var f = function (e) {\n                    e = e || win.event;\n                    e.preventDefault = e.preventDefault || preventDefault;\n                    e.stopPropagation = e.stopPropagation || stopPropagation;\n                    return fn.call(element, e);\n                };\n                obj.attachEvent(\"on\" + type, f);\n                var detacher = function () {\n                    obj.detachEvent(\"on\" + type, f);\n                    return true;\n                };\n                return detacher;\n            };\n        }\n    })(),\n    drag = [],\n    dragMove = function (e) {\n        var x = e.clientX,\n            y = e.clientY,\n            scrollY = doc.documentElement.scrollTop || doc.body.scrollTop,\n            scrollX = doc.documentElement.scrollLeft || doc.body.scrollLeft,\n            dragi,\n            j = drag.length;\n        while (j--) {\n            dragi = drag[j];\n            if (supportsTouch) {\n                var i = e.touches.length,\n                    touch;\n                while (i--) {\n                    touch = e.touches[i];\n                    if (touch.identifier == dragi.el._drag.id) {\n                        x = touch.clientX;\n                        y = touch.clientY;\n                        (e.originalEvent ? e.originalEvent : e).preventDefault();\n                        break;\n                    }\n                }\n            } else {\n                e.preventDefault();\n            }\n            x += scrollX;\n            y += scrollY;\n            dragi.move && dragi.move.call(dragi.move_scope || dragi.el, x - dragi.el._drag.x, y - dragi.el._drag.y, x, y, e);\n        }\n    },\n    dragUp = function (e) {\n        R.unmousemove(dragMove).unmouseup(dragUp);\n        var i = drag.length,\n            dragi;\n        while (i--) {\n            dragi = drag[i];\n            dragi.el._drag = {};\n            dragi.end && dragi.end.call(dragi.end_scope || dragi.start_scope || dragi.move_scope || dragi.el, e);\n        }\n        drag = [];\n    };\n    for (var i = events[length]; i--;) {\n        (function (eventName) {\n            R[eventName] = Element[proto][eventName] = function (fn, scope) {\n                if (R.is(fn, \"function\")) {\n                    this.events = this.events || [];\n                    this.events.push({name: eventName, f: fn, unbind: addEvent(this.shape || this.node || doc, eventName, fn, scope || this)});\n                }\n                return this;\n            };\n            R[\"un\" + eventName] = Element[proto][\"un\" + eventName] = function (fn) {\n                var events = this.events,\n                    l = events[length];\n                while (l--) if (events[l].name == eventName && events[l].f == fn) {\n                    events[l].unbind();\n                    events.splice(l, 1);\n                    !events.length && delete this.events;\n                    return this;\n                }\n                return this;\n            };\n        })(events[i]);\n    }\n    elproto.hover = function (f_in, f_out, scope_in, scope_out) {\n        return this.mouseover(f_in, scope_in).mouseout(f_out, scope_out || scope_in);\n    };\n    elproto.unhover = function (f_in, f_out) {\n        return this.unmouseover(f_in).unmouseout(f_out);\n    };\n    elproto.drag = function (onmove, onstart, onend, move_scope, start_scope, end_scope) {\n        this._drag = {};\n        this.mousedown(function (e) {\n            (e.originalEvent || e).preventDefault();\n            var scrollY = doc.documentElement.scrollTop || doc.body.scrollTop,\n                scrollX = doc.documentElement.scrollLeft || doc.body.scrollLeft;\n            this._drag.x = e.clientX + scrollX;\n            this._drag.y = e.clientY + scrollY;\n            this._drag.id = e.identifier;\n            onstart && onstart.call(start_scope || move_scope || this, e.clientX + scrollX, e.clientY + scrollY, e);\n            !drag.length && R.mousemove(dragMove).mouseup(dragUp);\n            drag.push({el: this, move: onmove, end: onend, move_scope: move_scope, start_scope: start_scope, end_scope: end_scope});\n        });\n        return this;\n    };\n    elproto.undrag = function (onmove, onstart, onend) {\n        var i = drag.length;\n        while (i--) {\n            drag[i].el == this && (drag[i].move == onmove && drag[i].end == onend) && drag.splice(i++, 1);\n        }\n        !drag.length && R.unmousemove(dragMove).unmouseup(dragUp);\n    };\n    paperproto.circle = function (x, y, r) {\n        return theCircle(this, x || 0, y || 0, r || 0);\n    };\n    paperproto.rect = function (x, y, w, h, r) {\n        return theRect(this, x || 0, y || 0, w || 0, h || 0, r || 0);\n    };\n    paperproto.ellipse = function (x, y, rx, ry) {\n        return theEllipse(this, x || 0, y || 0, rx || 0, ry || 0);\n    };\n    paperproto.path = function (pathString) {\n        pathString && !R.is(pathString, string) && !R.is(pathString[0], array) && (pathString += E);\n        return thePath(R.format[apply](R, arguments), this);\n    };\n    paperproto.image = function (src, x, y, w, h) {\n        return theImage(this, src || \"about:blank\", x || 0, y || 0, w || 0, h || 0);\n    };\n    paperproto.text = function (x, y, text) {\n        return theText(this, x || 0, y || 0, Str(text));\n    };\n    paperproto.set = function (itemsArray) {\n        arguments[length] > 1 && (itemsArray = Array[proto].splice.call(arguments, 0, arguments[length]));\n        return new Set(itemsArray);\n    };\n    paperproto.setSize = setSize;\n    paperproto.top = paperproto.bottom = null;\n    paperproto.raphael = R;\n    function x_y() {\n        return this.x + S + this.y;\n    }\n    elproto.resetScale = function () {\n        if (this.removed) {\n            return this;\n        }\n        this._.sx = 1;\n        this._.sy = 1;\n        this.attrs.scale = \"1 1\";\n    };\n    elproto.scale = function (x, y, cx, cy) {\n        if (this.removed) {\n            return this;\n        }\n        if (x == null && y == null) {\n            return {\n                x: this._.sx,\n                y: this._.sy,\n                toString: x_y\n            };\n        }\n        y = y || x;\n        !+y && (y = x);\n        var dx,\n            dy,\n            dcx,\n            dcy,\n            a = this.attrs;\n        if (x != 0) {\n            var bb = this.getBBox(),\n                rcx = bb.x + bb.width / 2,\n                rcy = bb.y + bb.height / 2,\n                kx = abs(x / this._.sx),\n                ky = abs(y / this._.sy);\n            cx = (+cx || cx == 0) ? cx : rcx;\n            cy = (+cy || cy == 0) ? cy : rcy;\n            var posx = this._.sx > 0,\n                posy = this._.sy > 0,\n                dirx = ~~(x / abs(x)),\n                diry = ~~(y / abs(y)),\n                dkx = kx * dirx,\n                dky = ky * diry,\n                s = this.node.style,\n                ncx = cx + abs(rcx - cx) * dkx * (rcx > cx == posx ? 1 : -1),\n                ncy = cy + abs(rcy - cy) * dky * (rcy > cy == posy ? 1 : -1),\n                fr = (x * dirx > y * diry ? ky : kx);\n            switch (this.type) {\n                case \"rect\":\n                case \"image\":\n                    var neww = a.width * kx,\n                        newh = a.height * ky;\n                    this.attr({\n                        height: newh,\n                        r: a.r * fr,\n                        width: neww,\n                        x: ncx - neww / 2,\n                        y: ncy - newh / 2\n                    });\n                    break;\n                case \"circle\":\n                case \"ellipse\":\n                    this.attr({\n                        rx: a.rx * kx,\n                        ry: a.ry * ky,\n                        r: a.r * fr,\n                        cx: ncx,\n                        cy: ncy\n                    });\n                    break;\n                case \"text\":\n                    this.attr({\n                        x: ncx,\n                        y: ncy\n                    });\n                    break;\n                case \"path\":\n                    var path = pathToRelative(a.path),\n                        skip = true,\n                        fx = posx ? dkx : kx,\n                        fy = posy ? dky : ky;\n                    for (var i = 0, ii = path[length]; i < ii; i++) {\n                        var p = path[i],\n                            P0 = upperCase.call(p[0]);\n                        if (P0 == \"M\" && skip) {\n                            continue;\n                        } else {\n                            skip = false;\n                        }\n                        if (P0 == \"A\") {\n                            p[path[i][length] - 2] *= fx;\n                            p[path[i][length] - 1] *= fy;\n                            p[1] *= kx;\n                            p[2] *= ky;\n                            p[5] = +(dirx + diry ? !!+p[5] : !+p[5]);\n                        } else if (P0 == \"H\") {\n                            for (var j = 1, jj = p[length]; j < jj; j++) {\n                                p[j] *= fx;\n                            }\n                        } else if (P0 == \"V\") {\n                            for (j = 1, jj = p[length]; j < jj; j++) {\n                                p[j] *= fy;\n                            }\n                         } else {\n                            for (j = 1, jj = p[length]; j < jj; j++) {\n                                p[j] *= (j % 2) ? fx : fy;\n                            }\n                        }\n                    }\n                    var dim2 = pathDimensions(path);\n                    dx = ncx - dim2.x - dim2.width / 2;\n                    dy = ncy - dim2.y - dim2.height / 2;\n                    path[0][1] += dx;\n                    path[0][2] += dy;\n                    this.attr({path: path});\n                break;\n            }\n            if (this.type in {text: 1, image:1} && (dirx != 1 || diry != 1)) {\n                if (this.transformations) {\n                    this.transformations[2] = \"scale(\"[concat](dirx, \",\", diry, \")\");\n                    this.node[setAttribute](\"transform\", this.transformations[join](S));\n                    dx = (dirx == -1) ? -a.x - (neww || 0) : a.x;\n                    dy = (diry == -1) ? -a.y - (newh || 0) : a.y;\n                    this.attr({x: dx, y: dy});\n                    a.fx = dirx - 1;\n                    a.fy = diry - 1;\n                } else {\n                    this.node.filterMatrix = ms + \".Matrix(M11=\"[concat](dirx,\n                        \", M12=0, M21=0, M22=\", diry,\n                        \", Dx=0, Dy=0, sizingmethod='auto expand', filtertype='bilinear')\");\n                    s.filter = (this.node.filterMatrix || E) + (this.node.filterOpacity || E);\n                }\n            } else {\n                if (this.transformations) {\n                    this.transformations[2] = E;\n                    this.node[setAttribute](\"transform\", this.transformations[join](S));\n                    a.fx = 0;\n                    a.fy = 0;\n                } else {\n                    this.node.filterMatrix = E;\n                    s.filter = (this.node.filterMatrix || E) + (this.node.filterOpacity || E);\n                }\n            }\n            a.scale = [x, y, cx, cy][join](S);\n            this._.sx = x;\n            this._.sy = y;\n        }\n        return this;\n    };\n    elproto.clone = function () {\n        if (this.removed) {\n            return null;\n        }\n        var attr = this.attr();\n        delete attr.scale;\n        delete attr.translation;\n        return this.paper[this.type]().attr(attr);\n    };\n    var curveslengths = {},\n    getPointAtSegmentLength = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, length) {\n        var len = 0,\n            precision = 100,\n            name = [p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y].join(),\n            cache = curveslengths[name],\n            old, dot;\n        !cache && (curveslengths[name] = cache = {data: []});\n        cache.timer && clearTimeout(cache.timer);\n        cache.timer = setTimeout(function () {delete curveslengths[name];}, 2000);\n        if (length != null) {\n            var total = getPointAtSegmentLength(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y);\n            precision = ~~total * 10;\n        }\n        for (var i = 0; i < precision + 1; i++) {\n            if (cache.data[length] > i) {\n                dot = cache.data[i * precision];\n            } else {\n                dot = R.findDotsAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, i / precision);\n                cache.data[i] = dot;\n            }\n            i && (len += pow(pow(old.x - dot.x, 2) + pow(old.y - dot.y, 2), .5));\n            if (length != null && len >= length) {\n                return dot;\n            }\n            old = dot;\n        }\n        if (length == null) {\n            return len;\n        }\n    },\n    getLengthFactory = function (istotal, subpath) {\n        return function (path, length, onlystart) {\n            path = path2curve(path);\n            var x, y, p, l, sp = \"\", subpaths = {}, point,\n                len = 0;\n            for (var i = 0, ii = path.length; i < ii; i++) {\n                p = path[i];\n                if (p[0] == \"M\") {\n                    x = +p[1];\n                    y = +p[2];\n                } else {\n                    l = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6]);\n                    if (len + l > length) {\n                        if (subpath && !subpaths.start) {\n                            point = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6], length - len);\n                            sp += [\"C\", point.start.x, point.start.y, point.m.x, point.m.y, point.x, point.y];\n                            if (onlystart) {return sp;}\n                            subpaths.start = sp;\n                            sp = [\"M\", point.x, point.y + \"C\", point.n.x, point.n.y, point.end.x, point.end.y, p[5], p[6]][join]();\n                            len += l;\n                            x = +p[5];\n                            y = +p[6];\n                            continue;\n                        }\n                        if (!istotal && !subpath) {\n                            point = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6], length - len);\n                            return {x: point.x, y: point.y, alpha: point.alpha};\n                        }\n                    }\n                    len += l;\n                    x = +p[5];\n                    y = +p[6];\n                }\n                sp += p;\n            }\n            subpaths.end = sp;\n            point = istotal ? len : subpath ? subpaths : R.findDotsAtSegment(x, y, p[1], p[2], p[3], p[4], p[5], p[6], 1);\n            point.alpha && (point = {x: point.x, y: point.y, alpha: point.alpha});\n            return point;\n        };\n    };\n    var getTotalLength = getLengthFactory(1),\n        getPointAtLength = getLengthFactory(),\n        getSubpathsAtLength = getLengthFactory(0, 1);\n    elproto.getTotalLength = function () {\n        if (this.type != \"path\") {return;}\n        if (this.node.getTotalLength) {\n            return this.node.getTotalLength();\n        }\n        return getTotalLength(this.attrs.path);\n    };\n    elproto.getPointAtLength = function (length) {\n        if (this.type != \"path\") {return;}\n        return getPointAtLength(this.attrs.path, length);\n    };\n    elproto.getSubpath = function (from, to) {\n        if (this.type != \"path\") {return;}\n        if (abs(this.getTotalLength() - to) < \"1e-6\") {\n            return getSubpathsAtLength(this.attrs.path, from).end;\n        }\n        var a = getSubpathsAtLength(this.attrs.path, to, 1);\n        return from ? getSubpathsAtLength(a, from).end : a;\n    };\n\n    // animation easing formulas\n    R.easing_formulas = {\n        linear: function (n) {\n            return n;\n        },\n        \"<\": function (n) {\n            return pow(n, 3);\n        },\n        \">\": function (n) {\n            return pow(n - 1, 3) + 1;\n        },\n        \"<>\": function (n) {\n            n = n * 2;\n            if (n < 1) {\n                return pow(n, 3) / 2;\n            }\n            n -= 2;\n            return (pow(n, 3) + 2) / 2;\n        },\n        backIn: function (n) {\n            var s = 1.70158;\n            return n * n * ((s + 1) * n - s);\n        },\n        backOut: function (n) {\n            n = n - 1;\n            var s = 1.70158;\n            return n * n * ((s + 1) * n + s) + 1;\n        },\n        elastic: function (n) {\n            if (n == 0 || n == 1) {\n                return n;\n            }\n            var p = .3,\n                s = p / 4;\n            return pow(2, -10 * n) * math.sin((n - s) * (2 * PI) / p) + 1;\n        },\n        bounce: function (n) {\n            var s = 7.5625,\n                p = 2.75,\n                l;\n            if (n < (1 / p)) {\n                l = s * n * n;\n            } else {\n                if (n < (2 / p)) {\n                    n -= (1.5 / p);\n                    l = s * n * n + .75;\n                } else {\n                    if (n < (2.5 / p)) {\n                        n -= (2.25 / p);\n                        l = s * n * n + .9375;\n                    } else {\n                        n -= (2.625 / p);\n                        l = s * n * n + .984375;\n                    }\n                }\n            }\n            return l;\n        }\n    };\n\n    var animationElements = [],\n        animation = function () {\n            var Now = +new Date;\n            for (var l = 0; l < animationElements[length]; l++) {\n                var e = animationElements[l];\n                if (e.stop || e.el.removed) {\n                    continue;\n                }\n                var time = Now - e.start,\n                    ms = e.ms,\n                    easing = e.easing,\n                    from = e.from,\n                    diff = e.diff,\n                    to = e.to,\n                    t = e.t,\n                    that = e.el,\n                    set = {},\n                    now;\n                if (time < ms) {\n                    var pos = easing(time / ms);\n                    for (var attr in from) if (from[has](attr)) {\n                        switch (availableAnimAttrs[attr]) {\n                            case \"along\":\n                                now = pos * ms * diff[attr];\n                                to.back && (now = to.len - now);\n                                var point = getPointAtLength(to[attr], now);\n                                that.translate(diff.sx - diff.x || 0, diff.sy - diff.y || 0);\n                                diff.x = point.x;\n                                diff.y = point.y;\n                                that.translate(point.x - diff.sx, point.y - diff.sy);\n                                to.rot && that.rotate(diff.r + point.alpha, point.x, point.y);\n                                break;\n                            case nu:\n                                now = +from[attr] + pos * ms * diff[attr];\n                                break;\n                            case \"colour\":\n                                now = \"rgb(\" + [\n                                    upto255(round(from[attr].r + pos * ms * diff[attr].r)),\n                                    upto255(round(from[attr].g + pos * ms * diff[attr].g)),\n                                    upto255(round(from[attr].b + pos * ms * diff[attr].b))\n                                ][join](\",\") + \")\";\n                                break;\n                            case \"path\":\n                                now = [];\n                                for (var i = 0, ii = from[attr][length]; i < ii; i++) {\n                                    now[i] = [from[attr][i][0]];\n                                    for (var j = 1, jj = from[attr][i][length]; j < jj; j++) {\n                                        now[i][j] = +from[attr][i][j] + pos * ms * diff[attr][i][j];\n                                    }\n                                    now[i] = now[i][join](S);\n                                }\n                                now = now[join](S);\n                                break;\n                            case \"csv\":\n                                switch (attr) {\n                                    case \"translation\":\n                                        var x = pos * ms * diff[attr][0] - t.x,\n                                            y = pos * ms * diff[attr][1] - t.y;\n                                        t.x += x;\n                                        t.y += y;\n                                        now = x + S + y;\n                                    break;\n                                    case \"rotation\":\n                                        now = +from[attr][0] + pos * ms * diff[attr][0];\n                                        from[attr][1] && (now += \",\" + from[attr][1] + \",\" + from[attr][2]);\n                                    break;\n                                    case \"scale\":\n                                        now = [+from[attr][0] + pos * ms * diff[attr][0], +from[attr][1] + pos * ms * diff[attr][1], (2 in to[attr] ? to[attr][2] : E), (3 in to[attr] ? to[attr][3] : E)][join](S);\n                                    break;\n                                    case \"clip-rect\":\n                                        now = [];\n                                        i = 4;\n                                        while (i--) {\n                                            now[i] = +from[attr][i] + pos * ms * diff[attr][i];\n                                        }\n                                    break;\n                                }\n                                break;\n                            default:\n                              var from2 = [].concat(from[attr]);\n                                now = [];\n                                i = that.paper.customAttributes[attr].length;\n                                while (i--) {\n                                    now[i] = +from2[i] + pos * ms * diff[attr][i];\n                                }\n                                break;\n                        }\n                        set[attr] = now;\n                    }\n                    that.attr(set);\n                    that._run && that._run.call(that);\n                } else {\n                    if (to.along) {\n                        point = getPointAtLength(to.along, to.len * !to.back);\n                        that.translate(diff.sx - (diff.x || 0) + point.x - diff.sx, diff.sy - (diff.y || 0) + point.y - diff.sy);\n                        to.rot && that.rotate(diff.r + point.alpha, point.x, point.y);\n                    }\n                    (t.x || t.y) && that.translate(-t.x, -t.y);\n                    to.scale && (to.scale += E);\n                    that.attr(to);\n                    animationElements.splice(l--, 1);\n                }\n            }\n            R.svg && that && that.paper && that.paper.safari();\n            animationElements[length] && setTimeout(animation);\n        },\n        keyframesRun = function (attr, element, time, prev, prevcallback) {\n            var dif = time - prev;\n            element.timeouts.push(setTimeout(function () {\n                R.is(prevcallback, \"function\") && prevcallback.call(element);\n                element.animate(attr, dif, attr.easing);\n            }, prev));\n        },\n        upto255 = function (color) {\n            return mmax(mmin(color, 255), 0);\n        },\n        translate = function (x, y) {\n            if (x == null) {\n                return {x: this._.tx, y: this._.ty, toString: x_y};\n            }\n            this._.tx += +x;\n            this._.ty += +y;\n            switch (this.type) {\n                case \"circle\":\n                case \"ellipse\":\n                    this.attr({cx: +x + this.attrs.cx, cy: +y + this.attrs.cy});\n                    break;\n                case \"rect\":\n                case \"image\":\n                case \"text\":\n                    this.attr({x: +x + this.attrs.x, y: +y + this.attrs.y});\n                    break;\n                case \"path\":\n                    var path = pathToRelative(this.attrs.path);\n                    path[0][1] += +x;\n                    path[0][2] += +y;\n                    this.attr({path: path});\n                break;\n            }\n            return this;\n        };\n    elproto.animateWith = function (element, params, ms, easing, callback) {\n        for (var i = 0, ii = animationElements.length; i < ii; i++) {\n            if (animationElements[i].el.id == element.id) {\n                params.start = animationElements[i].start;\n            }\n        }\n        return this.animate(params, ms, easing, callback);\n    };\n    elproto.animateAlong = along();\n    elproto.animateAlongBack = along(1);\n    function along(isBack) {\n        return function (path, ms, rotate, callback) {\n            var params = {back: isBack};\n            R.is(rotate, \"function\") ? (callback = rotate) : (params.rot = rotate);\n            path && path.constructor == Element && (path = path.attrs.path);\n            path && (params.along = path);\n            return this.animate(params, ms, callback);\n        };\n    }\n    function CubicBezierAtTime(t, p1x, p1y, p2x, p2y, duration) {\n        var cx = 3 * p1x,\n            bx = 3 * (p2x - p1x) - cx,\n            ax = 1 - cx - bx,\n            cy = 3 * p1y,\n            by = 3 * (p2y - p1y) - cy,\n            ay = 1 - cy - by;\n        function sampleCurveX(t) {\n            return ((ax * t + bx) * t + cx) * t;\n        }\n        function solve(x, epsilon) {\n            var t = solveCurveX(x, epsilon);\n            return ((ay * t + by) * t + cy) * t;\n        }\n        function solveCurveX(x, epsilon) {\n            var t0, t1, t2, x2, d2, i;\n            for(t2 = x, i = 0; i < 8; i++) {\n                x2 = sampleCurveX(t2) - x;\n                if (abs(x2) < epsilon) {\n                    return t2;\n                }\n                d2 = (3 * ax * t2 + 2 * bx) * t2 + cx;\n                if (abs(d2) < 1e-6) {\n                    break;\n                }\n                t2 = t2 - x2 / d2;\n            }\n            t0 = 0;\n            t1 = 1;\n            t2 = x;\n            if (t2 < t0) {\n                return t0;\n            }\n            if (t2 > t1) {\n                return t1;\n            }\n            while (t0 < t1) {\n                x2 = sampleCurveX(t2);\n                if (abs(x2 - x) < epsilon) {\n                    return t2;\n                }\n                if (x > x2) {\n                    t0 = t2;\n                } else {\n                    t1 = t2;\n                }\n                t2 = (t1 - t0) / 2 + t0;\n            }\n            return t2;\n        }\n        return solve(t, 1 / (200 * duration));\n    }\n    elproto.onAnimation = function (f) {\n        this._run = f || 0;\n        return this;\n    };\n    elproto.animate = function (params, ms, easing, callback) {\n        var element = this;\n        element.timeouts = element.timeouts || [];\n        if (R.is(easing, \"function\") || !easing) {\n            callback = easing || null;\n        }\n        if (element.removed) {\n            callback && callback.call(element);\n            return element;\n        }\n        var from = {},\n            to = {},\n            animateable = false,\n            diff = {};\n        for (var attr in params) if (params[has](attr)) {\n            if (availableAnimAttrs[has](attr) || element.paper.customAttributes[has](attr)) {\n                animateable = true;\n                from[attr] = element.attr(attr);\n                (from[attr] == null) && (from[attr] = availableAttrs[attr]);\n                to[attr] = params[attr];\n                switch (availableAnimAttrs[attr]) {\n                    case \"along\":\n                        var len = getTotalLength(params[attr]);\n                        var point = getPointAtLength(params[attr], len * !!params.back);\n                        var bb = element.getBBox();\n                        diff[attr] = len / ms;\n                        diff.tx = bb.x;\n                        diff.ty = bb.y;\n                        diff.sx = point.x;\n                        diff.sy = point.y;\n                        to.rot = params.rot;\n                        to.back = params.back;\n                        to.len = len;\n                        params.rot && (diff.r = toFloat(element.rotate()) || 0);\n                        break;\n                    case nu:\n                        diff[attr] = (to[attr] - from[attr]) / ms;\n                        break;\n                    case \"colour\":\n                        from[attr] = R.getRGB(from[attr]);\n                        var toColour = R.getRGB(to[attr]);\n                        diff[attr] = {\n                            r: (toColour.r - from[attr].r) / ms,\n                            g: (toColour.g - from[attr].g) / ms,\n                            b: (toColour.b - from[attr].b) / ms\n                        };\n                        break;\n                    case \"path\":\n                        var pathes = path2curve(from[attr], to[attr]);\n                        from[attr] = pathes[0];\n                        var toPath = pathes[1];\n                        diff[attr] = [];\n                        for (var i = 0, ii = from[attr][length]; i < ii; i++) {\n                            diff[attr][i] = [0];\n                            for (var j = 1, jj = from[attr][i][length]; j < jj; j++) {\n                                diff[attr][i][j] = (toPath[i][j] - from[attr][i][j]) / ms;\n                            }\n                        }\n                        break;\n                    case \"csv\":\n                        var values = Str(params[attr])[split](separator),\n                            from2 = Str(from[attr])[split](separator);\n                        switch (attr) {\n                            case \"translation\":\n                                from[attr] = [0, 0];\n                                diff[attr] = [values[0] / ms, values[1] / ms];\n                            break;\n                            case \"rotation\":\n                                from[attr] = (from2[1] == values[1] && from2[2] == values[2]) ? from2 : [0, values[1], values[2]];\n                                diff[attr] = [(values[0] - from[attr][0]) / ms, 0, 0];\n                            break;\n                            case \"scale\":\n                                params[attr] = values;\n                                from[attr] = Str(from[attr])[split](separator);\n                                diff[attr] = [(values[0] - from[attr][0]) / ms, (values[1] - from[attr][1]) / ms, 0, 0];\n                            break;\n                            case \"clip-rect\":\n                                from[attr] = Str(from[attr])[split](separator);\n                                diff[attr] = [];\n                                i = 4;\n                                while (i--) {\n                                    diff[attr][i] = (values[i] - from[attr][i]) / ms;\n                                }\n                            break;\n                        }\n                        to[attr] = values;\n                        break;\n                    default:\n                        values = [].concat(params[attr]);\n                        from2 = [].concat(from[attr]);\n                        diff[attr] = [];\n                        i = element.paper.customAttributes[attr][length];\n                        while (i--) {\n                            diff[attr][i] = ((values[i] || 0) - (from2[i] || 0)) / ms;\n                        }\n                        break;\n                }\n            }\n        }\n        if (!animateable) {\n            var attrs = [],\n                lastcall;\n            for (var key in params) if (params[has](key) && animKeyFrames.test(key)) {\n                attr = {value: params[key]};\n                key == \"from\" && (key = 0);\n                key == \"to\" && (key = 100);\n                attr.key = toInt(key, 10);\n                attrs.push(attr);\n            }\n            attrs.sort(sortByKey);\n            if (attrs[0].key) {\n                attrs.unshift({key: 0, value: element.attrs});\n            }\n            for (i = 0, ii = attrs[length]; i < ii; i++) {\n                keyframesRun(attrs[i].value, element, ms / 100 * attrs[i].key, ms / 100 * (attrs[i - 1] && attrs[i - 1].key || 0), attrs[i - 1] && attrs[i - 1].value.callback);\n            }\n            lastcall = attrs[attrs[length] - 1].value.callback;\n            if (lastcall) {\n                element.timeouts.push(setTimeout(function () {lastcall.call(element);}, ms));\n            }\n        } else {\n            var easyeasy = R.easing_formulas[easing];\n            if (!easyeasy) {\n                easyeasy = Str(easing).match(bezierrg);\n                if (easyeasy && easyeasy[length] == 5) {\n                    var curve = easyeasy;\n                    easyeasy = function (t) {\n                        return CubicBezierAtTime(t, +curve[1], +curve[2], +curve[3], +curve[4], ms);\n                    };\n                } else {\n                    easyeasy = function (t) {\n                        return t;\n                    };\n                }\n            }\n            animationElements.push({\n                start: params.start || +new Date,\n                ms: ms,\n                easing: easyeasy,\n                from: from,\n                diff: diff,\n                to: to,\n                el: element,\n                t: {x: 0, y: 0}\n            });\n            R.is(callback, \"function\") && (element._ac = setTimeout(function () {\n                callback.call(element);\n            }, ms));\n            animationElements[length] == 1 && setTimeout(animation);\n        }\n        return this;\n    };\n    elproto.stop = function () {\n        for (var i = 0; i < animationElements.length; i++) {\n            animationElements[i].el.id == this.id && animationElements.splice(i--, 1);\n        }\n        for (i = 0, ii = this.timeouts && this.timeouts.length; i < ii; i++) {\n            clearTimeout(this.timeouts[i]);\n        }\n        this.timeouts = [];\n        clearTimeout(this._ac);\n        delete this._ac;\n        return this;\n    };\n    elproto.translate = function (x, y) {\n        return this.attr({translation: x + \" \" + y});\n    };\n    elproto[toString] = function () {\n        return \"Rapha\\xebl\\u2019s object\";\n    };\n    R.ae = animationElements;\n \n    // Set\n    var Set = function (items) {\n        this.items = [];\n        this[length] = 0;\n        this.type = \"set\";\n        if (items) {\n            for (var i = 0, ii = items[length]; i < ii; i++) {\n                if (items[i] && (items[i].constructor == Element || items[i].constructor == Set)) {\n                    this[this.items[length]] = this.items[this.items[length]] = items[i];\n                    this[length]++;\n                }\n            }\n        }\n    };\n    Set[proto][push] = function () {\n        var item,\n            len;\n        for (var i = 0, ii = arguments[length]; i < ii; i++) {\n            item = arguments[i];\n            if (item && (item.constructor == Element || item.constructor == Set)) {\n                len = this.items[length];\n                this[len] = this.items[len] = item;\n                this[length]++;\n            }\n        }\n        return this;\n    };\n    Set[proto].pop = function () {\n        delete this[this[length]--];\n        return this.items.pop();\n    };\n    for (var method in elproto) if (elproto[has](method)) {\n        Set[proto][method] = (function (methodname) {\n            return function () {\n                for (var i = 0, ii = this.items[length]; i < ii; i++) {\n                    this.items[i][methodname][apply](this.items[i], arguments);\n                }\n                return this;\n            };\n        })(method);\n    }\n    Set[proto].attr = function (name, value) {\n        if (name && R.is(name, array) && R.is(name[0], \"object\")) {\n            for (var j = 0, jj = name[length]; j < jj; j++) {\n                this.items[j].attr(name[j]);\n            }\n        } else {\n            for (var i = 0, ii = this.items[length]; i < ii; i++) {\n                this.items[i].attr(name, value);\n            }\n        }\n        return this;\n    };\n    Set[proto].animate = function (params, ms, easing, callback) {\n        (R.is(easing, \"function\") || !easing) && (callback = easing || null);\n        var len = this.items[length],\n            i = len,\n            item,\n            set = this,\n            collector;\n        callback && (collector = function () {\n            !--len && callback.call(set);\n        });\n        easing = R.is(easing, string) ? easing : collector;\n        item = this.items[--i].animate(params, ms, easing, collector);\n        while (i--) {\n            this.items[i] && !this.items[i].removed && this.items[i].animateWith(item, params, ms, easing, collector);\n        }\n        return this;\n    };\n    Set[proto].insertAfter = function (el) {\n        var i = this.items[length];\n        while (i--) {\n            this.items[i].insertAfter(el);\n        }\n        return this;\n    };\n    Set[proto].getBBox = function () {\n        var x = [],\n            y = [],\n            w = [],\n            h = [];\n        for (var i = this.items[length]; i--;) {\n            var box = this.items[i].getBBox();\n            x[push](box.x);\n            y[push](box.y);\n            w[push](box.x + box.width);\n            h[push](box.y + box.height);\n        }\n        x = mmin[apply](0, x);\n        y = mmin[apply](0, y);\n        return {\n            x: x,\n            y: y,\n            width: mmax[apply](0, w) - x,\n            height: mmax[apply](0, h) - y\n        };\n    };\n    Set[proto].clone = function (s) {\n        s = new Set;\n        for (var i = 0, ii = this.items[length]; i < ii; i++) {\n            s[push](this.items[i].clone());\n        }\n        return s;\n    };\n\n    R.registerFont = function (font) {\n        if (!font.face) {\n            return font;\n        }\n        this.fonts = this.fonts || {};\n        var fontcopy = {\n                w: font.w,\n                face: {},\n                glyphs: {}\n            },\n            family = font.face[\"font-family\"];\n        for (var prop in font.face) if (font.face[has](prop)) {\n            fontcopy.face[prop] = font.face[prop];\n        }\n        if (this.fonts[family]) {\n            this.fonts[family][push](fontcopy);\n        } else {\n            this.fonts[family] = [fontcopy];\n        }\n        if (!font.svg) {\n            fontcopy.face[\"units-per-em\"] = toInt(font.face[\"units-per-em\"], 10);\n            for (var glyph in font.glyphs) if (font.glyphs[has](glyph)) {\n                var path = font.glyphs[glyph];\n                fontcopy.glyphs[glyph] = {\n                    w: path.w,\n                    k: {},\n                    d: path.d && \"M\" + path.d[rp](/[mlcxtrv]/g, function (command) {\n                            return {l: \"L\", c: \"C\", x: \"z\", t: \"m\", r: \"l\", v: \"c\"}[command] || \"M\";\n                        }) + \"z\"\n                };\n                if (path.k) {\n                    for (var k in path.k) if (path[has](k)) {\n                        fontcopy.glyphs[glyph].k[k] = path.k[k];\n                    }\n                }\n            }\n        }\n        return font;\n    };\n    paperproto.getFont = function (family, weight, style, stretch) {\n        stretch = stretch || \"normal\";\n        style = style || \"normal\";\n        weight = +weight || {normal: 400, bold: 700, lighter: 300, bolder: 800}[weight] || 400;\n        if (!R.fonts) {\n            return;\n        }\n        var font = R.fonts[family];\n        if (!font) {\n            var name = new RegExp(\"(^|\\\\s)\" + family[rp](/[^\\w\\d\\s+!~.:_-]/g, E) + \"(\\\\s|$)\", \"i\");\n            for (var fontName in R.fonts) if (R.fonts[has](fontName)) {\n                if (name.test(fontName)) {\n                    font = R.fonts[fontName];\n                    break;\n                }\n            }\n        }\n        var thefont;\n        if (font) {\n            for (var i = 0, ii = font[length]; i < ii; i++) {\n                thefont = font[i];\n                if (thefont.face[\"font-weight\"] == weight && (thefont.face[\"font-style\"] == style || !thefont.face[\"font-style\"]) && thefont.face[\"font-stretch\"] == stretch) {\n                    break;\n                }\n            }\n        }\n        return thefont;\n    };\n    paperproto.print = function (x, y, string, font, size, origin, letter_spacing) {\n        origin = origin || \"middle\"; // baseline|middle\n        letter_spacing = mmax(mmin(letter_spacing || 0, 1), -1);\n        var out = this.set(),\n            letters = Str(string)[split](E),\n            shift = 0,\n            path = E,\n            scale;\n        R.is(font, string) && (font = this.getFont(font));\n        if (font) {\n            scale = (size || 16) / font.face[\"units-per-em\"];\n            var bb = font.face.bbox.split(separator),\n                top = +bb[0],\n                height = +bb[1] + (origin == \"baseline\" ? bb[3] - bb[1] + (+font.face.descent) : (bb[3] - bb[1]) / 2);\n            for (var i = 0, ii = letters[length]; i < ii; i++) {\n                var prev = i && font.glyphs[letters[i - 1]] || {},\n                    curr = font.glyphs[letters[i]];\n                shift += i ? (prev.w || font.w) + (prev.k && prev.k[letters[i]] || 0) + (font.w * letter_spacing) : 0;\n                curr && curr.d && out[push](this.path(curr.d).attr({fill: \"#000\", stroke: \"none\", translation: [shift, 0]}));\n            }\n            out.scale(scale, scale, top, height).translate(x - top, y - height);\n        }\n        return out;\n    };\n\n    R.format = function (token, params) {\n        var args = R.is(params, array) ? [0][concat](params) : arguments;\n        token && R.is(token, string) && args[length] - 1 && (token = token[rp](formatrg, function (str, i) {\n            return args[++i] == null ? E : args[i];\n        }));\n        return token || E;\n    };\n    R.ninja = function () {\n        oldRaphael.was ? (win.Raphael = oldRaphael.is) : delete Raphael;\n        return R;\n    };\n    R.el = elproto;\n    R.st = Set[proto];\n\n    oldRaphael.was ? (win.Raphael = R) : (Raphael = R);\n})();/*!\n * g.Raphael 0.4.1 - Charting library, based on Raphaël\n *\n * Copyright (c) 2009 Dmitry Baranovskiy (http://g.raphaeljs.com)\n * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.\n */\n \n \n(function () {\n    var mmax = Math.max,\n        mmin = Math.min;\n    Raphael.fn.g = Raphael.fn.g || {};\n    Raphael.fn.g.markers = {\n        disc: \"disc\",\n        o: \"disc\",\n        flower: \"flower\",\n        f: \"flower\",\n        diamond: \"diamond\",\n        d: \"diamond\",\n        square: \"square\",\n        s: \"square\",\n        triangle: \"triangle\",\n        t: \"triangle\",\n        star: \"star\",\n        \"*\": \"star\",\n        cross: \"cross\",\n        x: \"cross\",\n        plus: \"plus\",\n        \"+\": \"plus\",\n        arrow: \"arrow\",\n        \"->\": \"arrow\"\n    };\n    Raphael.fn.g.shim = {stroke: \"none\", fill: \"#000\", \"fill-opacity\": 0};\n    Raphael.fn.g.txtattr = {font: \"12px Arial, sans-serif\"};\n    Raphael.fn.g.colors = [];\n    var hues = [.6, .2, .05, .1333, .75, 0];\n    for (var i = 0; i < 10; i++) {\n        if (i < hues.length) {\n            Raphael.fn.g.colors.push(\"hsb(\" + hues[i] + \", .75, .75)\");\n        } else {\n            Raphael.fn.g.colors.push(\"hsb(\" + hues[i - hues.length] + \", 1, .5)\");\n        }\n    }\n    Raphael.fn.g.text = function (x, y, text) {\n        return this.text(x, y, text).attr(this.g.txtattr);\n    };\n    Raphael.fn.g.labelise = function (label, val, total) {\n        if (label) {\n            return (label + \"\").replace(/(##+(?:\\.#+)?)|(%%+(?:\\.%+)?)/g, function (all, value, percent) {\n                if (value) {\n                    return (+val).toFixed(value.replace(/^#+\\.?/g, \"\").length);\n                }\n                if (percent) {\n                    return (val * 100 / total).toFixed(percent.replace(/^%+\\.?/g, \"\").length) + \"%\";\n                }\n            });\n        } else {\n            return (+val).toFixed(0);\n        }\n    };\n\n    Raphael.fn.g.finger = function (x, y, width, height, dir, ending, isPath) {\n        // dir 0 for horisontal and 1 for vertical\n        if ((dir && !height) || (!dir && !width)) {\n            return isPath ? \"\" : this.path();\n        }\n        ending = {square: \"square\", sharp: \"sharp\", soft: \"soft\"}[ending] || \"round\";\n        var path;\n        height = Math.round(height);\n        width = Math.round(width);\n        x = Math.round(x);\n        y = Math.round(y);\n        switch (ending) {\n            case \"round\":\n            if (!dir) {\n                var r = ~~(height / 2);\n                if (width < r) {\n                    r = width;\n                    path = [\"M\", x + .5, y + .5 - ~~(height / 2), \"l\", 0, 0, \"a\", r, ~~(height / 2), 0, 0, 1, 0, height, \"l\", 0, 0, \"z\"];\n                } else {\n                    path = [\"M\", x + .5, y + .5 - r, \"l\", width - r, 0, \"a\", r, r, 0, 1, 1, 0, height, \"l\", r - width, 0, \"z\"];\n                }\n            } else {\n                r = ~~(width / 2);\n                if (height < r) {\n                    r = height;\n                    path = [\"M\", x - ~~(width / 2), y, \"l\", 0, 0, \"a\", ~~(width / 2), r, 0, 0, 1, width, 0, \"l\", 0, 0, \"z\"];\n                } else {\n                    path = [\"M\", x - r, y, \"l\", 0, r - height, \"a\", r, r, 0, 1, 1, width, 0, \"l\", 0, height - r, \"z\"];\n                }\n            }\n            break;\n            case \"sharp\":\n            if (!dir) {\n                var half = ~~(height / 2);\n                path = [\"M\", x, y + half, \"l\", 0, -height, mmax(width - half, 0), 0, mmin(half, width), half, -mmin(half, width), half + (half * 2 < height), \"z\"];\n            } else {\n                half = ~~(width / 2);\n                path = [\"M\", x + half, y, \"l\", -width, 0, 0, -mmax(height - half, 0), half, -mmin(half, height), half, mmin(half, height), half, \"z\"];\n            }\n            break;\n            case \"square\":\n            if (!dir) {\n                path = [\"M\", x, y + ~~(height / 2), \"l\", 0, -height, width, 0, 0, height, \"z\"];\n            } else {\n                path = [\"M\", x + ~~(width / 2), y, \"l\", 1 - width, 0, 0, -height, width - 1, 0, \"z\"];\n            }\n            break;\n            case \"soft\":\n            if (!dir) {\n                r = mmin(width, Math.round(height / 5));\n                path = [\"M\", x + .5, y + .5 - ~~(height / 2), \"l\", width - r, 0, \"a\", r, r, 0, 0, 1, r, r, \"l\", 0, height - r * 2, \"a\", r, r, 0, 0, 1, -r, r, \"l\", r - width, 0, \"z\"];\n            } else {\n                r = mmin(Math.round(width / 5), height);\n                path = [\"M\", x - ~~(width / 2), y, \"l\", 0, r - height, \"a\", r, r, 0, 0, 1, r, -r, \"l\", width - 2 * r, 0, \"a\", r, r, 0, 0, 1, r, r, \"l\", 0, height - r, \"z\"];\n            }\n        }\n        if (isPath) {\n            return path.join(\",\");\n        } else {\n            return this.path(path);\n        }\n    };\n\n    // Symbols\n    Raphael.fn.g.disc = function (cx, cy, r) {\n        return this.circle(cx, cy, r);\n    };\n    Raphael.fn.g.line = function (cx, cy, r) {\n        return this.rect(cx - r, cy - r / 5, 2 * r, 2 * r / 5);\n    };\n    Raphael.fn.g.square = function (cx, cy, r) {\n        r = r * .7;\n        return this.rect(cx - r, cy - r, 2 * r, 2 * r);\n    };\n    Raphael.fn.g.triangle = function (cx, cy, r) {\n        r *= 1.75;\n        return this.path(\"M\".concat(cx, \",\", cy, \"m0-\", r * .58, \"l\", r * .5, \",\", r * .87, \"-\", r, \",0z\"));\n    };\n    Raphael.fn.g.diamond = function (cx, cy, r) {\n        return this.path([\"M\", cx, cy - r, \"l\", r, r, -r, r, -r, -r, r, -r, \"z\"]);\n    };\n    Raphael.fn.g.flower = function (cx, cy, r, n) {\n        r = r * 1.25;\n        var rout = r,\n            rin = rout * .5;\n        n = +n < 3 || !n ? 5 : n;\n        var points = [\"M\", cx, cy + rin, \"Q\"],\n            R;\n        for (var i = 1; i < n * 2 + 1; i++) {\n            R = i % 2 ? rout : rin;\n            points = points.concat([+(cx + R * Math.sin(i * Math.PI / n)).toFixed(3), +(cy + R * Math.cos(i * Math.PI / n)).toFixed(3)]);\n        }\n        points.push(\"z\");\n        return this.path(points.join(\",\"));\n    };\n    Raphael.fn.g.star = function (cx, cy, r, r2, rays) {\n        r2 = r2 || r * .382;\n        rays = rays || 5;\n        var points = [\"M\", cx, cy + r2, \"L\"],\n            R;\n        for (var i = 1; i < rays * 2; i++) {\n            R = i % 2 ? r : r2;\n            points = points.concat([(cx + R * Math.sin(i * Math.PI / rays)), (cy + R * Math.cos(i * Math.PI / rays))]);\n        }\n        points.push(\"z\");\n        return this.path(points.join(\",\"));\n    };\n    Raphael.fn.g.cross = function (cx, cy, r) {\n        r = r / 2.5;\n        return this.path(\"M\".concat(cx - r, \",\", cy, \"l\", [-r, -r, r, -r, r, r, r, -r, r, r, -r, r, r, r, -r, r, -r, -r, -r, r, -r, -r, \"z\"]));\n    };\n    Raphael.fn.g.plus = function (cx, cy, r) {\n        r = r / 2;\n        return this.path(\"M\".concat(cx - r / 2, \",\", cy - r / 2, \"l\", [0, -r, r, 0, 0, r, r, 0, 0, r, -r, 0, 0, r, -r, 0, 0, -r, -r, 0, 0, -r, \"z\"]));\n    };\n    Raphael.fn.g.arrow = function (cx, cy, r) {\n        return this.path(\"M\".concat(cx - r * .7, \",\", cy - r * .4, \"l\", [r * .6, 0, 0, -r * .4, r, r * .8, -r, r * .8, 0, -r * .4, -r * .6, 0], \"z\"));\n    };\n\n    // Tooltips\n    Raphael.fn.g.tag = function (x, y, text, angle, r) {\n        angle = angle || 0;\n        r = r == null ? 5 : r;\n        text = text == null ? \"$9.99\" : text;\n        var R = .5522 * r,\n            res = this.set(),\n            d = 3;\n        res.push(this.path().attr({fill: \"#000\", stroke: \"#000\"}));\n        res.push(this.text(x, y, text).attr(this.g.txtattr).attr({fill: \"#fff\", \"font-family\": \"Helvetica, Arial\"}));\n        res.update = function () {\n            this.rotate(0, x, y);\n            var bb = this[1].getBBox();\n            if (bb.height >= r * 2) {\n                this[0].attr({path: [\"M\", x, y + r, \"a\", r, r, 0, 1, 1, 0, -r * 2, r, r, 0, 1, 1, 0, r * 2, \"m\", 0, -r * 2 -d, \"a\", r + d, r + d, 0, 1, 0, 0, (r + d) * 2, \"L\", x + r + d, y + bb.height / 2 + d, \"l\", bb.width + 2 * d, 0, 0, -bb.height - 2 * d, -bb.width - 2 * d, 0, \"L\", x, y - r - d].join(\",\")});\n            } else {\n                var dx = Math.sqrt(Math.pow(r + d, 2) - Math.pow(bb.height / 2 + d, 2));\n                this[0].attr({path: [\"M\", x, y + r, \"c\", -R, 0, -r, R - r, -r, -r, 0, -R, r - R, -r, r, -r, R, 0, r, r - R, r, r, 0, R, R - r, r, -r, r, \"M\", x + dx, y - bb.height / 2 - d, \"a\", r + d, r + d, 0, 1, 0, 0, bb.height + 2 * d, \"l\", r + d - dx + bb.width + 2 * d, 0, 0, -bb.height - 2 * d, \"L\", x + dx, y - bb.height / 2 - d].join(\",\")});\n            }\n            this[1].attr({x: x + r + d + bb.width / 2, y: y});\n            angle = (360 - angle) % 360;\n            this.rotate(angle, x, y);\n            angle > 90 && angle < 270 && this[1].attr({x: x - r - d - bb.width / 2, y: y, rotation: [180 + angle, x, y]});\n            return this;\n        };\n        res.update();\n        return res;\n    };\n    Raphael.fn.g.popupit = function (x, y, set, dir, size) {\n        dir = dir == null ? 2 : dir;\n        size = size || 5;\n        x = Math.round(x);\n        y = Math.round(y);\n        var bb = set.getBBox(),\n            w = Math.round(bb.width / 2),\n            h = Math.round(bb.height / 2),\n            dx = [0, w + size * 2, 0, -w - size * 2],\n            dy = [-h * 2 - size * 3, -h - size, 0, -h - size],\n            p = [\"M\", x - dx[dir], y - dy[dir], \"l\", -size, (dir == 2) * -size, -mmax(w - size, 0), 0, \"a\", size, size, 0, 0, 1, -size, -size,\n                \"l\", 0, -mmax(h - size, 0), (dir == 3) * -size, -size, (dir == 3) * size, -size, 0, -mmax(h - size, 0), \"a\", size, size, 0, 0, 1, size, -size,\n                \"l\", mmax(w - size, 0), 0, size, !dir * -size, size, !dir * size, mmax(w - size, 0), 0, \"a\", size, size, 0, 0, 1, size, size,\n                \"l\", 0, mmax(h - size, 0), (dir == 1) * size, size, (dir == 1) * -size, size, 0, mmax(h - size, 0), \"a\", size, size, 0, 0, 1, -size, size,\n                \"l\", -mmax(w - size, 0), 0, \"z\"].join(\",\"),\n            xy = [{x: x, y: y + size * 2 + h}, {x: x - size * 2 - w, y: y}, {x: x, y: y - size * 2 - h}, {x: x + size * 2 + w, y: y}][dir];\n        set.translate(xy.x - w - bb.x, xy.y - h - bb.y);\n        return this.path(p).attr({fill: \"#000\", stroke: \"none\"}).insertBefore(set.node ? set : set[0]);\n    };\n    Raphael.fn.g.popup = function (x, y, text, dir, size) {\n        dir = dir == null ? 2 : dir > 3 ? 3 : dir;\n        size = size || 5;\n        text = text || \"$9.99\";\n        var res = this.set(),\n            d = 3;\n        res.push(this.path().attr({fill: \"#000\", stroke: \"#000\"}));\n        res.push(this.text(x, y, text).attr(this.g.txtattr).attr({fill: \"#fff\", \"font-family\": \"Helvetica, Arial\"}));\n        res.update = function (X, Y, withAnimation) {\n            X = X || x;\n            Y = Y || y;\n            var bb = this[1].getBBox(),\n                w = bb.width / 2,\n                h = bb.height / 2,\n                dx = [0, w + size * 2, 0, -w - size * 2],\n                dy = [-h * 2 - size * 3, -h - size, 0, -h - size],\n                p = [\"M\", X - dx[dir], Y - dy[dir], \"l\", -size, (dir == 2) * -size, -mmax(w - size, 0), 0, \"a\", size, size, 0, 0, 1, -size, -size,\n                    \"l\", 0, -mmax(h - size, 0), (dir == 3) * -size, -size, (dir == 3) * size, -size, 0, -mmax(h - size, 0), \"a\", size, size, 0, 0, 1, size, -size,\n                    \"l\", mmax(w - size, 0), 0, size, !dir * -size, size, !dir * size, mmax(w - size, 0), 0, \"a\", size, size, 0, 0, 1, size, size,\n                    \"l\", 0, mmax(h - size, 0), (dir == 1) * size, size, (dir == 1) * -size, size, 0, mmax(h - size, 0), \"a\", size, size, 0, 0, 1, -size, size,\n                    \"l\", -mmax(w - size, 0), 0, \"z\"].join(\",\"),\n                xy = [{x: X, y: Y + size * 2 + h}, {x: X - size * 2 - w, y: Y}, {x: X, y: Y - size * 2 - h}, {x: X + size * 2 + w, y: Y}][dir];\n            xy.path = p;\n            if (withAnimation) {\n                this.animate(xy, 500, \">\");\n            } else {\n                this.attr(xy);\n            }\n            return this;\n        };\n        return res.update(x, y);\n    };\n    Raphael.fn.g.flag = function (x, y, text, angle) {\n        angle = angle || 0;\n        text = text || \"$9.99\";\n        var res = this.set(),\n            d = 3;\n        res.push(this.path().attr({fill: \"#000\", stroke: \"#000\"}));\n        res.push(this.text(x, y, text).attr(this.g.txtattr).attr({fill: \"#fff\", \"font-family\": \"Helvetica, Arial\"}));\n        res.update = function (x, y) {\n            this.rotate(0, x, y);\n            var bb = this[1].getBBox(),\n                h = bb.height / 2;\n            this[0].attr({path: [\"M\", x, y, \"l\", h + d, -h - d, bb.width + 2 * d, 0, 0, bb.height + 2 * d, -bb.width - 2 * d, 0, \"z\"].join(\",\")});\n            this[1].attr({x: x + h + d + bb.width / 2, y: y});\n            angle = 360 - angle;\n            this.rotate(angle, x, y);\n            angle > 90 && angle < 270 && this[1].attr({x: x - r - d - bb.width / 2, y: y, rotation: [180 + angle, x, y]});\n            return this;\n        };\n        return res.update(x, y);\n    };\n    Raphael.fn.g.label = function (x, y, text) {\n        var res = this.set();\n        res.push(this.rect(x, y, 10, 10).attr({stroke: \"none\", fill: \"#000\"}));\n        res.push(this.text(x, y, text).attr(this.g.txtattr).attr({fill: \"#fff\"}));\n        res.update = function () {\n            var bb = this[1].getBBox(),\n                r = mmin(bb.width + 10, bb.height + 10) / 2;\n            this[0].attr({x: bb.x - r / 2, y: bb.y - r / 2, width: bb.width + r, height: bb.height + r, r: r});\n        };\n        res.update();\n        return res;\n    };\n    Raphael.fn.g.labelit = function (set) {\n        var bb = set.getBBox(),\n            r = mmin(20, bb.width + 10, bb.height + 10) / 2;\n        return this.rect(bb.x - r / 2, bb.y - r / 2, bb.width + r, bb.height + r, r).attr({stroke: \"none\", fill: \"#000\"}).insertBefore(set.node ? set : set[0]);\n    };\n    Raphael.fn.g.drop = function (x, y, text, size, angle) {\n        size = size || 30;\n        angle = angle || 0;\n        var res = this.set();\n        res.push(this.path([\"M\", x, y, \"l\", size, 0, \"A\", size * .4, size * .4, 0, 1, 0, x + size * .7, y - size * .7, \"z\"]).attr({fill: \"#000\", stroke: \"none\", rotation: [22.5 - angle, x, y]}));\n        angle = (angle + 90) * Math.PI / 180;\n        res.push(this.text(x + size * Math.sin(angle), y + size * Math.cos(angle), text).attr(this.g.txtattr).attr({\"font-size\": size * 12 / 30, fill: \"#fff\"}));\n        res.drop = res[0];\n        res.text = res[1];\n        return res;\n    };\n    Raphael.fn.g.blob = function (x, y, text, angle, size) {\n        angle = (+angle + 1 ? angle : 45) + 90;\n        size = size || 12;\n        var rad = Math.PI / 180,\n            fontSize = size * 12 / 12;\n        var res = this.set();\n        res.push(this.path().attr({fill: \"#000\", stroke: \"none\"}));\n        res.push(this.text(x + size * Math.sin((angle) * rad), y + size * Math.cos((angle) * rad) - fontSize / 2, text).attr(this.g.txtattr).attr({\"font-size\": fontSize, fill: \"#fff\"}));\n        res.update = function (X, Y, withAnimation) {\n            X = X || x;\n            Y = Y || y;\n            var bb = this[1].getBBox(),\n                w = mmax(bb.width + fontSize, size * 25 / 12),\n                h = mmax(bb.height + fontSize, size * 25 / 12),\n                x2 = X + size * Math.sin((angle - 22.5) * rad),\n                y2 = Y + size * Math.cos((angle - 22.5) * rad),\n                x1 = X + size * Math.sin((angle + 22.5) * rad),\n                y1 = Y + size * Math.cos((angle + 22.5) * rad),\n                dx = (x1 - x2) / 2,\n                dy = (y1 - y2) / 2,\n                rx = w / 2,\n                ry = h / 2,\n                k = -Math.sqrt(Math.abs(rx * rx * ry * ry - rx * rx * dy * dy - ry * ry * dx * dx) / (rx * rx * dy * dy + ry * ry * dx * dx)),\n                cx = k * rx * dy / ry + (x1 + x2) / 2,\n                cy = k * -ry * dx / rx + (y1 + y2) / 2;\n            if (withAnimation) {\n                this.animate({x: cx, y: cy, path: [\"M\", x, y, \"L\", x1, y1, \"A\", rx, ry, 0, 1, 1, x2, y2, \"z\"].join(\",\")}, 500, \">\");\n            } else {\n                this.attr({x: cx, y: cy, path: [\"M\", x, y, \"L\", x1, y1, \"A\", rx, ry, 0, 1, 1, x2, y2, \"z\"].join(\",\")});\n            }\n            return this;\n        };\n        res.update(x, y);\n        return res;\n    };\n\n    Raphael.fn.g.colorValue = function (value, total, s, b) {\n        return \"hsb(\" + [mmin((1 - value / total) * .4, 1), s || .75, b || .75] + \")\";\n    };\n\n    Raphael.fn.g.snapEnds = function (from, to, steps) {\n        var f = from,\n            t = to;\n        if (f == t) {\n            return {from: f, to: t, power: 0};\n        }\n        function round(a) {\n            return Math.abs(a - .5) < .25 ? ~~(a) + .5 : Math.round(a);\n        }\n        var d = (t - f) / steps,\n            r = ~~(d),\n            R = r,\n            i = 0;\n        if (r) {\n            while (R) {\n                i--;\n                R = ~~(d * Math.pow(10, i)) / Math.pow(10, i);\n            }\n            i ++;\n        } else {\n            while (!r) {\n                i = i || 1;\n                r = ~~(d * Math.pow(10, i)) / Math.pow(10, i);\n                i++;\n            }\n            i && i--;\n        }\n        t = round(to * Math.pow(10, i)) / Math.pow(10, i);\n        if (t < to) {\n            t = round((to + .5) * Math.pow(10, i)) / Math.pow(10, i);\n        }\n        f = round((from - (i > 0 ? 0 : .5)) * Math.pow(10, i)) / Math.pow(10, i);\n        return {from: f, to: t, power: i};\n    };\n    Raphael.fn.g.axis = function (x, y, length, from, to, steps, orientation, labels, type, dashsize) {\n        dashsize = dashsize == null ? 2 : dashsize;\n        type = type || \"t\";\n        steps = steps || 10;\n        var path = type == \"|\" || type == \" \" ? [\"M\", x + .5, y, \"l\", 0, .001] : orientation == 1 || orientation == 3 ? [\"M\", x + .5, y, \"l\", 0, -length] : [\"M\", x, y + .5, \"l\", length, 0],\n            ends = this.g.snapEnds(from, to, steps),\n            f = ends.from,\n            t = ends.to,\n            i = ends.power,\n            j = 0,\n            text = this.set();\n        d = (t - f) / steps;\n        var label = f,\n            rnd = i > 0 ? i : 0;\n            dx = length / steps;\n        if (+orientation == 1 || +orientation == 3) {\n            var Y = y,\n                addon = (orientation - 1 ? 1 : -1) * (dashsize + 3 + !!(orientation - 1));\n            while (Y >= y - length) {\n                type != \"-\" && type != \" \" && (path = path.concat([\"M\", x - (type == \"+\" || type == \"|\" ? dashsize : !(orientation - 1) * dashsize * 2), Y + .5, \"l\", dashsize * 2 + 1, 0]));\n                text.push(this.text(x + addon, Y, (labels && labels[j++]) || (Math.round(label) == label ? label : +label.toFixed(rnd))).attr(this.g.txtattr).attr({\"text-anchor\": orientation - 1 ? \"start\" : \"end\"}));\n                label += d;\n                Y -= dx;\n            }\n            if (Math.round(Y + dx - (y - length))) {\n                type != \"-\" && type != \" \" && (path = path.concat([\"M\", x - (type == \"+\" || type == \"|\" ? dashsize : !(orientation - 1) * dashsize * 2), y - length + .5, \"l\", dashsize * 2 + 1, 0]));\n                text.push(this.text(x + addon, y - length, (labels && labels[j]) || (Math.round(label) == label ? label : +label.toFixed(rnd))).attr(this.g.txtattr).attr({\"text-anchor\": orientation - 1 ? \"start\" : \"end\"}));\n            }\n        } else {\n            label = f;\n            rnd = (i > 0) * i;\n            addon = (orientation ? -1 : 1) * (dashsize + 9 + !orientation);\n            var X = x,\n                dx = length / steps,\n                txt = 0,\n                prev = 0;\n            while (X <= x + length) {\n                type != \"-\" && type != \" \" && (path = path.concat([\"M\", X + .5, y - (type == \"+\" ? dashsize : !!orientation * dashsize * 2), \"l\", 0, dashsize * 2 + 1]));\n                text.push(txt = this.text(X, y + addon, (labels && labels[j++]) || (Math.round(label) == label ? label : +label.toFixed(rnd))).attr(this.g.txtattr));\n                var bb = txt.getBBox();\n                if (prev >= bb.x - 5) {\n                    text.pop(text.length - 1).remove();\n                } else {\n                    prev = bb.x + bb.width;\n                }\n                label += d;\n                X += dx;\n            }\n            if (Math.round(X - dx - x - length)) {\n                type != \"-\" && type != \" \" && (path = path.concat([\"M\", x + length + .5, y - (type == \"+\" ? dashsize : !!orientation * dashsize * 2), \"l\", 0, dashsize * 2 + 1]));\n                text.push(this.text(x + length, y + addon, (labels && labels[j]) || (Math.round(label) == label ? label : +label.toFixed(rnd))).attr(this.g.txtattr));\n            }\n        }\n        var res = this.path(path);\n        res.text = text;\n        res.all = this.set([res, text]);\n        res.remove = function () {\n            this.text.remove();\n            this.constructor.prototype.remove.call(this);\n        };\n        return res;\n    };\n\n    Raphael.el.lighter = function (times) {\n        times = times || 2;\n        var fs = [this.attrs.fill, this.attrs.stroke];\n        this.fs = this.fs || [fs[0], fs[1]];\n        fs[0] = Raphael.rgb2hsb(Raphael.getRGB(fs[0]).hex);\n        fs[1] = Raphael.rgb2hsb(Raphael.getRGB(fs[1]).hex);\n        fs[0].b = mmin(fs[0].b * times, 1);\n        fs[0].s = fs[0].s / times;\n        fs[1].b = mmin(fs[1].b * times, 1);\n        fs[1].s = fs[1].s / times;\n        this.attr({fill: \"hsb(\" + [fs[0].h, fs[0].s, fs[0].b] + \")\", stroke: \"hsb(\" + [fs[1].h, fs[1].s, fs[1].b] + \")\"});\n    };\n    Raphael.el.darker = function (times) {\n        times = times || 2;\n        var fs = [this.attrs.fill, this.attrs.stroke];\n        this.fs = this.fs || [fs[0], fs[1]];\n        fs[0] = Raphael.rgb2hsb(Raphael.getRGB(fs[0]).hex);\n        fs[1] = Raphael.rgb2hsb(Raphael.getRGB(fs[1]).hex);\n        fs[0].s = mmin(fs[0].s * times, 1);\n        fs[0].b = fs[0].b / times;\n        fs[1].s = mmin(fs[1].s * times, 1);\n        fs[1].b = fs[1].b / times;\n        this.attr({fill: \"hsb(\" + [fs[0].h, fs[0].s, fs[0].b] + \")\", stroke: \"hsb(\" + [fs[1].h, fs[1].s, fs[1].b] + \")\"});\n    };\n    Raphael.el.original = function () {\n        if (this.fs) {\n            this.attr({fill: this.fs[0], stroke: this.fs[1]});\n            delete this.fs;\n        }\n    };\n})();/*!\n * g.Raphael 0.4.1 - Charting library, based on Raphaël\n *\n * Copyright (c) 2009 Dmitry Baranovskiy (http://g.raphaeljs.com)\n * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.\n */\nRaphael.fn.g.barchart = function (x, y, width, height, values, opts) {\n    opts = opts || {};\n    var type = {round: \"round\", sharp: \"sharp\", soft: \"soft\"}[opts.type] || \"square\",\n        gutter = parseFloat(opts.gutter || \"20%\"),\n        chart = this.set(),\n        bars = this.set(),\n        covers = this.set(),\n        covers2 = this.set(),\n        total = Math.max.apply(Math, values),\n        stacktotal = [],\n        paper = this,\n        multi = 0,\n        colors = opts.colors || this.g.colors,\n        len = values.length;\n    if (this.raphael.is(values[0], \"array\")) {\n        total = [];\n        multi = len;\n        len = 0;\n        for (var i = values.length; i--;) {\n            bars.push(this.set());\n            total.push(Math.max.apply(Math, values[i]));\n            len = Math.max(len, values[i].length);\n        }\n        if (opts.stacked) {\n            for (var i = len; i--;) {\n                var tot = 0;\n                for (var j = values.length; j--;) {\n                    tot +=+ values[j][i] || 0;\n                }\n                stacktotal.push(tot);\n            }\n        }\n        for (var i = values.length; i--;) {\n            if (values[i].length < len) {\n                for (var j = len; j--;) {\n                    values[i].push(0);\n                }\n            }\n        }\n        total = Math.max.apply(Math, opts.stacked ? stacktotal : total);\n    }\n    \n    total = (opts.to) || total;\n    var barwidth = width / (len * (100 + gutter) + gutter) * 100,\n        barhgutter = barwidth * gutter / 100,\n        barvgutter = opts.vgutter == null ? 20 : opts.vgutter,\n        stack = [],\n        X = x + barhgutter,\n        Y = (height - 2 * barvgutter) / total;\n    if (!opts.stretch) {\n        barhgutter = Math.round(barhgutter);\n        barwidth = Math.floor(barwidth);\n    }\n    !opts.stacked && (barwidth /= multi || 1);\n    for (var i = 0; i < len; i++) {\n        stack = [];\n        for (var j = 0; j < (multi || 1); j++) {\n            var h = Math.round((multi ? values[j][i] : values[i]) * Y),\n                top = y + height - barvgutter - h,\n                bar = this.g.finger(Math.round(X + barwidth / 2), top + h, barwidth, h, true, type).attr({stroke: \"none\", fill: colors[multi ? j : i]});\n            if (multi) {\n                bars[j].push(bar);\n            } else {\n                bars.push(bar);\n            }\n            bar.y = top;\n            bar.x = Math.round(X + barwidth / 2);\n            bar.w = barwidth;\n            bar.h = h;\n\t\t\t\t\t\tbar.index = i;\n            bar.value = multi ? values[j][i] : values[i];\n            if (!opts.stacked) {\n                X += barwidth;\n            } else {\n                stack.push(bar);\n            }\n        }\n        if (opts.stacked) {\n            var cvr;\n            covers2.push(cvr = this.rect(stack[0].x - stack[0].w / 2, y, barwidth, height).attr(this.g.shim));\n            cvr.bars = this.set();\n            var size = 0;\n            for (var s = stack.length; s--;) {\n                stack[s].toFront();\n            }\n            for (var s = 0, ss = stack.length; s < ss; s++) {\n                var bar = stack[s],\n                    cover,\n                    h = (size + bar.value) * Y,\n                    path = this.g.finger(bar.x, y + height - barvgutter - !!size * .5, barwidth, h, true, type, 1);\n                cvr.bars.push(bar);\n                size && bar.attr({path: path});\n                bar.h = h;\n                bar.y = y + height - barvgutter - !!size * .5 - h;\n                covers.push(cover = this.rect(bar.x - bar.w / 2, bar.y, barwidth, bar.value * Y).attr(this.g.shim));\n                cover.bar = bar;\n                cover.value = bar.value;\n                size += bar.value;\n            }\n            X += barwidth;\n        }\n        X += barhgutter;\n    }\n    covers2.toFront();\n    X = x + barhgutter;\n    if (!opts.stacked) {\n        for (var i = 0; i < len; i++) {\n            for (var j = 0; j < (multi || 1); j++) {\n                var cover;\n                covers.push(cover = this.rect(Math.round(X), y + barvgutter, barwidth, height - barvgutter).attr(this.g.shim));\n                cover.bar = multi ? bars[j][i] : bars[i];\n                cover.value = cover.bar.value;\n                X += barwidth;\n            }\n            X += barhgutter;\n        }\n    }\n    chart.label = function (labels, isBottom, rotate) {\n        labels = labels || [];\n        isBottom = isBottom == undefined ? true : isBottom;\n\trotate = rotate == undefined ? false : rotate;\n        this.labels = paper.set();\n        var L, l = -Infinity;\n        if (opts.stacked) {\n            for (var i = 0; i < len; i++) {\n                var tot = 0;\n                for (var j = 0; j < (multi || 1); j++) {\n                    tot += multi ? values[j][i] : values[i];\n                    if (j == 0) {\n                        var label = paper.g.labelise(labels[j][i], tot, total);\n                        L = paper.g.text(bars[j][i].x, isBottom ? y + height - barvgutter / 2 : bars[j][i].y - 10, label);\n\t\t\tif (rotate) {\n\t\t\t\tL.rotate(90);\n\t\t\t}\n                        var bb = L.getBBox();\n                        if (bb.x - 7 < l) {\n                            L.remove();\n                        } else {\n                            this.labels.push(L);\n                            l = bb.x + (rotate ? bb.height : bb.width);\n                        }\n                    }\n                }\n            }\n        } else {\n            for (var i = 0; i < len; i++) {\n                for (var j = 0; j < (multi || 1); j++) {\n                    // did not remove the loop because don't yet know whether to accept multi array input for arrays\n                    var label = paper.g.labelise(multi ? labels[0] && labels[0][i] : labels[i], multi ? values[0][i] : values[i], total);\n                     L = paper.g.text(bars[0][i].x, isBottom ? y + 5 + height - barvgutter / 2 : bars[0][i].y - 10, label);\n\t\t\tif (rotate) {\n\t\t\t\tL.rotate(90);\n\t\t\t\t// If we rotated it, we need to move it as well. Still have to use the width\n\t\t\t\t// to get the \"length\" of the label, divided it in two and shift down.\n\t\t\t\tL.translate(0, (L.getBBox().width / 2));\n\t\t\t}\n                    var bb = L.getBBox();\n//                    if (bb.x - 7 < l) {\n                    if (bb.x - (this.getBBox().width) < l) {\n                        L.remove();\n                    } else {\n                        this.labels.push(L);\n                        l = bb.x + (rotate ? bb.height : bb.width);\n                    }\n                }\n            }\n        }\n        return this;\n    };\n    chart.hover = function (fin, fout) {\n        covers2.hide();\n        covers.show();\n        covers.mouseover(fin).mouseout(fout);\n        return this;\n    };\n    chart.hoverColumn = function (fin, fout) {\n        covers.hide();\n        covers2.show();\n        fout = fout || function () {};\n        covers2.mouseover(fin).mouseout(fout);\n        return this;\n    };\n    chart.click = function (f) {\n        covers2.hide();\n        covers.show();\n        covers.click(f);\n        return this;\n    };\n    chart.each = function (f) {\n        if (!Raphael.is(f, \"function\")) {\n            return this;\n        }\n        for (var i = covers.length; i--;) {\n            f.call(covers[i]);\n        }\n        return this;\n    };\n    chart.eachColumn = function (f) {\n        if (!Raphael.is(f, \"function\")) {\n            return this;\n        }\n        for (var i = covers2.length; i--;) {\n            f.call(covers2[i]);\n        }\n        return this;\n    };\n    chart.clickColumn = function (f) {\n        covers.hide();\n        covers2.show();\n        covers2.click(f);\n        return this;\n    };\n    chart.push(bars, covers, covers2);\n    chart.bars = bars;\n    chart.covers = covers;\n    return chart;\n};\nRaphael.fn.g.hbarchart = function (x, y, width, height, values, opts) {\n    opts = opts || {};\n    var type = {round: \"round\", sharp: \"sharp\", soft: \"soft\"}[opts.type] || \"square\",\n        gutter = parseFloat(opts.gutter || \"20%\"),\n        chart = this.set(),\n        bars = this.set(),\n        covers = this.set(),\n        covers2 = this.set(),\n        total = Math.max.apply(Math, values),\n        stacktotal = [],\n        paper = this,\n        multi = 0,\n        colors = opts.colors || this.g.colors,\n        len = values.length;\n    if (this.raphael.is(values[0], \"array\")) {\n        total = [];\n        multi = len;\n        len = 0;\n        for (var i = values.length; i--;) {\n            bars.push(this.set());\n            total.push(Math.max.apply(Math, values[i]));\n            len = Math.max(len, values[i].length);\n        }\n        if (opts.stacked) {\n            for (var i = len; i--;) {\n                var tot = 0;\n                for (var j = values.length; j--;) {\n                    tot +=+ values[j][i] || 0;\n                }\n                stacktotal.push(tot);\n            }\n        }\n        for (var i = values.length; i--;) {\n            if (values[i].length < len) {\n                for (var j = len; j--;) {\n                    values[i].push(0);\n                }\n            }\n        }\n        total = Math.max.apply(Math, opts.stacked ? stacktotal : total);\n    }\n    \n    total = (opts.to) || total;\n    var barheight = Math.floor(height / (len * (100 + gutter) + gutter) * 100),\n        bargutter = Math.floor(barheight * gutter / 100),\n        stack = [],\n        Y = y + bargutter,\n        X = (width - 1) / total;\n    !opts.stacked && (barheight /= multi || 1);\n    for (var i = 0; i < len; i++) {\n        stack = [];\n        for (var j = 0; j < (multi || 1); j++) {\n            var val = multi ? values[j][i] : values[i],\n                bar = this.g.finger(x, Y + barheight / 2, Math.round(val * X), barheight - 1, false, type).attr({stroke: \"none\", fill: colors[multi ? j : i]});\n            if (multi) {\n                bars[j].push(bar);\n            } else {\n                bars.push(bar);\n            }\n            bar.x = x + Math.round(val * X);\n            bar.y = Y + barheight / 2;\n            bar.w = Math.round(val * X);\n            bar.h = barheight;\n            bar.value = +val;\n            if (!opts.stacked) {\n                Y += barheight;\n            } else {\n                stack.push(bar);\n            }\n        }\n        if (opts.stacked) {\n            var cvr = this.rect(x, stack[0].y - stack[0].h / 2, width, barheight).attr(this.g.shim);\n            covers2.push(cvr);\n            cvr.bars = this.set();\n            var size = 0;\n            for (var s = stack.length; s--;) {\n                stack[s].toFront();\n            }\n            for (var s = 0, ss = stack.length; s < ss; s++) {\n                var bar = stack[s],\n                    cover,\n                    val = Math.round((size + bar.value) * X),\n                    path = this.g.finger(x, bar.y, val, barheight - 1, false, type, 1);\n                cvr.bars.push(bar);\n                size && bar.attr({path: path});\n                bar.w = val;\n                bar.x = x + val;\n                covers.push(cover = this.rect(x + size * X, bar.y - bar.h / 2, bar.value * X, barheight).attr(this.g.shim));\n                cover.bar = bar;\n                size += bar.value;\n            }\n            Y += barheight;\n        }\n        Y += bargutter;\n    }\n    covers2.toFront();\n    Y = y + bargutter;\n    if (!opts.stacked) {\n        for (var i = 0; i < len; i++) {\n            for (var j = 0; j < (multi || 1); j++) {\n                var cover = this.rect(x, Y, width, barheight).attr(this.g.shim);\n                covers.push(cover);\n                cover.bar = multi ? bars[j][i] : bars[i];\n                cover.value = cover.bar.value;\n                Y += barheight;\n            }\n            Y += bargutter;\n        }\n    }\n    chart.label = function (labels, isRight) {\n        labels = labels || [];\n        this.labels = paper.set();\n        for (var i = 0; i < len; i++) {\n            for (var j = 0; j < multi; j++) {\n                var  label = paper.g.labelise(multi ? labels[j] && labels[j][i] : labels[i], multi ? values[j][i] : values[i], total);\n                var X = isRight ? bars[i * (multi || 1) + j].x - barheight / 2 + 3 : x + 5,\n                    A = isRight ? \"end\" : \"start\",\n                    L;\n                this.labels.push(L = paper.g.text(X, bars[i * (multi || 1) + j].y, label).attr({\"text-anchor\": A}).insertBefore(covers[0]));\n                if (L.getBBox().x < x + 5) {\n                    L.attr({x: x + 5, \"text-anchor\": \"start\"});\n                } else {\n                    bars[i * (multi || 1) + j].label = L;\n                }\n            }\n        }\n        return this;\n    };\n    chart.hover = function (fin, fout) {\n        covers2.hide();\n        covers.show();\n        fout = fout || function () {};\n        covers.mouseover(fin).mouseout(fout);\n        return this;\n    };\n    chart.hoverColumn = function (fin, fout) {\n        covers.hide();\n        covers2.show();\n        fout = fout || function () {};\n        covers2.mouseover(fin).mouseout(fout);\n        return this;\n    };\n    chart.each = function (f) {\n        if (!Raphael.is(f, \"function\")) {\n            return this;\n        }\n        for (var i = covers.length; i--;) {\n            f.call(covers[i]);\n        }\n        return this;\n    };\n    chart.eachColumn = function (f) {\n        if (!Raphael.is(f, \"function\")) {\n            return this;\n        }\n        for (var i = covers2.length; i--;) {\n            f.call(covers2[i]);\n        }\n        return this;\n    };\n    chart.click = function (f) {\n        covers2.hide();\n        covers.show();\n        covers.click(f);\n        return this;\n    };\n    chart.clickColumn = function (f) {\n        covers.hide();\n        covers2.show();\n        covers2.click(f);\n        return this;\n    };\n    chart.push(bars, covers, covers2);\n    chart.bars = bars;\n    chart.covers = covers;\n    return chart;\n};\n/*!\n * g.Raphael 0.4.1 - Charting library, based on Raphaël\n *\n * Copyright (c) 2009 Dmitry Baranovskiy (http://g.raphaeljs.com)\n * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.\n */\nRaphael.fn.g.dotchart = function (x, y, width, height, valuesx, valuesy, size, opts) {\n    function drawAxis(ax) {\n        +ax[0] && (ax[0] = paper.g.axis(x + gutter, y + gutter, width - 2 * gutter, minx, maxx, opts.axisxstep || Math.floor((width - 2 * gutter) / 20), 2, opts.axisxlabels || null, opts.axisxtype || \"t\"));\n        +ax[1] && (ax[1] = paper.g.axis(x + width - gutter, y + height - gutter, height - 2 * gutter, miny, maxy, opts.axisystep || Math.floor((height - 2 * gutter) / 20), 3, opts.axisylabels || null, opts.axisytype || \"t\"));\n        +ax[2] && (ax[2] = paper.g.axis(x + gutter, y + height - gutter + maxR, width - 2 * gutter, minx, maxx, opts.axisxstep || Math.floor((width - 2 * gutter) / 20), 0, opts.axisxlabels || null, opts.axisxtype || \"t\"));\n        +ax[3] && (ax[3] = paper.g.axis(x + gutter - maxR, y + height - gutter, height - 2 * gutter, miny, maxy, opts.axisystep || Math.floor((height - 2 * gutter) / 20), 1, opts.axisylabels || null, opts.axisytype || \"t\"));\n    }\n    opts = opts || {};\n    var xdim = this.g.snapEnds(Math.min.apply(Math, valuesx), Math.max.apply(Math, valuesx), valuesx.length - 1),\n        minx = xdim.from,\n        maxx = xdim.to,\n        gutter = opts.gutter || 10,\n        ydim = this.g.snapEnds(Math.min.apply(Math, valuesy), Math.max.apply(Math, valuesy), valuesy.length - 1),\n        miny = ydim.from,\n        maxy = ydim.to,\n        len = Math.max(valuesx.length, valuesy.length, size.length),\n        symbol = this.g.markers[opts.symbol] || \"disc\",\n        res = this.set(),\n        series = this.set(),\n        max = opts.max || 100,\n        top = Math.max.apply(Math, size),\n        R = [],\n        paper = this,\n        k = Math.sqrt(top / Math.PI) * 2 / max;\n\n    for (var i = 0; i < len; i++) {\n        R[i] = Math.min(Math.sqrt(size[i] / Math.PI) * 2 / k, max);\n    }\n    gutter = Math.max.apply(Math, R.concat(gutter));\n    var axis = this.set(),\n        maxR = Math.max.apply(Math, R);\n    if (opts.axis) {\n        var ax = (opts.axis + \"\").split(/[,\\s]+/);\n        drawAxis(ax);\n        var g = [], b = [];\n        for (var i = 0, ii = ax.length; i < ii; i++) {\n            var bb = ax[i].all ? ax[i].all.getBBox()[[\"height\", \"width\"][i % 2]] : 0;\n            g[i] = bb + gutter;\n            b[i] = bb;\n        }\n        gutter = Math.max.apply(Math, g.concat(gutter));\n        for (var i = 0, ii = ax.length; i < ii; i++) if (ax[i].all) {\n            ax[i].remove();\n            ax[i] = 1;\n        }\n        drawAxis(ax);\n        for (var i = 0, ii = ax.length; i < ii; i++) if (ax[i].all) {\n            axis.push(ax[i].all);\n        }\n        res.axis = axis;\n    }\n    var kx = (width - gutter * 2) / ((maxx - minx) || 1),\n        ky = (height - gutter * 2) / ((maxy - miny) || 1);\n    for (var i = 0, ii = valuesy.length; i < ii; i++) {\n        var sym = this.raphael.is(symbol, \"array\") ? symbol[i] : symbol,\n            X = x + gutter + (valuesx[i] - minx) * kx,\n            Y = y + height - gutter - (valuesy[i] - miny) * ky;\n        sym && R[i] && series.push(this.g[sym](X, Y, R[i]).attr({fill: opts.heat ? this.g.colorValue(R[i], maxR) : Raphael.fn.g.colors[0], \"fill-opacity\": opts.opacity ? R[i] / max : 1, stroke: \"none\"}));\n    }\n    var covers = this.set();\n    for (var i = 0, ii = valuesy.length; i < ii; i++) {\n        var X = x + gutter + (valuesx[i] - minx) * kx,\n            Y = y + height - gutter - (valuesy[i] - miny) * ky;\n        covers.push(this.circle(X, Y, maxR).attr(this.g.shim));\n        opts.href && opts.href[i] && covers[i].attr({href: opts.href[i]});\n        covers[i].r = +R[i].toFixed(3);\n        covers[i].x = +X.toFixed(3);\n        covers[i].y = +Y.toFixed(3);\n        covers[i].X = valuesx[i];\n        covers[i].Y = valuesy[i];\n        covers[i].value = size[i] || 0;\n        covers[i].dot = series[i];\n    }\n    res.covers = covers;\n    res.series = series;\n    res.push(series, axis, covers);\n    res.hover = function (fin, fout) {\n        covers.mouseover(fin).mouseout(fout);\n        return this;\n    };\n    res.click = function (f) {\n        covers.click(f);\n        return this;\n    };\n    res.each = function (f) {\n        if (!Raphael.is(f, \"function\")) {\n            return this;\n        }\n        for (var i = covers.length; i--;) {\n            f.call(covers[i]);\n        }\n        return this;\n    };\n    res.href = function (map) {\n        var cover;\n        for (var i = covers.length; i--;) {\n            cover = covers[i];\n            if (cover.X == map.x && cover.Y == map.y && cover.value == map.value) {\n                cover.attr({href: map.href});\n            }\n        }\n    };\n    return res;\n};\n/*!\n * g.Raphael 0.4.2 - Charting library, based on Raphaël\n *\n * Copyright (c) 2009 Dmitry Baranovskiy (http://g.raphaeljs.com)\n * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.\n */\nRaphael.fn.g.linechart = function (x, y, width, height, valuesx, valuesy, opts) {\n    function shrink(values, dim) {\n        var k = values.length / dim,\n            j = 0,\n            l = k,\n            sum = 0,\n            res = [];\n        while (j < values.length) {\n            l--;\n            if (l < 0) {\n                sum += values[j] * (1 + l);\n                res.push(sum / k);\n                sum = values[j++] * -l;\n                l += k;\n            } else {\n                sum += values[j++];\n            }\n        }\n        return res;\n    }\n    function getAnchors(p1x, p1y, p2x, p2y, p3x, p3y) {\n        var l1 = (p2x - p1x) / 2,\n            l2 = (p3x - p2x) / 2,\n            a = Math.atan((p2x - p1x) / Math.abs(p2y - p1y)),\n            b = Math.atan((p3x - p2x) / Math.abs(p2y - p3y));\n        a = p1y < p2y ? Math.PI - a : a;\n        b = p3y < p2y ? Math.PI - b : b;\n        var alpha = Math.PI / 2 - ((a + b) % (Math.PI * 2)) / 2,\n            dx1 = l1 * Math.sin(alpha + a),\n            dy1 = l1 * Math.cos(alpha + a),\n            dx2 = l2 * Math.sin(alpha + b),\n            dy2 = l2 * Math.cos(alpha + b);\n        return {\n            x1: p2x - dx1,\n            y1: p2y + dy1,\n            x2: p2x + dx2,\n            y2: p2y + dy2\n        };\n    }\n    opts = opts || {};\n    if (!this.raphael.is(valuesx[0], \"array\")) {\n        valuesx = [valuesx];\n    }\n    if (!this.raphael.is(valuesy[0], \"array\")) {\n        valuesy = [valuesy];\n    }\n    var gutter = opts.gutter || 10,\n        len = Math.max(valuesx[0].length, valuesy[0].length),\n        symbol = opts.symbol || \"\",\n        colors = opts.colors || Raphael.fn.g.colors,\n        that = this,\n        columns = null,\n        dots = null,\n        chart = this.set(),\n        path = [];\n\n    for (var i = 0, ii = valuesy.length; i < ii; i++) {\n        len = Math.max(len, valuesy[i].length);\n    }\n    var shades = this.set();\n    for (i = 0, ii = valuesy.length; i < ii; i++) {\n        if (opts.shade) {\n            shades.push(this.path().attr({stroke: \"none\", fill: colors[i], opacity: opts.nostroke ? 1 : .3}));\n        }\n        if (valuesy[i].length > width - 2 * gutter) {\n            valuesy[i] = shrink(valuesy[i], width - 2 * gutter);\n            len = width - 2 * gutter;\n        }\n        if (valuesx[i] && valuesx[i].length > width - 2 * gutter) {\n            valuesx[i] = shrink(valuesx[i], width - 2 * gutter);\n        }\n    }\n    var allx = Array.prototype.concat.apply([], valuesx),\n        ally = Array.prototype.concat.apply([], valuesy),\n        xdim = this.g.snapEnds(Math.min.apply(Math, allx), Math.max.apply(Math, allx), valuesx[0].length - 1);\n        if(opts.clip) {\n            var minx = opts.minx || xdim.from,\n                maxx = opts.maxx || xdim.to,\n                ydim = this.g.snapEnds(Math.min.apply(Math, ally), Math.max.apply(Math, ally), valuesy[0].length - 1),\n                miny = opts.miny || ydim.from,\n                maxy = opts.maxy || ydim.to;\n        } else {\n            var minx = opts.minx && Math.min(opts.minx, xdim.from) || xdim.from,\n                maxx = opts.maxx && Math.max(opts.maxx, xdimt.to) || xdim.to,\n                ydim = this.g.snapEnds(Math.min.apply(Math, ally), Math.max.apply(Math, ally), valuesy[0].length - 1),\n                miny = opts.miny && Math.min(opts.miny, ydim.from) || ydim.from,\n                maxy = opts.maxy && Math.max(opts.maxy, ydim.to) || ydim.to;\n        }\n        kx = (width - gutter * 2) / ((maxx - minx) || 1),\n        ky = (height - gutter * 2) / ((maxy - miny) || 1);\n\n    var lines = this.set(),\n        symbols = this.set(),\n        line;\n    for (i = 0, ii = valuesy.length; i < ii; i++) {\n        if (!opts.nostroke) {\n            lines.push(line = this.path().attr({\n                stroke: colors[i],\n                \"stroke-width\": opts.width || 2,\n                \"stroke-linejoin\": \"round\",\n                \"stroke-linecap\": \"round\",\n                \"stroke-dasharray\": opts.dash || \"\"\n            }));\n        }\n        var sym = this.raphael.is(symbol, \"array\") ? symbol[i] : symbol,\n            symset = this.set();\n        path = [];\n        for (var j = 0, jj = valuesy[i].length; j < jj; j++) {\n            var X = x + gutter + ((valuesx[i] || valuesx[0])[j] - minx) * kx,\n                Y = y + height - gutter - (valuesy[i][j] - miny) * ky;\n            (Raphael.is(sym, \"array\") ? sym[j] : sym) && symset.push(this.g[Raphael.fn.g.markers[this.raphael.is(sym, \"array\") ? sym[j] : sym]](X, Y, (opts.width || 2) * 3).attr({fill: colors[i], stroke: \"none\"}));\n            if (opts.smooth) {\n                if (j && j != jj - 1) {\n                    var X0 = x + gutter + ((valuesx[i] || valuesx[0])[j - 1] - minx) * kx,\n                        Y0 = y + height - gutter - (valuesy[i][j - 1] - miny) * ky,\n                        X2 = x + gutter + ((valuesx[i] || valuesx[0])[j + 1] - minx) * kx,\n                        Y2 = y + height - gutter - (valuesy[i][j + 1] - miny) * ky;\n                    var a = getAnchors(X0, Y0, X, Y, X2, Y2);\n                    path = path.concat([a.x1, a.y1, X, Y, a.x2, a.y2]);\n                }\n                if (!j) {\n                    path = [\"M\", X, Y, \"C\", X, Y];\n                }\n            } else {\n                path = path.concat([j ? \"L\" : \"M\", X, Y]);\n            }\n        }\n        if (opts.smooth) {\n            path = path.concat([X, Y, X, Y]);\n        }\n        symbols.push(symset);\n        if (opts.shade) {\n            shades[i].attr({path: path.concat([\"L\", X, y + height - gutter, \"L\",  x + gutter + ((valuesx[i] || valuesx[0])[0] - minx) * kx, y + height - gutter, \"z\"]).join(\",\")});\n        }\n        !opts.nostroke && line.attr({path: path.join(\",\"), 'clip-rect': [x + gutter, y + gutter, width - 2 * gutter, height - 2 * gutter].join(\",\")});\n    }\n\n    function createColumns(f) {\n        // unite Xs together\n        var Xs = [];\n        for (var i = 0, ii = valuesx.length; i < ii; i++) {\n            Xs = Xs.concat(valuesx[i]);\n        }\n        Xs.sort(function(a,b) { return a - b; });\n        // remove duplicates\n        var Xs2 = [],\n            xs = [];\n        for (i = 0, ii = Xs.length; i < ii; i++) {\n            Xs[i] != Xs[i - 1] && Xs2.push(Xs[i]) && xs.push(x + gutter + (Xs[i] - minx) * kx);\n        }\n        Xs = Xs2;\n        ii = Xs.length;\n        var cvrs = f || that.set();\n        for (i = 0; i < ii; i++) {\n            var X = xs[i] - (xs[i] - (xs[i - 1] || x)) / 2,\n                w = ((xs[i + 1] || x + width) - xs[i]) / 2 + (xs[i] - (xs[i - 1] || x)) / 2,\n                C;\n            f ? (C = {}) : cvrs.push(C = that.rect(X - 1, y, Math.max(w + 1, 1), height).attr({stroke: \"none\", fill: \"#000\", opacity: 0}));\n            C.values = [];\n            C.symbols = that.set();\n            C.y = [];\n            C.x = xs[i];\n            C.axis = Xs[i];\n            for (var j = 0, jj = valuesy.length; j < jj; j++) {\n                Xs2 = valuesx[j] || valuesx[0];\n                for (var k = 0, kk = Xs2.length; k < kk; k++) {\n                    if (Xs2[k] == Xs[i]) {\n                        C.values.push(valuesy[j][k]);\n                        C.y.push(y + height - gutter - (valuesy[j][k] - miny) * ky);\n                        C.symbols.push(chart.symbols[j][k]);\n                    }\n                }\n            }\n            f && f.call(C);\n        }\n        !f && (columns = cvrs);\n    }\n    function createDots(f) {\n        var cvrs = f || that.set(),\n            C;\n        for (var i = 0, ii = valuesy.length; i < ii; i++) {\n            for (var j = 0, jj = valuesy[i].length; j < jj; j++) {\n                var X = x + gutter + ((valuesx[i] || valuesx[0])[j] - minx) * kx,\n                    nearX = x + gutter + ((valuesx[i] || valuesx[0])[j ? j - 1 : 1] - minx) * kx,\n                    Y = y + height - gutter - (valuesy[i][j] - miny) * ky;\n                f ? (C = {}) : cvrs.push(C = that.circle(X, Y, Math.abs(nearX - X) / 2).attr({stroke: \"none\", fill: \"#000\", opacity: 0}));\n                C.x = X;\n                C.y = Y;\n                C.value = valuesy[i][j];\n                C.line = chart.lines[i];\n                C.shade = chart.shades[i];\n                C.symbol = chart.symbols[i][j];\n                C.symbols = chart.symbols[i];\n                C.axis = (valuesx[i] || valuesx[0])[j];\n                f && f.call(C);\n            }\n        }\n        !f && (dots = cvrs);\n    }\n\n    var axis = this.set();\n    if (opts.axis) {\n        var ax = (opts.axis + \"\").split(/[,\\s]+/);\n        +ax[0] && axis.push(this.g.axis(x + gutter, y + gutter, width - 2 * gutter, minx, maxx, opts.axisxstep || Math.floor((width - 2 * gutter) / 20), 2, opts.axisxlabels || null, opts.axisxtype || \"t\"));\n        +ax[1] && axis.push(this.g.axis(x + width - gutter, y + height - gutter, height - 2 * gutter, miny, maxy, opts.axisystep || Math.floor((height - 2 * gutter) / 20), 3, opts.axisylabels || null, opts.axisytype || \"t\"));\n        +ax[2] && axis.push(this.g.axis(x + gutter, y + height - gutter, width - 2 * gutter, minx, maxx, opts.axisxstep || Math.floor((width - 2 * gutter) / 20), 0, opts.axisxlabels || null, opts.axisxtype || \"t\"));\n        +ax[3] && axis.push(this.g.axis(x + gutter, y + height - gutter, height - 2 * gutter, miny, maxy, opts.axisystep || Math.floor((height - 2 * gutter) / 20), 1, opts.axisylabels || null, opts.axisytype || \"t\"));\n    }\n\n    chart.push(lines, shades, symbols, axis, columns, dots);\n    chart.lines = lines;\n    chart.shades = shades;\n    chart.symbols = symbols;\n    chart.axis = axis;\n    chart.hoverColumn = function (fin, fout) {\n        !columns && createColumns();\n        columns.mouseover(fin).mouseout(fout);\n        return this;\n    };\n    chart.clickColumn = function (f) {\n        !columns && createColumns();\n        columns.click(f);\n        return this;\n    };\n    chart.hrefColumn = function (cols) {\n        var hrefs = that.raphael.is(arguments[0], \"array\") ? arguments[0] : arguments;\n        if (!(arguments.length - 1) && typeof cols == \"object\") {\n            for (var x in cols) {\n                for (var i = 0, ii = columns.length; i < ii; i++) if (columns[i].axis == x) {\n                    columns[i].attr(\"href\", cols[x]);\n                }\n            }\n        }\n        !columns && createColumns();\n        for (i = 0, ii = hrefs.length; i < ii; i++) {\n            columns[i] && columns[i].attr(\"href\", hrefs[i]);\n        }\n        return this;\n    };\n    chart.hover = function (fin, fout) {\n        !dots && createDots();\n        dots.mouseover(fin).mouseout(fout);\n        return this;\n    };\n    chart.click = function (f) {\n        !dots && createDots();\n        dots.click(f);\n        return this;\n    };\n    chart.each = function (f) {\n        createDots(f);\n        return this;\n    };\n    chart.eachColumn = function (f) {\n        createColumns(f);\n        return this;\n    };\n    return chart;\n};\n/*!\n * g.Raphael 0.4.1 - Charting library, based on Raphaël\n *\n * Copyright (c) 2009 Dmitry Baranovskiy (http://g.raphaeljs.com)\n * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.\n */\nRaphael.fn.g.piechart = function (cx, cy, r, values, opts) {\n    opts = opts || {};\n    var paper = this,\n        sectors = [],\n        covers = this.set(),\n        chart = this.set(),\n        series = this.set(),\n        order = [],\n        len = values.length,\n        angle = 0,\n        total = 0,\n        others = 0,\n        cut = 9,\n        defcut = true;\n\n    var sum = 0;\n    for (var i = 0; i < len; i++)\n        sum += values[i];\n    var single = false;\n    var single_index = -1;\n    for (var i = 0; i < len; i++)\n        if (sum == values[i]) {\n            single = true;\n            single_index = i;\n            break;\n        }\n    if (len == 1 || single == true) {\n        for(var i = 0; i < len; i++) {\n            var radius = 0.1;\n            if (i == single_index) {\n                radius = r;\n            }\n            series.push(this.circle(cx, cy, radius).attr({fill: opts.colors && opts.colors[i] || this.g.colors[i], stroke: opts.stroke || \"#fff\", \"stroke-width\": opts.strokewidth == null ? 1 : opts.strokewidth}));\n            covers.push(this.circle(cx, cy, radius).attr({href: opts.href ? opts.href[i] : null}).attr(this.g.shim));\n            values[i] = {value: values[i], order: i, valueOf: function () { return this.value; }};\n            series[i].middle = {x: cx, y: cy};\n            series[i].mangle = 180;\n        }\n        total = values[single_index];\n    } else {\n        function sector(cx, cy, r, startAngle, endAngle, fill) {\n            var rad = Math.PI / 180,\n                x1 = cx + r * Math.cos(-startAngle * rad),\n                x2 = cx + r * Math.cos(-endAngle * rad),\n                xm = cx + r / 2 * Math.cos(-(startAngle + (endAngle - startAngle) / 2) * rad),\n                y1 = cy + r * Math.sin(-startAngle * rad),\n                y2 = cy + r * Math.sin(-endAngle * rad),\n                ym = cy + r / 2 * Math.sin(-(startAngle + (endAngle - startAngle) / 2) * rad),\n                res = [\"M\", cx, cy, \"L\", x1, y1, \"A\", r, r, 0, +(Math.abs(endAngle - startAngle) > 180), 1, x2, y2, \"z\"];\n            res.middle = {x: xm, y: ym};\n            return res;\n        }\n        for (var i = 0; i < len; i++) {\n            total += values[i];\n            values[i] = {value: values[i], order: i, valueOf: function () { return this.value; }};\n        }\n        values.sort(function (a, b) {\n            return b.value - a.value;\n        });\n        for (i = 0; i < len; i++) {\n            if (defcut && values[i] * 360 / total <= 1.5) {\n                cut = i;\n                defcut = false;\n            }\n            if (i > cut) {\n                defcut = false;\n                values[cut].value += values[i];\n                values[cut].others = true;\n                others = values[cut].value;\n            }\n        }\n        len = Math.min(cut + 1, values.length);\n        others && values.splice(len) && (values[cut].others = true);\n        for (i = 0; i < len; i++) {\n            var valueOrder = values[i].order;\n            var mangle = angle - 360 * values[i] / total / 2;\n            if (!i) {\n                angle = 90 - mangle;\n                mangle = angle - 360 * values[i] / total / 2;\n            }\n            if (opts.init) {\n                var ipath = sector(cx, cy, 1, angle, angle - 360 * values[i] / total).join(\",\");\n            }\n            var path = sector(cx, cy, r, angle, angle -= 360 * values[i] / total);\n            var p = this.path(opts.init ? ipath : path).attr({fill: opts.colors && opts.colors[valueOrder] || this.g.colors[valueOrder] || \"#666\", stroke: opts.stroke || \"#fff\", \"stroke-width\": (opts.strokewidth == null ? 1 : opts.strokewidth), \"stroke-linejoin\": \"round\"});\n            p.value = values[i];\n            p.middle = path.middle;\n            p.mangle = mangle;\n            sectors.push(p);\n            series.push(p);\n            opts.init && p.animate({path: path.join(\",\")}, (+opts.init - 1) || 1000, \">\");\n        }\n        for (i = 0; i < len; i++) {\n            p = paper.path(sectors[i].attr(\"path\")).attr(this.g.shim);\n            var valueOrder = values[i].order;\n            opts.href && opts.href[valueOrder] && p.attr({href: opts.href[valueOrder]});\n            //p.attr = function () {}; // this breaks translate!\n            covers.push(p);\n        }\n    }\n\n    chart.hover = function (fin, fout) {\n        fout = fout || function () {};\n        var that = this;\n        for (var i = 0; i < len; i++) {\n            (function (sector, cover, j) {\n                var o = {\n                    sector: sector,\n                    cover: cover,\n                    cx: cx,\n                    cy: cy,\n                    mx: sector.middle.x,\n                    my: sector.middle.y,\n                    mangle: sector.mangle,\n                    r: r,\n                    value: values[j],\n                    total: total,\n                    label: that.labels && that.labels[j]\n                };\n                cover.mouseover(function () {\n                    fin.call(o);\n                }).mouseout(function () {\n                    fout.call(o);\n                });\n            })(series[i], covers[i], i);\n        }\n        return this;\n    };\n    // x: where label could be put\n    // y: where label could be put\n    // value: value to show\n    // total: total number to count %\n    chart.each = function (f) {\n        var that = this;\n        for (var i = 0; i < len; i++) {\n            (function (sector, cover, j) {\n                var o = {\n                    sector: sector,\n                    cover: cover,\n                    cx: cx,\n                    cy: cy,\n                    x: sector.middle.x,\n                    y: sector.middle.y,\n                    mangle: sector.mangle,\n                    r: r,\n                    value: values[j],\n                    total: total,\n                    label: that.labels && that.labels[j]\n                };\n                f.call(o);\n            })(series[i], covers[i], i);\n        }\n        return this;\n    };\n    chart.click = function (f) {\n        var that = this;\n        for (var i = 0; i < len; i++) {\n            (function (sector, cover, j) {\n                var o = {\n                    sector: sector,\n                    cover: cover,\n                    cx: cx,\n                    cy: cy,\n                    mx: sector.middle.x,\n                    my: sector.middle.y,\n                    mangle: sector.mangle,\n                    r: r,\n                    value: values[j],\n                    total: total,\n                    label: that.labels && that.labels[j]\n                };\n                cover.click(function () { f.call(o); });\n            })(series[i], covers[i], i);\n        }\n        return this;\n    };\n    chart.inject = function (element) {\n        element.insertBefore(covers[0]);\n    };\n    var legend = function (labels, otherslabel, mark, dir) {\n        var x = cx + r + r / 5,\n            y = cy,\n            h = y + 10;\n        labels = labels || [];\n        dir = (dir && dir.toLowerCase && dir.toLowerCase()) || \"east\";\n        mark = paper.g.markers[mark && mark.toLowerCase()] || \"disc\";\n        chart.labels = paper.set();\n        for (var i = 0; i < len; i++) {\n            var clr = series[i].attr(\"fill\"),\n                j = values[i].order,\n                txt;\n            values[i].others && (labels[j] = otherslabel || \"Others\");\n            labels[j] = paper.g.labelise(labels[j], values[i], total);\n            chart.labels.push(paper.set());\n            chart.labels[i].push(paper.g[mark](x + 5, h, 5).attr({fill: clr, stroke: \"none\"}));\n            chart.labels[i].push(txt = paper.text(x + 20, h, labels[j] || values[j]).attr(paper.g.txtattr).attr({fill: opts.legendcolor || \"#000\", \"text-anchor\": \"start\"}));\n            covers[i].label = chart.labels[i];\n            h += txt.getBBox().height * 1.2;\n        }\n        var bb = chart.labels.getBBox(),\n            tr = {\n                east: [0, -bb.height / 2],\n                west: [-bb.width - 2 * r - 20, -bb.height / 2],\n                north: [-r - bb.width / 2, -r - bb.height - 10],\n                south: [-r - bb.width / 2, r + 10]\n            }[dir];\n        chart.labels.translate.apply(chart.labels, tr);\n        chart.push(chart.labels);\n    };\n    if (opts.legend) {\n        legend(opts.legend, opts.legendothers, opts.legendmark, opts.legendpos);\n    }\n    chart.push(series, covers);\n    chart.series = series;\n    chart.covers = covers;\n    \n    var w = paper.width,\n        h = paper.height,\n        bb = chart.getBBox(),\n        tr = [(w - bb.width)/2 - bb.x, (h - bb.height)/2 - bb.y];\n    cx += tr[0];\n    cy += tr[1];\n    chart.translate.apply(chart, tr);\n    return chart;\n};\n"
  },
  {
    "path": "src/vendor/i18n/i18n.js",
    "content": "(function() {\n\t/**\n\t * provides text formatting and i18n key storage features<br>\n\t * implements most of the Sun Java MessageFormat functionality.\n\t * @see <a href=\"http://java.sun.com/j2se/1.5.0/docs/api/java/text/MessageFormat.html\" target=\"sun\">Sun's Documentation</a>\n\t */\n\n\tvar keys = {};\n\tvar locale = undefined;\n\n\tvar format = function(message, args) {\n\t\tvar substitute = function() {\n\t\t\tvar format = arguments[1].split(',');\n\t\t\tvar substr = escape(args[format.shift()]);\n\t\t\tif(format.length === 0) {\n\t\t\t\treturn substr; // simple substitution eg {0}\n\t\t\t}\n\t\t\tswitch(format.shift()) {\n\t\t\t\tcase \"number\" : return (new Number(substr)).toLocaleString(locale);\n\t\t\t\tcase \"date\" : return (new Date(+substr)).toLocaleDateString(locale); // date and time require milliseconds since epoch\n\t\t\t\tcase \"time\" : return (new Date(+substr)).toLocaleTimeString(locale); //  eg i18n.text(\"Key\", +(new Date())); for current time\n\t\t\t}\n\t\t\tvar styles = format.join(\"\").split(\"|\").map(function(style) {\n\t\t\t\treturn style.match(/(-?[\\.\\d]+)(#|<)([^{}]*)/);\n\t\t\t});\n\t\t\tvar match = styles[0][3];\n\t\t\tfor(var i=0; i<styles.length; i++) {\n\t\t\t\tif((styles[i][2] === \"#\" && (+styles[i][1]) === (+substr)) ||\n\t\t\t\t\t\t(styles[i][2] === \"<\" && ((+styles[i][1]) < (+substr)))) {\n\t\t\t\t\tmatch = styles[i][3];\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn match;\n\t\t};\n\n\t\treturn message && message.replace(/'(')|'([^']+)'|([^{']+)|([^']+)/g, function(x, sq, qs, ss, sub) {\n\t\t\tdo {} while(sub && (sub !== (sub = (sub.replace(/\\{([^{}]+)\\}/, substitute)))));\n\t\t\treturn sq || qs || ss || unescape(sub);\n\t\t});\n\t};\n\n\tthis.i18n = {\n\n\t\tsetLocale: function(loc){\n\t\t\tlocale = loc;\n\t\t},\n\n\t\tsetKeys: function(strings) {\n\t\t\tfor(var key in strings) {\n\t\t\t\tkeys[key] = strings[key];\n\t\t\t}\n\t\t},\n\n\t\ttext: function() {\n\t\t\tvar args = Array.prototype.slice.call(arguments),\n\t\t\t\tkey = keys[args.shift()];\n\t\t\tif(args.length === 0) {\n\t\t\t\treturn key;\n\t\t\t}\n\t\t\treturn format(key, args);\n\t\t},\n\n\t\tcomplex: function() {\n\t\t\tvar args = Array.prototype.slice.call(arguments),\n\t\t\t\tkey = keys[args.shift()],\n\t\t\t\tret = [],\n\t\t\t\treplacer = function(x, pt, sub) { ret.push(pt || args[+sub]); return \"\"; };\n\t\t\tdo {} while(key && key !== (key = key.replace(/([^{]+)|\\{(\\d+)\\}/, replacer )));\n\t\t\treturn ret;\n\t\t}\n\n\t};\n\n})();\n\n(function() {\n\tvar args = location.search.substring(1).split(\"&\").reduce(function(r, p) {\n\t\tr[decodeURIComponent(p.split(\"=\")[0])] = decodeURIComponent(p.split(\"=\")[1]); return r;\n\t}, {});\n\tvar nav = window.navigator;\n\tvar userLang = args[\"lang\"] || ( nav.languages && nav.languages[0] ) || nav.language || nav.userLanguage;\n\tvar scripts = document.getElementsByTagName('script');\n\tvar data = [].find.call(scripts, elm => elm.dataset && elm.dataset.langs).dataset;\n\tif( ! data[\"langs\"] ) {\n\t\treturn;\n\t}\n\tvar langs = data[\"langs\"].split(/\\s*,\\s*/);\n\tvar script0 = scripts[0];\n\tfunction install( lang ) {\n\t\tvar s = document.createElement(\"script\");\n\t\ts.src = data[\"basedir\"] + \"/\" + lang + '_strings.js';\n\t\ts.async = false;\n\t\tscript0.parentNode.appendChild(s);\n\t\tscript0 = s;\n\n\t\ti18n.setLocale(lang);\n\t}\n\n\tinstall( langs.shift() ); // always install primary language\n\tuserLang && langs\n\t\t.filter( function( lang ) { return userLang.indexOf( lang ) === 0; } )\n\t\t.forEach( install );\n}());\n"
  },
  {
    "path": "src/vendor/joey/joey.js",
    "content": "(function() {\n\n\tvar joey = this.joey = function joey(elementDef, parentNode) {\n\t\treturn createNode( elementDef, parentNode, parentNode ? parentNode.ownerDocument : this.document );\n\t};\n\n\tvar shortcuts = joey.shortcuts = {\n\t\t\"text\" : \"textContent\",\n\t\t\"cls\" : \"className\"\n\t};\n\n\tvar plugins = joey.plugins = [\n\t\tfunction( obj, context ) {\n\t\t\tif( typeof obj === 'string' ) {\n\t\t\t\treturn context.createTextNode( obj );\n\t\t\t}\n\t\t},\n\t\tfunction( obj, context ) {\n\t\t\tif( \"tag\" in obj ) {\n\t\t\t\tvar el = context.createElement( obj.tag );\n\t\t\t\tfor( var attr in obj ) {\n\t\t\t\t\taddAttr( el, attr, obj[ attr ], context );\n\t\t\t\t}\n\t\t\t\treturn el;\n\t\t\t}\n\t\t}\n\t];\n\n\tfunction addAttr( el, attr, value, context ) {\n\t\tattr = shortcuts[attr] || attr;\n\t\tif( attr === 'children' ) {\n\t\t\tfor( var i = 0; i < value.length; i++) {\n\t\t\t\tcreateNode( value[i], el, context );\n\t\t\t}\n\t\t} else if( attr === 'style' || attr === 'dataset' ) {\n\t\t\tfor( var prop in value ) {\n\t\t\t\tel[ attr ][ prop ] = value[ prop ];\n\t\t\t}\n\t\t} else if( attr.indexOf(\"on\") === 0 ) {\n\t\t\tel.addEventListener( attr.substr(2), value, false );\n\t\t} else if( value !== undefined ) {\n\t\t\tel[ attr ] = value;\n\t\t}\n\t}\n\n\tfunction createNode( obj, parent, context ) {\n\t\tvar el;\n\t\tif( obj != null ) {\n\t\t\tplugins.some( function( plug ) {\n\t\t\t\treturn ( el = plug( obj, context ) );\n\t\t\t});\n\t\t\tparent && parent.appendChild( el );\n\t\t\treturn el;\n\t\t}\n\t}\n\n}());\n"
  },
  {
    "path": "src/vendor/jquery/jquery.js",
    "content": "/*!\n * jQuery JavaScript Library v1.6.1\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: Thu May 12 15:04:36 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// (both of which we optimize for)\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// 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.1\",\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\t// Not own constructor property must be Object\n\t\tif ( obj.constructor &&\n\t\t\t!hasOwn.call(obj, \"constructor\") &&\n\t\t\t!hasOwn.call(obj.constructor.prototype, \"isPrototypeOf\") ) {\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\t// (xml & tmp used internally)\n\tparseXML: function( data , xml , tmp ) {\n\n\t\tif ( window.DOMParser ) { // Standard\n\t\t\ttmp = new DOMParser();\n\t\t\txml = tmp.parseFromString( data , \"text/xml\" );\n\t\t} else { // IE\n\t\t\txml = new ActiveXObject( \"Microsoft.XMLDOM\" );\n\t\t\txml.async = \"false\";\n\t\t\txml.loadXML( data );\n\t\t}\n\n\t\ttmp = xml.documentElement;\n\n\t\tif ( ! tmp || ! tmp.nodeName || tmp.nodeName === \"parsererror\" ) {\n\t\t\tjQuery.error( \"Invalid XML: \" + data );\n\t\t}\n\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\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\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 be optionally by executed if its 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\n// Expose jQuery to the global object\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 ]( 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\tbodyStyle,\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\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 click() {\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\tdiv.detachEvent( \"onclick\", click );\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\t// We use our own, invisible, body\n\tbody = document.createElement( \"body\" );\n\tbodyStyle = {\n\t\tvisibility: \"hidden\",\n\t\twidth: 0,\n\t\theight: 0,\n\t\tborder: 0,\n\t\tmargin: 0,\n\t\t// Set background to avoid IE crashes when removing (#9028)\n\t\tbackground: \"none\"\n\t};\n\tfor ( i in bodyStyle ) {\n\t\tbody.style[ i ] = bodyStyle[ i ];\n\t}\n\tbody.appendChild( div );\n\tdocumentElement.insertBefore( body, documentElement.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\tbody.innerHTML = \"\";\n\tdocumentElement.removeChild( body );\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\treturn support;\n})();\n\n// Keep track of boxModel\njQuery.boxModel = jQuery.support.boxModel;\n\n\n\n\nvar rbrace = /^(?:\\{.*\\}|\\[.*\\])$/,\n\trmultiDash = /([a-z])([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 internalKey = jQuery.expando, getByName = typeof name === \"string\", thisCache,\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 ][ 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\treturn getByName ? thisCache[ jQuery.camelCase( name ) ] : thisCache;\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 internalKey = jQuery.expando, isNode = 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\t\t\tvar thisCache = pvt ? cache[ id ][ internalKey ] : cache[ id ];\n\n\t\t\tif ( thisCache ) {\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\tif ( jQuery.support.deleteExpando || cache != window ) {\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\t\tvar name = \"data-\" + key.replace( rmultiDash, \"$1-$2\" ).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\trinvalidChar = /\\:/,\n\tformHook, 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\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function(i) {\n\t\t\t\tvar self = jQuery(this);\n\t\t\t\tself.addClass( value.call(this, i, self.attr(\"class\") || \"\") );\n\t\t\t});\n\t\t}\n\n\t\tif ( value && typeof value === \"string\" ) {\n\t\t\tvar classNames = (value || \"\").split( rspace );\n\n\t\t\tfor ( var i = 0, l = this.length; i < l; i++ ) {\n\t\t\t\tvar elem = this[i];\n\n\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\tif ( !elem.className ) {\n\t\t\t\t\t\telem.className = value;\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tvar className = \" \" + elem.className + \" \",\n\t\t\t\t\t\t\tsetClass = elem.className;\n\n\t\t\t\t\t\tfor ( var c = 0, cl = classNames.length; c < cl; c++ ) {\n\t\t\t\t\t\t\tif ( className.indexOf( \" \" + classNames[c] + \" \" ) < 0 ) {\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\tif ( jQuery.isFunction(value) ) {\n\t\t\treturn this.each(function(i) {\n\t\t\t\tvar self = jQuery(this);\n\t\t\t\tself.removeClass( value.call(this, i, self.attr(\"class\")) );\n\t\t\t});\n\t\t}\n\n\t\tif ( (value && typeof value === \"string\") || value === undefined ) {\n\t\t\tvar classNames = (value || \"\").split( rspace );\n\n\t\t\tfor ( var i = 0, l = this.length; i < l; i++ ) {\n\t\t\t\tvar elem = 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\tvar className = (\" \" + elem.className + \" \").replace(rclass, \" \");\n\t\t\t\t\t\tfor ( var 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\tvar self = jQuery(this);\n\t\t\t\tself.toggleClass( value.call(this, i, self.attr(\"class\"), 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].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\treturn (elem.value || \"\").replace(rreturn, \"\");\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\tname = notxml && jQuery.attrFix[ name ] || name;\n\n\t\thooks = jQuery.attrHooks[ name ];\n\n\t\tif ( !hooks ) {\n\t\t\t// Use boolHook for boolean attributes\n\t\t\tif ( rboolean.test( name ) &&\n\t\t\t\t(typeof value === \"boolean\" || value === undefined || value.toLowerCase() === name.toLowerCase()) ) {\n\n\t\t\t\thooks = boolHook;\n\n\t\t\t// Use formHook for forms and if the name contains certain characters\n\t\t\t} else if ( formHook && (jQuery.nodeName( elem, \"form\" ) || rinvalidChar.test( name )) ) {\n\t\t\t\thooks = formHook;\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 ) {\n\t\t\treturn hooks.get( elem, name );\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\t\t\n\t\t\tif ( jQuery.support.getSetAttribute ) {\n\t\t\t\t// Use removeAttribute in browsers that support it\n\t\t\t\telem.removeAttribute( name );\n\t\t\t} else {\n\t\t\t\tjQuery.attr( elem, name, \"\" );\n\t\t\t\telem.removeAttributeNode( elem.getAttributeNode( name ) );\n\t\t\t}\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\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\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\t// Try to normalize/fix the name\n\t\tname = notxml && jQuery.propFix[ name ] || name;\n\t\t\n\t\thooks = jQuery.propHooks[ name ];\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 )) !== undefined ) {\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});\n\n// Hook for boolean attributes\nboolHook = {\n\tget: function( elem, name ) {\n\t\t// Align boolean attributes with corresponding properties\n\t\treturn elem[ jQuery.propFix[ name ] || name ] ?\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 ] = value;\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// Use the value property for back compat\n// Use the formHook for button elements in IE6/7 (#1954)\njQuery.attrHooks.value = {\n\tget: function( elem, name ) {\n\t\tif ( formHook && jQuery.nodeName( elem, \"button\" ) ) {\n\t\t\treturn formHook.get( elem, name );\n\t\t}\n\t\treturn elem.value;\n\t},\n\tset: function( elem, value, name ) {\n\t\tif ( formHook && jQuery.nodeName( elem, \"button\" ) ) {\n\t\t\treturn formHook.set( elem, value, name );\n\t\t}\n\t\t// Does not return so that setAttribute is also used\n\t\telem.value = value;\n\t}\n};\n\n// IE6/7 do not support getting/setting some attributes with get/setAttribute\nif ( !jQuery.support.getSetAttribute ) {\n\n\t// propFix is more comprehensive and contains all fixes\n\tjQuery.attrFix = jQuery.propFix;\n\t\n\t// Use this for any attribute on a form in IE6/7\n\tformHook = jQuery.attrHooks.name = 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// Check form objects in IE (multiple bugs related)\n\t\t\t// Only use nodeValue if the attribute node exists on the form\n\t\t\tvar ret = elem.getAttributeNode( name );\n\t\t\tif ( ret ) {\n\t\t\t\tret.nodeValue = value;\n\t\t\t\treturn value;\n\t\t\t}\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}\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 hasOwn = Object.prototype.hasOwnProperty,\n\trnamespaces = /\\.(.*)$/,\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 ? 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 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\t// Check if mouse(over|out) are still within the same parent element\n\tvar parent = event.relatedTarget;\n\n\t// set the correct event type\n\tevent.type = event.data;\n\n\t// Firefox sometimes assigns relatedTarget a XUL element\n\t// which we cannot access the parentNode property of\n\ttry {\n\n\t\t// Chrome does something similar, the parentNode property\n\t\t// can be accessed but is null.\n\t\tif ( parent && parent !== document && !parent.parentNode ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Traverse up the tree\n\t\twhile ( parent && parent !== this ) {\n\t\t\tparent = parent.parentNode;\n\t\t}\n\n\t\tif ( parent !== this ) {\n\t\t\t// handle event if we actually just moused on to a non sub-element\n\t\t\tjQuery.event.handle.apply( this, arguments );\n\t\t}\n\n\t// assuming we've left the element since we most likely mousedover a xul element\n\t} catch(e) { }\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\tvar elem = e.target,\n\t\t\t\t\t\ttype = 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 = 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 = elem.type, val = 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\t\tif ( !elem || typeof elem === \"string\" ) {\n\t\t\treturn jQuery.inArray( this[0],\n\t\t\t\t// If it receives a string, the selector is used\n\t\t\t\t// If it receives nothing, the siblings are used\n\t\t\t\telem ? jQuery( elem ) : this.parent().children() );\n\t\t}\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,\n\t\tdoc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);\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 ( elem.getElementsByTagName ) {\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\tcloneFixAttributes( srcElements[i], destElements[i] );\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\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\trdashAlpha = /-([a-z])/ig,\n\t// fixed for IE9, see #8346\n\trupper = /([A-Z]|^ms)/g,\n\trnumpx = /^-?\\d+(?:px)?$/i,\n\trnum = /^-?\\d/,\n\trrelNum = /^[+\\-]=/,\n\trrelNumFilter = /[^+\\-\\.\\de]+/g,\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\n\tfcamelCase = function( all, letter ) {\n\t\treturn letter.toUpperCase();\n\t};\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\"zIndex\": true,\n\t\t\"fontWeight\": true,\n\t\t\"opacity\": true,\n\t\t\"zoom\": true,\n\t\t\"lineHeight\": true,\n\t\t\"widows\": true,\n\t\t\"orphans\": 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// Make sure that NaN and null values aren't set. See: #7116\n\t\t\tif ( type === \"number\" && isNaN( value ) || value == null ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// convert relative number strings (+= or -=) to relative numbers. #7345\n\t\t\tif ( type === \"string\" && rrelNum.test( value ) ) {\n\t\t\t\tvalue = +value.replace( rrelNumFilter, \"\" ) + parseFloat( jQuery.css( elem, name ) );\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\tcamelCase: function( string ) {\n\t\treturn string.replace( rdashAlpha, fcamelCase );\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\tval = getWH( elem, name, extra );\n\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\tif ( val <= 0 ) {\n\t\t\t\t\tval = curCSS( elem, name, name );\n\n\t\t\t\t\tif ( val === \"0px\" && currentStyle ) {\n\t\t\t\t\t\tval = currentStyle( elem, name, name );\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( val != null ) {\n\t\t\t\t\t\t// Should return \"auto\" instead of 0, use 0 for\n\t\t\t\t\t\t// temporary backwards-compat\n\t\t\t\t\t\treturn val === \"\" || val === \"auto\" ? \"0px\" : val;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif ( val < 0 || val == null ) {\n\t\t\t\t\tval = elem.style[ name ];\n\n\t\t\t\t\t// Should return \"auto\" instead of 0, use 0 for\n\t\t\t\t\t// temporary backwards-compat\n\t\t\t\t\treturn val === \"\" || val === \"auto\" ? \"0px\" : val;\n\t\t\t\t}\n\n\t\t\t\treturn typeof val === \"string\" ? val : val + \"px\";\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\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// Set the alpha filter to set the opacity\n\t\t\tvar opacity = jQuery.isNaN( value ) ?\n\t\t\t\t\"\" :\n\t\t\t\t\"alpha(opacity=\" + value * 100 + \")\",\n\t\t\t\tfilter = currentStyle && currentStyle.filter || style.filter || \"\";\n\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\tvar which = name === \"width\" ? cssWidth : cssHeight,\n\t\tval = name === \"width\" ? elem.offsetWidth : elem.offsetHeight;\n\n\tif ( extra === \"border\" ) {\n\t\treturn val;\n\t}\n\n\tjQuery.each( which, function() {\n\t\tif ( !extra ) {\n\t\t\tval -= parseFloat(jQuery.css( elem, \"padding\" + this )) || 0;\n\t\t}\n\n\t\tif ( extra === \"margin\" ) {\n\t\t\tval += parseFloat(jQuery.css( elem, \"margin\" + this )) || 0;\n\n\t\t} else {\n\t\t\tval -= parseFloat(jQuery.css( elem, \"border\" + this + \"Width\" )) || 0;\n\t\t}\n\t});\n\n\treturn val;\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|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|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\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\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// Only one parameter, we extend ajaxSettings\n\t\t\tsettings = target;\n\t\t\ttarget = jQuery.extend( true, jQuery.ajaxSettings, settings );\n\t\t} else {\n\t\t\t// target was provided, we extend into it\n\t\t\tjQuery.extend( true, target, jQuery.ajaxSettings, settings );\n\t\t}\n\t\t// Flatten fields we don't want deep extended\n\t\tfor( var field in { context: 1, url: 1 } ) {\n\t\t\tif ( field in settings ) {\n\t\t\t\ttarget[ field ] = settings[ field ];\n\t\t\t} else if( field in jQuery.ajaxSettings ) {\n\t\t\t\ttarget[ field ] = jQuery.ajaxSettings[ field ];\n\t\t\t}\n\t\t}\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\"*\": \"*/*\"\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\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, statusText, 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 ? 4 : 0;\n\n\t\t\tvar isSuccess,\n\t\t\t\tsuccess,\n\t\t\t\terror,\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 = 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}\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 ] !== \"*\" ? \", */*; 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 ( status < 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\trequestAnimationFrame = window.webkitRequestAnimationFrame ||\n\t    window.mozRequestAnimationFrame ||\n\t    window.oRequestAnimationFrame;\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 ( 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\n\t\t\tif ( jQuery.isFunction( opt.old ) ) {\n\t\t\t\topt.old.call( 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\t\t\traf;\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\t// Use requestAnimationFrame instead of setInterval if available\n\t\t\tif ( requestAnimationFrame ) {\n\t\t\t\ttimerId = 1;\n\t\t\t\traf = function() {\n\t\t\t\t\t// When timerId gets set to null at any point, this stops\n\t\t\t\t\tif ( timerId ) {\n\t\t\t\t\t\trequestAnimationFrame( raf );\n\t\t\t\t\t\tfx.tick();\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\trequestAnimationFrame( raf );\n\t\t\t} else {\n\t\t\t\ttimerId = setInterval( fx.tick, fx.interval );\n\t\t\t}\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 elem = 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\tdocument.body.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( \"<!doctype><html><body></body></html>\" );\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\tdocument.body.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 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\treturn this[0] ?\n\t\t\tparseFloat( jQuery.css( this[0], type, \"padding\" ) ) :\n\t\t\tnull;\n\t};\n\n\t// outerHeight and outerWidth\n\tjQuery.fn[\"outer\" + name] = function( margin ) {\n\t\treturn this[0] ?\n\t\t\tparseFloat( jQuery.css( this[0], 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\treturn elem.document.compatMode === \"CSS1Compat\" && docElemProp ||\n\t\t\t\telem.document.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\nwindow.jQuery = window.$ = jQuery;\n})(window);"
  },
  {
    "path": "src/vendor/nohtml/jquery-nohtml.js",
    "content": "(function($, document) {\n\n\tvar create = $.create = (function() {\n\n\t\tfunction addAttrs( el, obj, context ) {\n\t\t\tfor( var attr in obj ){\n\t\t\t\tswitch( attr ) {\n\t\t\t\tcase 'tag' :\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'html' :\n\t\t\t\t\tel.innerHTML = obj[ attr ];\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'css' :\n\t\t\t\t\tfor( var style in obj.css ) {\n\t\t\t\t\t\t$.attr( el.style, style, obj.css[ style ] );\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'text' : case 'child' : case 'children' :\n\t\t\t\t\tcreateNode( obj[attr], el, context );\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'cls' :\n\t\t\t\t\tel.className = obj[attr];\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'data' :\n\t\t\t\t\tfor( var data in obj.data ) {\n\t\t\t\t\t\t$.data( el, data, obj.data[data] );\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tdefault :\n\t\t\t\t\tif( attr.indexOf(\"on\") === 0 && $.isFunction(obj[attr]) ) {\n\t\t\t\t\t\t$.event.add( el, attr.substr(2).replace(/^[A-Z]/, function(a) { return a.toLowerCase(); }), obj[attr] );\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$.attr( el, attr, obj[attr] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfunction createNode(obj, parent, context) {\n\t\t\tif(obj && ($.isArray(obj) || obj instanceof $)) {\n\t\t\t\tfor(var ret = [], i = 0; i < obj.length; i++) {\n\t\t\t\t\tvar newNode = createNode(obj[i], parent, context);\n\t\t\t\t\tif(newNode) {\n\t\t\t\t\t\tret.push(newNode);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t\tvar el;\n\t\t\tif(typeof(obj) === 'string') {\n\t\t\t\tel = context.createTextNode( obj );\n\t\t\t} else if(!obj) {\n\t\t\t\treturn undefined;\n\t\t\t} else if(obj.nodeType === 1) {\n\t\t\t\tel = obj;\n\t\t\t} else if( obj instanceof app.ui.AbstractWidget ) {\n\t\t\t\tel = obj.el[0];\n\t\t\t} else {\n\t\t\t\tel = context.createElement( obj.tag || 'DIV' );\n\t\t\t\taddAttrs(el, obj, context);\n\t\t\t}\n\t\t\tif(parent){ parent.appendChild(el); }\n\t\t\treturn el;\n\t\t}\n\n\t\treturn function(elementDef, parentNode) {\n\t\t\treturn createNode(elementDef, parentNode, (parentNode && parentNode.ownerDocument) || document);\n\t\t};\n\t\t\n\t})();\n\t\n\n\t// inject create into jquery internals so object definitions are treated as first class constructors (overrides non-public methods)\n\tvar clean = $.clean,\n\t\tinit = $.fn.init;\n\n\t$.clean = function( elems, context, fragment, scripts ) {\n\t\tfor(var i = 0; i < elems.length; i++) {\n\t\t\tif( elems[i].tag || elems[i] instanceof app.ui.AbstractWidget ) {\n\t\t\t\telems[i] = create( elems[i], null, context );\n\t\t\t}\n\t\t}\n\t\treturn clean( elems, context, fragment, scripts );\n\t};\n\n\t$.fn.init = function( selector, context, rootjQuery ) {\n\t\tif ( selector && ( selector.tag || selector instanceof app.ui.AbstractWidget )) {\n\t\t\tselector = create( selector, null, context );\n\t\t}\n\t\treturn init.call( this, selector, context, rootjQuery );\n\t};\n\n\t$.fn.init.prototype = $.fn;\n\n})(jQuery, window.document);\n\n"
  },
  {
    "path": "test/demo.html",
    "content": "<!DOCTYPE html>\n\n<html>\n\t<head>\n\t\t<meta charset=\"UTF-8\">\n\t\t<title>Elasticsearch UI Demo</title>\n\t\t<link rel=\"stylesheet\" href=\"../_site/base/reset.css\">\n\t\t<link rel=\"stylesheet\" href=\"../_site/app.css\">\n\t\t<script src=\"../_site/i18n.js\" data-baseDir=\"../_site/lang\" data-langs=\"en,fr\"></script>\n\t\t<script src=\"../_site/vendor.js\"></script>\n\t\t<script src=\"../_site/app.js\"></script>\n\t\t<script>\n\t\t\t$( function() {\n\t\t\t\tvar args = location.search.substring(1).split(\"&\").reduce(function(r, p) {\n\t\t\t\t\tr[decodeURIComponent(p.split(\"=\")[0])] = decodeURIComponent(p.split(\"=\")[1]); return r;\n\t\t\t\t}, {});\n\t\t\t\tvar script0 = document.getElementsByTagName('script')[0];\n\t\t\t\tvar s = document.createElement(\"script\");\n\t\t\t\ts.src = '../src/' + args['demo'];\n\t\t\t\ts.onload = function() {\n\t\t\t\t\t$(\"body\").append(\n\t\t\t\t\t\t{ tag: \"DIV\", children: [\n\t\t\t\t\t\t\twindow.builder()\n\t\t\t\t\t\t] }\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tscript0.parentNode.insertBefore(s, script0);\n\t\t\t\tdocument.title = args['demo'].match(/([^\\/]+)(\\.js)$/)[1]\n\t\t\t} );\n\t\t</script>\n\t\t<link rel=\"icon\" href=\"../_site/app/favicon.png\" type=\"image/png\">\n\t</head>\n\t<body></body>\n</html>\n"
  },
  {
    "path": "test/generators/conflictingField.sh",
    "content": "#!/bin/sh\n\ncurl -XDELETE 'http://localhost:9200/conflicting_field_type'\necho\ncurl -XPUT 'http://localhost:9200/conflicting_field_type'\necho\ncurl -XPUT 'http://localhost:9200/conflicting_field_type/map1/_mapping' -d '{\n  \"map1\": {\n    \"date_formats\": [\"date_time\", \"yyyyMMddHHmmss\", \"yyyyMMddHHmmssSSS\"],\n    \"_all\": {\n      \"enabled\": true,\n      \"store\": \"yes\"\n    },\n    \"properties\": {\n      \"field1\": {\n        \"type\": \"date\",\n        \"store\": \"yes\",\n        \"format\": \"yyyyMMddHHmmssSSS\",\n        \"include_in_all\": false\n      }\n    }\n  }\n}'\necho\ncurl -XPUT 'http://localhost:9200/conflicting_field_type/map2/_mapping' -d '{\n  \"map2\": {\n    \"date_formats\": [\"date_time\", \"yyyyMMddHHmmss\", \"yyyyMMddHHmmssSSS\"],\n    \"_all\": {\n      \"enabled\": true,\n      \"store\": \"yes\"\n    },\n    \"properties\": {\n      \"field1\": {\n        \"type\": \"string\",\n        \"store\": \"yes\",\n        \"term_vector\": \"yes\",\n        \"include_in_all\": false\n      }\n    }\n  }\n}'\necho\ncurl -XPUT 'http://localhost:9200/conflicting_field_type/map1/1' -d '{\n    \"field1\" : \"20110214172449000\"\n}'\necho\ncurl -XPUT 'http://localhost:9200/conflicting_field_type/map2/2' -d '{\n    \"field1\" : \"Test map2 with string type field\"\n}'\necho"
  },
  {
    "path": "test/generators/delete_all_indices.sh",
    "content": "#!/bin/sh\n\ncurl -XDELETE 'http://localhost:9200/conflicting_field_type'\necho\ncurl -XDELETE 'http://localhost:9200/twitter'\necho\n"
  },
  {
    "path": "test/generators/multi_type.sh",
    "content": "curl -XDELETE 'http://localhost:9200/multi_field_type'\necho\ncurl -XPUT 'http://localhost:9200/multi_field_type'\necho\ncurl -XPUT 'http://localhost:9200/multi_field_type/map1/_mapping' -d '{\n\t\"map1\": {\n\t\t\"properties\": {\n\t\t\t\"field1\": {\n\t\t\t\t\"type\": \"string\",\n\t\t\t\t\"store\": \"yes\"\n\t\t\t},\n\t\t\t\"field2\": {\n\t\t\t\t\"type\": \"multi_field\",\n\t\t\t\t\"path\": \"full\",\n\t\t\t\t\"fields\": {\n\t\t\t\t\t\"field2\": { \"type\": \"string\" },\n\t\t\t\t\t\"alt_name\": { \"type\": \"string\" },\n\t\t\t\t\t\"alt_name2\": { \"type\": \"string\" }\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"field3\": {\n\t\t\t\t\"type\": \"multi_field\",\n\t\t\t\t\"path\": \"just_name\",\n\t\t\t\t\"fields\": {\n\t\t\t\t\t\"field3\": { \"type\": \"string\" },\n\t\t\t\t\t\"foobar\": { \"type\": \"string\" }\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"field4\": {\n\t\t\t\t\"type\": \"multi_field\",\n\t\t\t\t\"path\": \"just_name\",\n\t\t\t\t\"fields\": {\n\t\t\t\t\t\"field4\": { \"type\": \"string\" },\n\t\t\t\t\t\"foobar\": { \"type\": \"string\" }\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"field5\": {\n\t\t\t\t\"type\": \"string\"\n\t\t\t}\n\t\t}\n\t}\n}'\necho\ncurl -XPUT 'http://localhost:9200/multi_field_type/map1/1' -d '{\n\t\"field1\": \"Whats the dogs name\",\n\t\"field2\": \"Max\",\n\t\"field3\": \"Hey Janelle, whats wrong with Wolfie? I can hear him barking\",\n\t\"field4\": \"Wolfies fine, honey, Wolfies just fine. Where are you\",\n\t\"field5\": \"Your foster parents are dead\"\n}'\necho\ncurl -XPUT 'http://localhost:9200/multi_field_type/map1/2' -d '{\n\t\"field1\": \"Nice night for a walk, eh\",\n\t\"field2\": \"Nice night for a walk\",\n\t\"field3\": \"Wash day tomorrow? Nothing clean, right?\",\n\t\"field4\": \"Nothing clean. Right\",\n\t\"field5\": \"Hey, I think this guys a couple cans short of a six-pack\"\n}'\necho\ncurl -XPUT 'http://localhost:9200/multi_field_type/map1/3' -d '{\n\t\"field1\": \"The 600 series had rubber skin. We spotted them easy, but these are new. They look human... sweat, bad breath, everything. Very hard to spot. I had to wait till he moved on you before I could zero him\",\n\t\"field2\": \"Look... I am not stupid, you know. They cannot make things like that yet.\",\n\t\"field3\": \"Not yet. Not for about 40 years\",\n\t\"field4\": \"Are you saying its from the future?\",\n\t\"field5\": \"One possible future. From your point of view... I dont know tech stuff\"\n}'\necho\ncurl -XPUT 'http://localhost:9200/multi_field_type/map1/4' -d '{\n\t\"field1\": \"Did you see this war?\",\n\t\"field2\": \"No. I grew up after. In the ruins... starving... hiding from H-Ks\",\n\t\"field3\": \"H-Ks?\",\n\t\"field4\": \"Hunter-Killers. Patrol machines built in automated factories. Most of us were rounded up, put in camps for orderly disposal\",\n\t\"field5\": \"This is burned in by laser scan. Some of us were kept alive... to work... loading bodies. The disposal units ran night and day. We were that close to going out forever. But there was one man who taught us to fight, to storm the wire of the camps, to smash those metal motherfuckers into junk. He turned it around. He brought us back from the brink. His name is Connor. John Connor. Your son, Sarah, your unborn son\"\n}'\necho\n"
  },
  {
    "path": "test/generators/twitter_feed.sh",
    "content": "#!/bin/sh\n\ncurl -XDELETE 'http://localhost:9200/twitter'\necho\ncurl -XPUT 'http://localhost:9200/twitter'\necho\ncurl -XPUT 'http://localhost:9200/twitter/_mapping' -d '{\n\t\"tweet\": {\n\t\t\"date_formats\": [\"date_time\", \"yyyyMMddHHmmss\", \"yyyyMMddHHmmssSSS\"],\n\t\t\"properties\" : {\n\t\t\t\"user\" : { \"type\" : \"string\", \"index\" : \"not_analyzed\" },\n\t\t\t\"message\" : { \"type\" : \"string\" },\n\t\t\t\"postDate\" : { \"type\" : \"date\" },\n\t\t\t\"srcAddr\" : { \"type\" : \"ip\" },\n\t\t\t\"priority\" : { \"type\" : \"integer\", null_value: 1 },\n\t\t\t\"rank\" : { \"type\" : \"float\", null_value: 1.0 },\n\t\t\t\"loc\" : { \"type\": \"geo_point\" }\n\t\t}\n\t}\n}'\necho\ncurl -XPUT 'http://localhost:9200/twitter/tweet/1' -d '{\n\t\"user\" : \"mobz\",\n\t\"message\" : \"developing a tool to search with\",\n\t\"postDate\" : \"20110220100330\",\n\t\"srcAddr\" : \"203.19.74.11\",\n\t\"loc\" : \"-37.86,144.90\"\n}'\necho\ncurl -XPUT 'http://localhost:9200/twitter/tweet/2' -d '{\n\t\"user\" : \"mobz\",\n\t\"message\" : \"you know, for elastic search\",\n\t\"postDate\" : \"20110220095900\",\n\t\"srcAddr\" : \"203.19.74.11\",\n\t\"loc\" : \"-37.86,144.90\"\n}'\necho\ncurl -XPUT 'http://localhost:9200/twitter/tweet/3' -d '{\n\t\"user\" : \"mobz\",\n\t\"message\" : \"lets take some matilda bay\",\n\t\"postDate\" : \"20110221171330\",\n\t\"srcAddr\" : \"203.19.74.11\",\n\t\"loc\" : \"-37.86,144.90\"\n}'\necho"
  },
  {
    "path": "test/generators/twitter_river.sh",
    "content": "curl -XDELETE 'http://localhost:9200/twitter_river'\necho\ncurl -XDELETE 'http://localhost:9200/_river/twitter_river'\necho\ncurl -XPUT 'http://localhost:9200/twitter_river'\necho\nread -p \"consumer key: \" consumer_key\nread -p \"consumer secret: \" consumer_secret\nread -p \"access token: \" access_token\nread -p \"access token secret: \" access_token_secret\ncurl -XPUT 'localhost:9200/_river/twitter_river/_meta' -d '\n{\n\t\"type\" : \"twitter\",\n\t\"twitter\" : {\n\t\t\"oauth\": {\n\t\t\t\"consumer_key\": \"'${consumer_key}'\",\n\t\t\t\"consumer_secret\": \"'${consumer_secret}'\",\n\t\t\t\"access_token\": \"'${access_token}'\",\n\t\t\t\"access_token_secret\": \"'${access_token_secret}'\"\n\t\t}\n\t},\n\t\"index\": {\n\t\t\"index\": \"twitter_river\",\n\t\t\"type\": \"status\",\n\t\t\"buk_size\": 100\n\t}\n}'\necho"
  },
  {
    "path": "test/perf.html",
    "content": "<!DOCTYPE html>\n\n<html>\n\t<head>\n\t\t<meta charset=\"UTF-8\">\n\t\t<title>Elasticsearch UI Performance Testing Harness</title>\n\t\t<link rel=\"stylesheet\" href=\"../_site/base/reset.css\">\n\t\t<link rel=\"stylesheet\" href=\"../_site/app.css\">\n\t\t<script src=\"../_site/i18n.js\" data-baseDir=\"../_site/lang\" data-langs=\"en,fr\"></script>\n\t\t<script src=\"../_site/vendor.js\"></script>\n\t\t<script src=\"../_site/app.js\"></script>\n\t\t<script>\n\t\t\t$( function() {\n\t\t\t\tvar widget;\n\t\t\t\tvar container = document.getElementById(\"demo\");\n\t\t\t\tfunction build() {\n\t\t\t\t\twidget = window.builder();\n\t\t\t\t\twidget.attach( demo );\n\t\t\t\t}\n\t\t\t\tfunction remove() {\n\t\t\t\t\twidget.remove();\n\t\t\t\t\twidget = null;\n\t\t\t\t}\n\t\t\t\tvar args = location.search.substring(1).split(\"&\").reduce(function(r, p) {\n\t\t\t\t\tr[decodeURIComponent(p.split(\"=\")[0])] = decodeURIComponent(p.split(\"=\")[1]); return r;\n\t\t\t\t}, {});\n\t\t\t\tvar script0 = document.getElementsByTagName('script')[0];\n\t\t\t\tvar s = document.createElement(\"script\");\n\t\t\t\ts.src = '../src/' + args['demo'];\n\t\t\t\tscript0.parentNode.insertBefore(s, script0);\n\t\t\t\tdocument.title = args['demo'].match(/([^\\/]+)(\\.js)$/)[1];\n\t\t\t\tdocument.getElementsByName(\"build\")[0].addEventListener(\"click\", build );\n\t\t\t\tdocument.getElementsByName(\"remove\")[0].addEventListener(\"click\", remove );\n\t\t\t\tdocument.getElementsByName(\"repeat\")[0].addEventListener(\"click\", function() {\n\t\t\t\t\tconsole.time(\"build x 1000 in\");\n\t\t\t\t\tfor( var i = 0; i < 1000; i++ ) {\n\t\t\t\t\t\tbuild();\n\t\t\t\t\t\tremove();\n\t\t\t\t\t}\n\t\t\t\t\tconsole.timeEnd(\"build x 1000 in\");\n\t\t\t\t});\n\t\t\t} );\n\t\t</script>\n\t\t<link rel=\"icon\" href=\"../_site/app/favicon.png\" type=\"image/png\">\n\t</head>\n\t<body>\n\t\t<div class=\"header\">\n\t\t\t<button type=\"button\" name=\"build\">Build</button>\n\t\t\t<button type=\"button\" name=\"remove\">Remove</button>\n\t\t\t<button type=\"button\" name=\"repeat\">Build and Remove x 1000</button>\n\t\t</div>\n\t\t<div id=\"demo\"></div>\n\t</body>\n</html>\n"
  },
  {
    "path": "test/spec/specHelper.js",
    "content": "// find *Spec.js files in the src directory next to the corresponding source file\n\nvar test = window.test = {};\n\ntest.cb = (function( jasmine ) {\n\tvar callbacks = [];\n\n\treturn {\n\t\tuse: function() {\n\t\t\tcallbacks = [];\n\t\t},\n\t\tcreateSpy: function( name, arg, data, context ) {\n\t\t\treturn jasmine.createSpy( name ).and.callFake( function() {\n\t\t\t\tcallbacks.push( { cb: arguments[ arg || 0 ], data: data, context: context } );\n\t\t\t});\n\t\t},\n\t\texecOne: function() {\n\t\t\tvar exec = callbacks.shift();\n\t\t\texec.cb.apply( exec.context, exec.data );\n\t\t},\n\t\texecAll: function() {\n\t\t\twhile( callbacks.length ) {\n\t\t\t\tthis.execOne();\n\t\t\t}\n\t\t}\n\t};\n})( this.jasmine );\n\n\ntest.clock = ( function() {\n\tvar id = 0, timers, saved;\n\tvar names = [ \"setTimeout\", \"setInterval\", \"clearTimeout\", \"clearInterval\" ];\n\tvar byNext = function( a, b ) { return a.next - b.next; };\n\tvar mocks = {\n\t\tsetTimeout: function( fn, t ) {\n\t\t\ttimers.push( { id: id, fn: fn, next: t, t: t, type: \"t\" } );\n\t\t\treturn id++;\n\t\t},\n\t\tclearTimeout: function( id ) {\n\t\t\ttimers = timers.filter( function( timer ) { return timer.id !== id; } );\n\t\t},\n\t\tsetInterval: function( fn, t ) {\n\t\t\ttimers.push( { id: id, fn: fn, next: t, t: t, type: \"i\" } );\n\t\t\treturn id++;\n\t\t},\n\t\tclearInterval: function( id ) {\n\t\t\ttimers = timers.filter( function( timer ) { return timer.id !== id; } );\n\t\t}\n\t};\n\n\treturn {\n\t\tsteal: function() {\n\t\t\ttimers = [];\n\t\t\tsaved = {};\n\t\t\tnames.forEach( function( n ) {\n\t\t\t\tsaved[n] = window[n];\n\t\t\t\twindow[n] = mocks[n];\n\t\t\t});\n\t\t},\n\t\trestore: function() {\n\t\t\tnames.forEach( function( n ) {\n\t\t\t\twindow[n] = saved[n];\n\t\t\t});\n\t\t\ttimers = null;\n\t\t\tsaved = null;\n\t\t},\n\t\ttick: function() {\n\t\t\tif( timers.length ) {\n\t\t\t\ttimers.sort( byNext );\n\t\t\t\tvar t0 = timers[0];\n\t\t\t\tif( t0.type === \"t\" ) {\n\t\t\t\t\ttimers.shift();\n\t\t\t\t} else {\n\t\t\t\t\tt0.next += t0.t;\n\t\t\t\t}\n\t\t\t\tt0.fn();\n\t\t\t}\n\t\t}\n\t};\n\n})();\n"
  }
]