From 4eea7f23346a3de2177a3cb77918f3400ab4756f Mon Sep 17 00:00:00 2001 From: Nate Harada Date: Wed, 6 May 2015 18:55:22 +0000 Subject: [PATCH 1/4] Import source code --- .gitignore | 3 + Gruntfile.js | 115 + LICENSE | 201 + Procfile | 2 + README.md | 130 + app.json | 17 + bin/web.js | 5 + bin/worker.js | 5 + bower.json | 16 + lib/alerts/index.js | 16 + lib/alerts/mail.js | 40 + lib/alerts/sms.js | 28 + lib/alerts/webhook.js | 35 + lib/apis/alerts.js | 73 + lib/apis/api.js | 66 + lib/apis/events.js | 72 + lib/apis/index.js | 12 + lib/apis/info.js | 8 + lib/apis/reports.js | 56 + lib/apis/stats/categories.js | 59 + lib/apis/stats/time.js | 169 + lib/config.js | 40 + lib/database.js | 41 + lib/index.js | 110 + lib/jobs/alert.js | 13 + lib/jobs/index.js | 17 + lib/jobs/post.js | 9 + lib/models/alert.js | 144 + lib/models/event.js | 75 + lib/models/index.js | 5 + lib/models/report.js | 32 + lib/models/visualization.js | 29 + lib/queue/index.js | 7 + lib/queue/kue.js | 53 + lib/queue/memory.js | 34 + lib/utils/error.js | 34 + lib/utils/logger.js | 32 + lib/utils/objects.js | 31 + package.json | 49 + preview.png | Bin 0 -> 73800 bytes public/build/index.html | 28 + public/build/static/application.css | 1 + public/build/static/application.js | 56748 ++++++++++++++++ public/build/static/images/icon.png | Bin 0 -> 3573 bytes public/build/static/images/icon_fill.png | Bin 0 -> 1393 bytes public/build/static/images/ios.png | Bin 0 -> 4197 bytes .../build/static/images/isocity-housing_1.svg | 966 + .../build/static/octicons/octicons-local.ttf | Bin 0 -> 52764 bytes public/build/static/octicons/octicons.css | 247 + public/build/static/octicons/octicons.eot | Bin 0 -> 31440 bytes public/build/static/octicons/octicons.svg | 198 + public/build/static/octicons/octicons.ttf | Bin 0 -> 31272 bytes public/build/static/octicons/octicons.woff | Bin 0 -> 17492 bytes .../static/octicons/sprockets-octicons.scss | 243 + public/src/collections/alerts.js | 34 + public/src/collections/reports.js | 33 + public/src/collections/visualizations.js | 18 + public/src/core/api.js | 39 + public/src/core/settings.js | 44 + public/src/index.html | 28 + public/src/main.js | 300 + public/src/models/alert.js | 81 + public/src/models/report.js | 49 + public/src/models/visualization.js | 57 + public/src/resources/images/icon.png | Bin 0 -> 3573 bytes public/src/resources/images/icon_fill.png | Bin 0 -> 1393 bytes public/src/resources/images/ios.png | Bin 0 -> 4197 bytes .../resources/images/isocity-housing_1.svg | 966 + public/src/resources/init.js | 18 + public/src/resources/langs/en.json | 233 + public/src/resources/stylesheets/alerts.less | 11 + public/src/resources/stylesheets/body.less | 21 + public/src/resources/stylesheets/header.less | 29 + public/src/resources/stylesheets/intro.less | 69 + public/src/resources/stylesheets/main.less | 68 + public/src/resources/stylesheets/start.less | 22 + public/src/resources/stylesheets/toolbar.less | 60 + .../src/resources/stylesheets/variables.less | 40 + .../resources/stylesheets/visualization.less | 92 + .../stylesheets/visualizations/bar.less | 58 + .../stylesheets/visualizations/map.less | 8 + .../stylesheets/visualizations/table.less | 43 + .../stylesheets/visualizations/time.less | 8 + .../stylesheets/visualizations/value.less | 27 + public/src/resources/templates/alert.html | 14 + .../resources/templates/dialogs/alert.html | 14 + .../resources/templates/dialogs/alerts.html | 17 + .../resources/templates/dialogs/confirm.html | 15 + .../resources/templates/dialogs/fields.html | 58 + .../resources/templates/dialogs/prompt.html | 15 + .../resources/templates/dialogs/select.html | 19 + public/src/resources/templates/main.html | 38 + .../resources/templates/visualization.html | 11 + .../templates/visualizations/bar.html | 10 + .../templates/visualizations/table.html | 22 + .../templates/visualizations/time.html | 1 + .../templates/visualizations/value.html | 8 + public/src/utils/dialogs.js | 156 + public/src/utils/dragdrop.js | 265 + public/src/utils/i18n.js | 18 + public/src/utils/template.js | 30 + public/src/views/alerts/all.js | 13 + public/src/views/alerts/mail.js | 15 + public/src/views/alerts/sms.js | 20 + public/src/views/alerts/webhook.js | 14 + public/src/views/dialogs/alerts.js | 37 + public/src/views/dialogs/base.js | 162 + public/src/views/lists/alerts.js | 66 + public/src/views/lists/visualizations.js | 126 + public/src/views/visualizations/all.js | 17 + public/src/views/visualizations/bar.js | 47 + public/src/views/visualizations/base.js | 44 + public/src/views/visualizations/map.js | 95 + public/src/views/visualizations/table.js | 53 + public/src/views/visualizations/time.js | 126 + public/src/views/visualizations/value.js | 57 + test/event.js | 16 + test/helper.js | 38 + 118 files changed, 64427 insertions(+) create mode 100644 .gitignore create mode 100644 Gruntfile.js create mode 100644 LICENSE create mode 100644 Procfile create mode 100644 README.md create mode 100644 app.json create mode 100644 bin/web.js create mode 100644 bin/worker.js create mode 100644 bower.json create mode 100644 lib/alerts/index.js create mode 100644 lib/alerts/mail.js create mode 100644 lib/alerts/sms.js create mode 100644 lib/alerts/webhook.js create mode 100644 lib/apis/alerts.js create mode 100644 lib/apis/api.js create mode 100644 lib/apis/events.js create mode 100644 lib/apis/index.js create mode 100644 lib/apis/info.js create mode 100644 lib/apis/reports.js create mode 100644 lib/apis/stats/categories.js create mode 100644 lib/apis/stats/time.js create mode 100644 lib/config.js create mode 100644 lib/database.js create mode 100644 lib/index.js create mode 100644 lib/jobs/alert.js create mode 100644 lib/jobs/index.js create mode 100644 lib/jobs/post.js create mode 100644 lib/models/alert.js create mode 100644 lib/models/event.js create mode 100644 lib/models/index.js create mode 100644 lib/models/report.js create mode 100644 lib/models/visualization.js create mode 100644 lib/queue/index.js create mode 100644 lib/queue/kue.js create mode 100644 lib/queue/memory.js create mode 100644 lib/utils/error.js create mode 100644 lib/utils/logger.js create mode 100644 lib/utils/objects.js create mode 100644 package.json create mode 100644 preview.png create mode 100644 public/build/index.html create mode 100644 public/build/static/application.css create mode 100644 public/build/static/application.js create mode 100644 public/build/static/images/icon.png create mode 100644 public/build/static/images/icon_fill.png create mode 100644 public/build/static/images/ios.png create mode 100644 public/build/static/images/isocity-housing_1.svg create mode 100644 public/build/static/octicons/octicons-local.ttf create mode 100644 public/build/static/octicons/octicons.css create mode 100644 public/build/static/octicons/octicons.eot create mode 100644 public/build/static/octicons/octicons.svg create mode 100644 public/build/static/octicons/octicons.ttf create mode 100644 public/build/static/octicons/octicons.woff create mode 100644 public/build/static/octicons/sprockets-octicons.scss create mode 100644 public/src/collections/alerts.js create mode 100644 public/src/collections/reports.js create mode 100644 public/src/collections/visualizations.js create mode 100644 public/src/core/api.js create mode 100644 public/src/core/settings.js create mode 100644 public/src/index.html create mode 100644 public/src/main.js create mode 100644 public/src/models/alert.js create mode 100644 public/src/models/report.js create mode 100644 public/src/models/visualization.js create mode 100644 public/src/resources/images/icon.png create mode 100644 public/src/resources/images/icon_fill.png create mode 100644 public/src/resources/images/ios.png create mode 100644 public/src/resources/images/isocity-housing_1.svg create mode 100644 public/src/resources/init.js create mode 100644 public/src/resources/langs/en.json create mode 100644 public/src/resources/stylesheets/alerts.less create mode 100644 public/src/resources/stylesheets/body.less create mode 100644 public/src/resources/stylesheets/header.less create mode 100644 public/src/resources/stylesheets/intro.less create mode 100644 public/src/resources/stylesheets/main.less create mode 100644 public/src/resources/stylesheets/start.less create mode 100644 public/src/resources/stylesheets/toolbar.less create mode 100644 public/src/resources/stylesheets/variables.less create mode 100644 public/src/resources/stylesheets/visualization.less create mode 100644 public/src/resources/stylesheets/visualizations/bar.less create mode 100644 public/src/resources/stylesheets/visualizations/map.less create mode 100644 public/src/resources/stylesheets/visualizations/table.less create mode 100644 public/src/resources/stylesheets/visualizations/time.less create mode 100644 public/src/resources/stylesheets/visualizations/value.less create mode 100644 public/src/resources/templates/alert.html create mode 100644 public/src/resources/templates/dialogs/alert.html create mode 100644 public/src/resources/templates/dialogs/alerts.html create mode 100644 public/src/resources/templates/dialogs/confirm.html create mode 100644 public/src/resources/templates/dialogs/fields.html create mode 100644 public/src/resources/templates/dialogs/prompt.html create mode 100644 public/src/resources/templates/dialogs/select.html create mode 100644 public/src/resources/templates/main.html create mode 100644 public/src/resources/templates/visualization.html create mode 100644 public/src/resources/templates/visualizations/bar.html create mode 100644 public/src/resources/templates/visualizations/table.html create mode 100644 public/src/resources/templates/visualizations/time.html create mode 100644 public/src/resources/templates/visualizations/value.html create mode 100644 public/src/utils/dialogs.js create mode 100644 public/src/utils/dragdrop.js create mode 100644 public/src/utils/i18n.js create mode 100644 public/src/utils/template.js create mode 100644 public/src/views/alerts/all.js create mode 100644 public/src/views/alerts/mail.js create mode 100644 public/src/views/alerts/sms.js create mode 100644 public/src/views/alerts/webhook.js create mode 100644 public/src/views/dialogs/alerts.js create mode 100644 public/src/views/dialogs/base.js create mode 100644 public/src/views/lists/alerts.js create mode 100644 public/src/views/lists/visualizations.js create mode 100644 public/src/views/visualizations/all.js create mode 100644 public/src/views/visualizations/bar.js create mode 100644 public/src/views/visualizations/base.js create mode 100644 public/src/views/visualizations/map.js create mode 100644 public/src/views/visualizations/table.js create mode 100644 public/src/views/visualizations/time.js create mode 100644 public/src/views/visualizations/value.js create mode 100644 test/event.js create mode 100644 test/helper.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..65d2cb8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +node_modules/ +.env +public/src/vendors/ \ No newline at end of file diff --git a/Gruntfile.js b/Gruntfile.js new file mode 100644 index 0000000..8dac27c --- /dev/null +++ b/Gruntfile.js @@ -0,0 +1,115 @@ +var path = require("path"); +var _ = require("lodash"); +var pkg = require("./package.json"); + +module.exports = function (grunt) { + // Path to the client src + var srcPath = path.resolve(__dirname, "public/src"); + + // Load grunt modules + grunt.loadNpmTasks('grunt-hr-builder'); + grunt.loadNpmTasks("grunt-bower-install-simple"); + + // Init GRUNT configuraton + grunt.initConfig({ + "pkg": pkg, + "bower-install-simple": { + options: { + color: true, + production: false, + directory: "public/src/vendors" + } + }, + "hr": { + "app": { + "source": path.resolve(__dirname, "node_modules/happyrhino"), + + // Base directory for the application + "base": srcPath, + + // Application name + "name": "Reportr", + + // Mode debug + "debug": true, + + // Main entry point for application + "main": "main", + + // Build output directory + "build": path.resolve(__dirname, "public/build"), + + // HTML entry point + 'index': grunt.file.read(path.resolve(srcPath, "index.html")), + + // Static files mappage + "static": { + "octicons": path.resolve(srcPath, "vendors/octicons/octicons"), + "images": path.resolve(srcPath, "resources/images"), + }, + + // Stylesheet entry point + "style": path.resolve(srcPath, "resources/stylesheets/main.less"), + + // Modules paths + 'paths': { + 'rickshaw': "vendors/rickshaw/rickshaw", + 'd3': "vendors/d3/d3", + "datamaps": "vendors/datamaps/dist/datamaps.world", + "topojson": "vendors/topojson/topojson", + "moment": "vendors/moment/moment" + }, + "shim": { + "main": { + "deps": [ + 'hr/dom', + 'vendors/bootstrap/js/carousel', + 'vendors/bootstrap/js/dropdown', + 'vendors/bootstrap/js/button', + 'vendors/bootstrap/js/modal', + 'vendors/bootstrap/js/affix', + 'vendors/bootstrap/js/alert', + 'vendors/bootstrap/js/collapse', + 'vendors/bootstrap/js/tooltip', + 'vendors/bootstrap/js/popover', + 'vendors/bootstrap/js/scrollspy', + 'vendors/bootstrap/js/tab', + 'vendors/bootstrap/js/transition' + ] + }, + "rickshaw": { + "exports": "Rickshaw", + "deps": [ + 'd3' + ] + }, + "d3": { + "exports": "d3" + }, + "datamaps": { + "deps": [ + "topojson" + ] + } + }, + 'args': {}, + 'options': {} + } + } + }); + + // Prepare build + grunt.registerTask("prepare", [ + "bower-install-simple" + ]); + + // Build + grunt.registerTask('build', [ + 'hr:app' + ]); + + grunt.registerTask('default', [ + 'prepare', + 'build' + ]); +}; diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..5c304d1 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/Procfile b/Procfile new file mode 100644 index 0000000..4efa90b --- /dev/null +++ b/Procfile @@ -0,0 +1,2 @@ +web: node bin/web.js +worker: node bin/worker.js diff --git a/README.md b/README.md new file mode 100644 index 0000000..c8b8b82 --- /dev/null +++ b/README.md @@ -0,0 +1,130 @@ +Reportr +========= + +> "Your life's personal dashboard." + +[![Deploy](https://www.herokucdn.com/deploy/button.png)](https://heroku.com/deploy) + +Reportr is a complete application which works like a dashboard for tracking events in your life (using a very simple API). With a simple interface, it helps you track and display your online activity or your real-life activity (with hardware trackers or applications like Runkeeper), some trackers are available on [this organization](https://github.com/Reportr). + +The project is entirely open source and you can host your own Reportr instance on your own server or Heroku. + +[![Screen Preview](./preview.png)](./preview.png) + +## Start your instance + +Reportr is really easy to run locally or on heroku-compatible services. + +``` +$ git clone https://github.com/Reportr/dashboard.git +$ npm install . +``` + +To run it locally, you should use [foreman](http://ddollar.github.io/foreman/) (configuration can be stored in a [.env file](https://devcenter.heroku.com/articles/config-vars#local-setup)): + +``` +$ foreman start +``` + +To deploy it on Heroku: + +``` +$ heroku config:set MONGODB_URL=mongodb://... +$ heroku config:set AUTH_USERNAME=... +$ heroku config:set AUTH_PASSWORD=... +$ git push heroku master +``` + +## API and Events + +Reportr uses an HTTP REST API to track events. Datas are always JSON encoded. + +| Endpoint | HTTP Method | Description | Arguments | +| -------- | ----------- | ----------- | --------- | +| /api/infos | GET | Get informations about this instance | | +| /api/types | GET | Return all event types | | +| /api/events | POST | Post a new event | `type`, `properties` | +| /api/events | GET | List all events | `type`, `start(0)`, `limit` | +| /api/stats/categories | GET | Get categorized events stats | `type`,`field` | +| /api/stats/time | GET | Get time stats | `type`,`fields`, `interval`, `func` | +| /api/reports | POST | Create a new report | `title` | +| /api/reports | GET | List all reports | | +| /api/report/:id | PUT | Update a report | `title`, `visualizations` | +| /api/report/:id | DELETE | Remove a report | | +| /api/alerts | GET | List all alerts | | +| /api/alerts | POST | Create an alert | `type`, `eventName`, `condition`, `title` | + +#### Special Events + +| Name | Description | Properties | +| ---- | ----------- | ---------- | +| reportr.alert | Triggered when an alert is triggered | `type`, `eventName` | + + +## Configuration + +Reportr is configured using environment variables. + +| Name | Description | +| ---- | ----------- | +| PORT | Port for running the application, default is 5000 | +| MONGODB_URL | Url for the mongoDB database | +| REDIS_URL | (Optional) Url for a redis database when using worker mode | +| AUTH_USERNAME | Username for authentication | +| AUTH_PASSWORD | Password for authentication | + +See [types](#types) for informations about alert configurations. + +## Events + +An event represent something to monitor at a defined date. For example if I'm monitoring the temperature in my home, I'll post an event `home.temperature` with a property `temp`: + +``` +$ curl -X POST -H "Content-Type: application/json" --data '{ "type":"home.temperature", "properties": { "temperature": 66 } }' http://localhost:5000/api/events +``` + +## Visualizations + +A visualization is a configured way to show data, for example in a pie, bar chart or time graph. + +#### Types + +| Type | Description | +| ---- | ----------- | + +#### Templates + +Visualizations accept templates as most of rendering options. Template are processed using [lodash's _.template method](http://lodash.com/docs#template) with some special functions: + +- `$.date(date)`: returns a beautiful date + +## Alerts + +Reportr lets you configure alerts to be triggered when specific condition is valid at a specific interval. + +#### Types + +| Type | Description | Configuration | +| ---- | ----------- | ------------- | +| webhook | Post an HTTP request to a specific url with the data encoded in the body | | +| mail | Send an email notification | `MAIL_SERVICE`, `MAIL_USERNAME`, `MAIL_PASSWORD`, `MAIL_FROM` | +| sms | Send a text message notification | `TWILIO_SID`, `TWILIO_TOKEN`, `TWILIO_FROM` | + +#### Condition + +Condition for alerts are really easy to write, for example: `COUNT > 9`, this condition will be valid if at least 10 events have been posted in the alert interval. Conditions can also use the event object, for example: `event.temperature > 80`. + +## Trackers + +| Description | Link | +| ---- | ----------- | +| Google Chrome Navigation | https://github.com/Reportr/tracker-googlechrome | +| Home ambient (temperature, humidity, light) | https://github.com/Reportr/tracker-home-ambient | +| Memory and CPU of computer | https://github.com/Reportr/tracker-machine | +| Battery data | https://github.com/hughrawlinson/tracker-machine-battery | + +## Scale it + +Reportr can easily be scaled on Heroku (and compatibles), use the `REDIS_URL` to enable a task queue between **workers** and **web** processes. + + diff --git a/app.json b/app.json new file mode 100644 index 0000000..a605d23 --- /dev/null +++ b/app.json @@ -0,0 +1,17 @@ +{ + "name": "Reportr", + "description": "Your life's personal dashboard.", + "website": "http://www.reportr.io/", + "repository": "https://github.com/Reportr/dashboard", + "logo": "https://avatars2.githubusercontent.com/u/7984166?v=2&s=200", + "keywords": ["node", "dashboard", "analytic"], + "addons": ["mongolab"], + "env": { + "AUTH_USERNAME": { + "description": "Username" + }, + "AUTH_PASSWORD": { + "description": "Password" + } + } +} diff --git a/bin/web.js b/bin/web.js new file mode 100644 index 0000000..96b0238 --- /dev/null +++ b/bin/web.js @@ -0,0 +1,5 @@ +#! /usr/bin/env node + +var app = require("../lib"); + +app.start(); diff --git a/bin/worker.js b/bin/worker.js new file mode 100644 index 0000000..e19e291 --- /dev/null +++ b/bin/worker.js @@ -0,0 +1,5 @@ +#! /usr/bin/env node + +var app = require("../lib"); + +app.worker(); diff --git a/bower.json b/bower.json new file mode 100644 index 0000000..c01b890 --- /dev/null +++ b/bower.json @@ -0,0 +1,16 @@ +{ + "name": "Reportr", + "dependencies": { + "bootstrap": "3.1.1", + "octicons": "2.0.2", + "d3": "3.4.8", + "rickshaw": "1.4.6", + "datamaps": "0.3.3", + "moment": "2.7.0", + "leaflet": "~0.7.3", + "leaflet.markercluster": "~0.4.0" + }, + "resolutions": { + "d3": "3.4.8" + } +} \ No newline at end of file diff --git a/lib/alerts/index.js b/lib/alerts/index.js new file mode 100644 index 0000000..853ae81 --- /dev/null +++ b/lib/alerts/index.js @@ -0,0 +1,16 @@ +var _ = require("lodash"); + +var ALL = [ + require("./webhook"), + require("./mail"), + require("./sms") +]; + + +module.exports = { + ALL: ALL, + TYPES: _.pluck(ALL, "id"), + byId: function(id) { + return _.find(ALL, function(a) { return a.id == id; }); + } +}; diff --git a/lib/alerts/mail.js b/lib/alerts/mail.js new file mode 100644 index 0000000..d96c4e5 --- /dev/null +++ b/lib/alerts/mail.js @@ -0,0 +1,40 @@ +var Q = require('q'); +var _ = require('lodash'); +var nodemailer = require("nodemailer"); + +var config = require("../config"); +var mailConfig = config.alerts.mail; + +var exec = function(alert, alertConfig, e) { + var deferred = Q.defer(); + + var transport = nodemailer.createTransport("SMTP", { + service: mailConfig.service, + auth: mailConfig.auth + }); + + var content = [ + "Alert Notification for "+alert.eventName+"" + ].join("
\n"); + + transport.sendMail({ + from: mailConfig.from, + to: alertConfig.to, + subject: "Reportr - Alert - "+alert.eventName, + text: "", + html: content + }, function(error, response){ + if (error) { + deferred.reject(error); + } else { + deferred.resolve(); + } + }); + + return deferred.promise; +}; + +module.exports = { + id: "mail", + execute: exec +}; diff --git a/lib/alerts/sms.js b/lib/alerts/sms.js new file mode 100644 index 0000000..18c16d6 --- /dev/null +++ b/lib/alerts/sms.js @@ -0,0 +1,28 @@ +var Q = require('q'); +var _ = require('lodash'); +var Twilio = require('twilio') + +var config = require("../config"); +var smsConfig = config.alerts.sms; + +var exec = function(alert, alertConfig, e) { + var deferred = Q.defer(); + + var client = Twilio(smsConfig.sId, smsConfig.token); + + client.messages.create({ + body: _.template(alertConfig.body || "", e), + to: alertConfig.to, + from: smsConfig.from + }, function(err, message) { + if (err) return deferred.reject(err); + deferred.resolve(); + }); + + return deferred.promise; +}; + +module.exports = { + id: "sms", + execute: exec +}; diff --git a/lib/alerts/webhook.js b/lib/alerts/webhook.js new file mode 100644 index 0000000..304f96b --- /dev/null +++ b/lib/alerts/webhook.js @@ -0,0 +1,35 @@ +var Q = require('q'); +var _ = require('lodash'); +var request = require("request"); + +var exec = function(alert, config, e) { + var deferred = Q.defer(); + + var args = { + 'event': e.repr() + }; + + request.post(config.url, { + 'body': args + }, function (error, response, body) { + if (!error && response.statusCode == 200) { + deferred.resolve(); + } else { + deferred.reject(error || new Error("Status: "+response.statusCode)); + } + }); + + return deferred.promise; +}; + +module.exports = { + id: "webhook", + title: "Webhook", + options: { + url: { + type: "text", + label: "Url" + } + }, + execute: exec +}; diff --git a/lib/apis/alerts.js b/lib/apis/alerts.js new file mode 100644 index 0000000..92360be --- /dev/null +++ b/lib/apis/alerts.js @@ -0,0 +1,73 @@ +var _ = require("lodash"); + +var api = require("./api.js"); +var Alert = require("../models/alert"); +var alerts = require("../alerts") + +// Create an alert +api.register("post", "alerts", function(args) { + var r = new Alert(args); + + return r.saveQ() + .then(function(e) { + return e.repr(); + }) +}, { + needed: [ + "eventName", "type", "condition" + ] +}); + +// List alerts +api.register("get", "alerts", function(args) { + return Alert.find({}) + .skip(args.start) + .limit(args.limit) + .execQ() + .then(function(alerts) { + return _.map(alerts, function(a) { + return a.repr(); + }); + }) +}, { + defaults: { + start: 0, + limit: 100 + } +}); + + +// Edit an alert +api.register("put", "alert/:alert", function(args, context) { + context.alert.title = args.title || context.alert.title; + context.alert.condition = args.condition || context.alert.condition; + context.alert.interval = args.interval || context.alert.interval; + context.alert.configuration = args.configuration || context.alert.configuration; + + return context.alert.saveQ() + .then(function() { + return context.alert.repr(); + }) +}); + +// Toggle an alert +api.register("put", "alert/:alert/toggle", function(args, context) { + context.alert.enabled = !context.alert.enabled; + + return context.alert.saveQ() + .then(function() { + return { + enabled: context.alert.enabled + } + }) +}); + +// Remove an alert +api.register("delete", "alert/:alert", function(args, context) { + return context.alert.removeQ() + .then(function() { + return { deleted: true } + }) +}); + + diff --git a/lib/apis/api.js b/lib/apis/api.js new file mode 100644 index 0000000..8218113 --- /dev/null +++ b/lib/apis/api.js @@ -0,0 +1,66 @@ +var Q = require("q"); +var _ = require("lodash"); + +var Report = require("../models/report"); +var Alert = require("../models/alert"); + +var methods = []; + +// Register an api +var register = function(method, path, handler, options) { + methods.push({ + 'method': method, + 'path': path, + 'handler': handler, + 'options': _.defaults(options || {}, { + needed: [], + defaults: {} + }) + }); +}; + +// Init all APIs on an application +var init = function(app) { + _.each(methods, function(method) { + app[method.method]("/api/"+method.path, function(req, res, next) { + var args = _.extend({}, method.options.defaults, req.query, req.body); + var context = {}; + + Q() + + // Check args + .then(function() { + if (_.size(method.options.needed) > 0 && _.difference(method.options.needed, _.keys(args)).length > 0) { + throw "Need: "+method.options.needed.join(", "); + } + }) + + // Load context + .then(function() { + if (req.params.report) { + return Report.findByIdQ(req.params.report) + .then(function(report) { + context.report = report; + }); + } else if (req.params.alert) { + return Alert.findByIdQ(req.params.alert) + .then(function(alert) { + context.alert = alert; + }); + } + }) + + .then(function() { + return method.handler(args, context); + }) + .then(function(data) { + res.send(data); + }, next); + }); + }) +}; + +module.exports = { + init: init, + register: register +}; diff --git a/lib/apis/events.js b/lib/apis/events.js new file mode 100644 index 0000000..073ba0b --- /dev/null +++ b/lib/apis/events.js @@ -0,0 +1,72 @@ +var _ = require("lodash"); + +var api = require("./api.js"); +var Event = require("../models/event"); +var queue = require("../queue"); + +// Create an event +api.register("post", "events", function(args) { + queue.job("post", args); + + return { + posted: true + }; +}, { + needed: [ + "type" + ] +}); + +// List events +api.register("get", "events", function(args) { + var has = _.chain(args.has.split(",")).compact().value(); + var query = { + 'type': args.type + }; + + if (has.length > 0) { + query = { + '$and': _.chain(has) + .map(function(key) { + return _.object([["properties."+key, {"$exists": true}]]) + }) + .concat([query]) + .value() + } + } + + return Event.find(query) + .sort({ date:-1 }) + .skip(args.start) + .limit(args.limit) + .execQ() + .then(function(events) { + return _.map(events, function(e) { + return e.repr(); + }); + }) +}, { + needed: [ + "type" + ], + defaults: { + start: 0, + limit: 100, + has: "" + } +}); + +// List events +api.register("get", "types", function(args) { + return Event.distinctQ('type') + .then(function(events) { + return _.chain(events) + .map(function(e) { + return { + type: e + }; + }) + .value(); + }) +}); + diff --git a/lib/apis/index.js b/lib/apis/index.js new file mode 100644 index 0000000..e0bb755 --- /dev/null +++ b/lib/apis/index.js @@ -0,0 +1,12 @@ +var api = require("./api.js"); + +require("./info.js"); +require("./events.js"); +require("./reports.js"); +require("./alerts.js"); +require("./stats/categories.js"); +require("./stats/time.js"); + +module.exports = { + init: api.init +}; diff --git a/lib/apis/info.js b/lib/apis/info.js new file mode 100644 index 0000000..b3af39e --- /dev/null +++ b/lib/apis/info.js @@ -0,0 +1,8 @@ +var api = require("./api.js"); +var pkg = require("../../package.json"); + +api.register("get", "infos", function() { + return { + version: pkg.version + } +}); diff --git a/lib/apis/reports.js b/lib/apis/reports.js new file mode 100644 index 0000000..7d8e291 --- /dev/null +++ b/lib/apis/reports.js @@ -0,0 +1,56 @@ +var _ = require("lodash"); + +var api = require("./api.js"); +var Report = require("../models/report"); + +// Create a report +api.register("post", "reports", function(args) { + var r = new Report(args); + + return r.saveQ() + .then(function(e) { + return e.repr(); + }) +}, { + needed: [ + "title" + ] +}); + +// List reports +api.register("get", "reports", function(args) { + return Report.find({}) + .skip(args.start) + .limit(args.limit) + .execQ() + .then(function(reports) { + return _.map(reports, function(e) { + return e.repr(); + }); + }) +}, { + defaults: { + start: 0, + limit: 100 + } +}); + +// Edit a report +api.register("put", "report/:report", function(args, context) { + context.report.title = args.title || context.report.title; + context.report.visualizations = args.visualizations || context.report.visualizations; + + return context.report.saveQ() + .then(function() { + return context.report.repr(); + }) +}); + +// Remove a report +api.register("delete", "report/:report", function(args, context) { + return context.report.removeQ() + .then(function() { + return { deleted: true } + }) +}); + diff --git a/lib/apis/stats/categories.js b/lib/apis/stats/categories.js new file mode 100644 index 0000000..cf748c6 --- /dev/null +++ b/lib/apis/stats/categories.js @@ -0,0 +1,59 @@ +var _ = require("lodash"); + +var api = require("../api.js"); +var Event = require("../../models/event"); + + +// List events +api.register("get", "stats/categories", function(args) { + return Event.aggregateQ( + { + '$match': { + 'type': args.type + } + }, + { + '$sort': { + 'date': -1 + } + }, + { '$skip': args.start }, + { '$limit': args.limit }, + { + '$group': { + '_id': _.object([["k", "$"+"properties."+args.field]]), + 'n': _.object([["$"+args.func, args.arg]]) + } + } + ) + .then(function(results) { + var max = _.chain(results).pluck("n").max().value(); + var total = _.chain(results).reduce(function(sum, r) { return sum + r.n; }, 0).value() + + return _.chain(results) + .map(function(r) { + return { + 'key': r._id.k, + 'value': r.n, + 'percents': { + 'total': (total > 0 ? ((r.n*100)/total): 0), + 'max': (max > 0 ? ((r.n*100)/max): 0) + } + } + }) + .sortBy("value") + .reverse() + .value(); + }) +}, { + needed: [ + "type", "field" + ], + defaults: { + start: 0, + limit: 1000, + func: "sum", + arg: 1 + } +}); + diff --git a/lib/apis/stats/time.js b/lib/apis/stats/time.js new file mode 100644 index 0000000..a24a4e3 --- /dev/null +++ b/lib/apis/stats/time.js @@ -0,0 +1,169 @@ +var _ = require("lodash"); + +var api = require("../api.js"); +var Event = require("../../models/event"); + +var INTERVALS = { + 'minute': ["year", "month", "dayOfMonth", "hour", "minute"], + 'hour': ["year", "month", "dayOfMonth", "hour"], + 'day': ["year", "month", "dayOfMonth"], + 'week': ["year", "month", "week"], + 'month': ["year", "month"], + 'month': ["year"] +}; + +var INTERVALS_INT = { + 'minute': 60*1000, + 'hour': 60*60*1000, + 'day': 24*60*60*1000, + 'week': 7*24*60*60*1000, + 'month': 30*24*60*60*1000, + 'month': 365*24*60*60*1000 +}; + +// List events +api.register("get", "stats/time", function(args) { + if (!INTERVALS[args.interval]) throw "Invalid interval, valids are: "+_.keys(INTERVALS).join(", "); + var fields = _.compact(args.fields.split(",")); + var intMs = INTERVALS_INT[args.interval]; + var intS = intMs/1000; + + args.start = Number(args.start || 0); + args.limit = Number(args.limit || 1000); + + return Event.aggregateQ( + { + '$match': { + 'type': args.type + } + }, + { + '$sort': { + 'date': -1 + } + }, + { '$skip': args.start }, + { '$limit': args.limit }, + { + '$project': _.chain([]) + .concat(INTERVALS[args.interval]) + .map(function(s) { + return [s, _.object([["$"+s,'$date']])]; + }) + .concat([ + ["date", 1] + ]) + .concat(_.map(fields, function(field) { + return ["properties."+field, 1] + })) + .object() + .value() + }, + { + $group : _.extend({ + _id: _.chain(INTERVALS[args.interval]) + .map(function(s) { + return [ + s, + "$"+s + ]; + }) + .object().value(), + n: { $sum: 1 }, + date: { $max: "$date" } + }, + _.chain(fields) + .map(function(field) { + return [ + field, + _.object([["$"+args.func, "$properties."+field]]) + ] + }) + .object() + .value() + ) + }, + { + $sort: { + date: 1 + } + } + ) + .then(function(results) { + // Normaliza data + var data = _.chain(results) + .map(function(r) { + + return { + date: (Math.floor(r.date.getTime()/intMs)*intMs)/1000, + n: r.n, + fields: _.chain(fields) + .map(function(f) { + return [ + f, + Number(r[f]) + ]; + }) + .object() + .value() + } + }) + .value(); + + if (args.fillEmpty != null) { + data = _.transform(data, function(_data, r, i, original) { + var next = original[i+1]; + var prev = original[i-1]; + + if (prev && (r.date - prev.date) > intS) { + _data.push({ + date: (Math.floor((r.date-intS)/intS)*intS), + n: 0, + fields: _.chain(fields) + .map(function(f) { + return [ + f, + 0 + ]; + }) + .object() + .value() + }); + } + + _data.push(r); + + if (next && (next.date - r.date) > intS) { + _data.push({ + date: (Math.floor((r.date+intS)/intS)*intS), + n: 0, + fields: _.chain(fields) + .map(function(f) { + return [ + f, + 0 + ]; + }) + .object() + .value() + }); + } + }) + } + + return data; + }) +}, { + needed: [ + "type" + ], + defaults: { + start: 0, + limit: 1000, + interval: "hour", + fields: "", + func: "avg", + fillEmpty: null + } +}); + diff --git a/lib/config.js b/lib/config.js new file mode 100644 index 0000000..7cabc2d --- /dev/null +++ b/lib/config.js @@ -0,0 +1,40 @@ +var TESTING = (process.env.TESTING && process.env.TESTING.toLowerCase() === 'true'); + +var LOCAL_URL = 'mongodb://localhost/' + (TESTING ? + 'reportr_test': + 'reportr' +); + +module.exports = { + 'port': process.env.PORT, + + 'database': { + 'url': process.env.MONGOLAB_URI || process.env.MONGOHQ_URL || process.env.MONGODB_URL || LOCAL_URL + }, + + 'auth': { + 'username': process.env.AUTH_USERNAME , + 'password': process.env.AUTH_PASSWORD + }, + + 'tasks': { + 'redis': process.env.REDISCLOUD_URL || process.env.REDIS_URL + }, + + 'alerts': { + 'mail': { + 'service': process.env.MAIL_SERVICE, + 'auth': { + 'user': process.env.MAIL_USERNAME, + 'password': process.env.MAIL_PASSWORD + }, + 'from': process.env.MAIL_FROM + }, + 'sms': { + 'sId': process.env.TWILIO_SID, + 'token': process.env.TWILIO_TOKEN, + 'from': process.env.TWILIO_FROM + } + } +}; + diff --git a/lib/database.js b/lib/database.js new file mode 100644 index 0000000..6e8b379 --- /dev/null +++ b/lib/database.js @@ -0,0 +1,41 @@ +var _ = require("lodash"); +var Q = require("q"); +var mongoose = require('mongoose-q')(); + +var logger = require("./utils/logger")("database"); +var config = require("./config"); + +// Register all models to mongoose +var models = require('./models/'); + +var init = function() { + var d = Q.defer(); + var connection = mongoose.connection; + + logger.log("Connection to", config.database.url, "..."); + mongoose.connect(config.database.url, function(err) { + if (err) return d.reject(err); + logger.log("Open on", config.database.url); + + d.resolve(connection); + }); + + connection.on('reconnected', function () { + logger.log('Reconnected'); + }); + + connection.on('disconnected', function () { + logger.log('Disconnected'); + }); + + connection.on('error', function(err) { + logger.exception(err); + }); + + return d.promise; +}; + + +module.exports = { + init: init +}; \ No newline at end of file diff --git a/lib/index.js b/lib/index.js new file mode 100644 index 0000000..83f5c8c --- /dev/null +++ b/lib/index.js @@ -0,0 +1,110 @@ +var _ = require("lodash"); +var Q = require("q"); +var path = require("path"); +var express = require("express"); +var http = require('http'); +var morgan = require('morgan'); +var bodyParser = require('body-parser'); +var cookieParser = require('cookie-parser'); +var basicAuth = require('basic-auth-connect'); + +var config = require("./config"); +var database = require("./database"); +var apis = require("./apis/"); +var queue = require("./queue"); +var jobs = require("./jobs"); +var error = require("./utils/error"); +var logger = require("./utils/logger")("web"); + +var prepare = function(mode) { + return database.init() + .then(function() { + return queue.init(mode); + }) + .then(function() { + if (!queue.worker || mode == "worker") { + return jobs.init(); + } + }); +}; + +var start = function() { + var app = express(); + var server = http.createServer(app); + + // Parse form data + app.use(bodyParser()); + + // Static files + app.use('/', express.static(path.resolve(__dirname, '../public/build'))); + + // Enable logger + app.use(morgan()); + + // Parse and sign cookies + // IMPORTANT: Signing is crucial for security + app.use(cookieParser()); + + // Auth + if (config.auth.username && config.auth.password) { + app.use(basicAuth(config.auth.username, config.auth.password)); + } + + apis.init(app); + + // Error handling + app.use(function(req, res, next) { + next(error.withCode(404, "Page not found")); + }); + app.use(function(err, req, res, next) { + var msg = err.message || err; + var code = Number(err.code || 500); + + if (!_.contains(error.VALID_CODES, code)) code = 500; + + if (req.session) req.session.report = err.stack || err.message || err; + + // Return error + res.format({ + 'text/plain': function(){ + res.status(code); + res.send(msg); + }, + 'application/json': function (){ + res.status(code); + res.send({ + 'error': msg, + 'code': code + }); + } + }); + + logger.error(err.stack || err); + }); + + logger.log("Start listening on ", config.port); + + return prepare("web") + .then(function() { + return Q.nfapply(_.bind(server.listen, server), [config.port]); + }) + .then(function() { + logger.log("Application is now running!"); + }, function(err) { + logger.exception(err, false); + }); +}; + +var worker = function() { + return prepare("worker") + .then(function() { + logger.log("Worker is now running!"); + }, function(err) { + logger.exception(err, false); + }); +}; + +module.exports = { + start: start, + worker: worker +}; \ No newline at end of file diff --git a/lib/jobs/alert.js b/lib/jobs/alert.js new file mode 100644 index 0000000..77e7419 --- /dev/null +++ b/lib/jobs/alert.js @@ -0,0 +1,13 @@ +var Alert = require("../models/alert"); +var Event = require("../models/event"); + +module.exports = function(args) { + return Event.findByIdQ(args.id) + .then(function(e) { + return Alert.post(e); + }) + .then(function() { + return {}; + }); +}; + diff --git a/lib/jobs/index.js b/lib/jobs/index.js new file mode 100644 index 0000000..07c7777 --- /dev/null +++ b/lib/jobs/index.js @@ -0,0 +1,17 @@ +var _ = require("lodash"); +var queue = require("../queue"); + +var JOBS = { + alert: require("./alert"), + post: require("./post") +}; + +var init = function() { + _.each(JOBS, function(func, jobId) { + queue.process(jobId, func); + }); +}; + +module.exports = { + init: init +}; diff --git a/lib/jobs/post.js b/lib/jobs/post.js new file mode 100644 index 0000000..d910822 --- /dev/null +++ b/lib/jobs/post.js @@ -0,0 +1,9 @@ +var Event = require("../models/event"); + +module.exports = function(args) { + Event.push(args.type, args.properties) + .then(function(e) { + return e.repr(); + }); +}; + diff --git a/lib/models/alert.js b/lib/models/alert.js new file mode 100644 index 0000000..ddc32f0 --- /dev/null +++ b/lib/models/alert.js @@ -0,0 +1,144 @@ +var Q = require("q"); +var _ = require("lodash"); +var mongoose = require('mongoose-q')(); +var expressions = require("angular-expressions"); + +var logger = require("../utils/logger")("alerts"); +var alerts = require("../alerts"); +var queue = require("../queue"); + +var alertSchema = new mongoose.Schema({ + title: { + type: String, + required: true + }, + eventName: { + type: String, + required: true, + index: true + }, + condition: { + type: String, + required: true + }, + interval: { + type: Number, + default: 1 + }, + type: { + type: String, + enum: alerts.TYPES, + require: true + }, + configuration: { + type: Object, + default: {} + }, + lastTimeRun: { + type: Date + }, + enabled: { + type: Boolean, + default: true + } +}); + + +// Methods + +// Return a json representation +alertSchema.methods.repr = function() { + return { + 'id': this.id.toString(), + 'type': this.type, + 'title': this.title, + 'condition': this.condition, + 'configuration': this.configuration, + 'eventName': this.eventName, + 'interval': this.interval, + 'enabled': this.enabled + }; +}; + +// Check an alert condition +alertSchema.methods.validCondition = function(scope) { + var expr = expressions.compile(this.condition); + return expr(scope); +}; + +// Check alert for an event +alertSchema.methods.postEvent = function(e) { + var Event = mongoose.models.Event; + var that = this; + var alert = alerts.byId(this.type); + + return Q() + .then(function() { + if (!that.enabled) { + return Q.fail(new Error("Alert is disabled")); + } + if (that.lastTimeRun > (Date.now() - that.interval*60*1000)) { + return Q.fail(new Error("Alert already run in the configurated interval")); + } + + return Q.all([ + Event.find({ + 'type': that.eventName, + 'date': { + '$gt': (Date.now() - that.interval*60*1000) + } + }).countQ() + ]); + }) + .spread(function(COUNT) { + var context = { + 'COUNT': COUNT, + 'event': e.properties + }; + + if (!that.validCondition(context)) { + return Q.fail(new Error("Don't respect condition")); + } + + that.lastTimeRun = new Date(); + return that.saveQ(); + }) + .then(function() { + logger.log("post alert", that.title); + + queue.job("post", { + 'type': "reportr.alert", + 'properties': { + 'alert': that.id.toString(), + 'type': that.type, + 'eventName': that.eventName + }, + 'date': that.lastTimeRun + }); + + return alert.execute(that, that.configuration, e); + }); +}; + +// Send an alert +alertSchema.statics.post = function(e) { + return Alert.find({ + eventName: e.type + }).execQ() + .then(function(alerts) { + return Q.all(_.map(alerts, function(a) { + return a.postEvent(e) + .fail(function(err) { + logger.exception(err, false); + return Q(); + }); + })); + }); +}; + + +// Model +var Alert = mongoose.model('Alert', alertSchema); + +// Exports +module.exports = Alert; diff --git a/lib/models/event.js b/lib/models/event.js new file mode 100644 index 0000000..14af722 --- /dev/null +++ b/lib/models/event.js @@ -0,0 +1,75 @@ +var Q = require("q"); +var _ = require("lodash"); +var mongoose = require('mongoose-q')(); + +var objects = require('../utils/objects'); + +var eventSchema = new mongoose.Schema({ + date: { + type: Date, + required: true, + index: true + }, + type: { + type: String, + required: true, + index: true + }, + properties: { + type: Object, + default: {} + }, + propertiesKeys: { + type: Array, + default: [], + index: true + } +}); + +// Indexes +eventSchema.index({ type: 1, date: 1}); + +eventSchema.pre('save', function(next) { + this.propertiesKeys = _.keys(objects.flatten(this.properties)); + + next(); +}); + + +// Statics + +// Push a new event +eventSchema.statics.push = function(type, properties) { + var Alert = mongoose.models.Alert; + var e = new Event({ + type: type, + properties: properties || {}, + date: new Date() + }); + + return e.saveQ() + .then(function() { + return Alert.post(e); + }) + .then(function() { + return e; + }); +}; + +// Methods + +// Return a json representation +eventSchema.methods.repr = function() { + return { + 'type': this.type, + 'date': Math.floor(this.date.getTime() / 1000), + 'properties': this.properties + }; +} + + +// Model +var Event = mongoose.model('Event', eventSchema); + +// Exports +module.exports = Event; diff --git a/lib/models/index.js b/lib/models/index.js new file mode 100644 index 0000000..16dde41 --- /dev/null +++ b/lib/models/index.js @@ -0,0 +1,5 @@ +module.exports = { + Event: require("./event"), + Report: require("./report"), + Alert: require("./alert") +}; diff --git a/lib/models/report.js b/lib/models/report.js new file mode 100644 index 0000000..ddbe5dc --- /dev/null +++ b/lib/models/report.js @@ -0,0 +1,32 @@ +var Q = require("q"); +var _ = require("lodash"); +var mongoose = require('mongoose-q')(); + +var visualizationSchema = require("./visualization"); + +var reportSchema = new mongoose.Schema({ + title: { + type: String, + required: true + }, + visualizations: [visualizationSchema] +}); + + +// Methods + +// Return a json representation +reportSchema.methods.repr = function() { + return { + id: this.id.toString(), + title: this.title, + visualizations: _.map(this.visualizations, function(v) { return v.repr(); }) + }; +} + + +// Model +var Report = mongoose.model('Report', reportSchema); + +// Exports +module.exports = Report; diff --git a/lib/models/visualization.js b/lib/models/visualization.js new file mode 100644 index 0000000..2a722a6 --- /dev/null +++ b/lib/models/visualization.js @@ -0,0 +1,29 @@ +var Q = require("q"); +var _ = require("lodash"); +var mongoose = require('mongoose-q')(); + +var visualizationSchema = new mongoose.Schema({ + type: { + type: String, + required: true + }, + eventName: { + type: String, + required: true + }, + configuration: { + type: Object, + default: {} + } +}); + +visualizationSchema.methods.repr = function() { + return { + id: this.id.toString(), + type: this.type, + eventName: this.eventName, + configuration: this.configuration + }; +}; + +module.exports = visualizationSchema; diff --git a/lib/queue/index.js b/lib/queue/index.js new file mode 100644 index 0000000..51936b4 --- /dev/null +++ b/lib/queue/index.js @@ -0,0 +1,7 @@ +var config = require("../config"); + +if (config.tasks.redis) { + module.exports = require("./kue"); +} else { + module.exports = require("./memory"); +} diff --git a/lib/queue/kue.js b/lib/queue/kue.js new file mode 100644 index 0000000..1a91e45 --- /dev/null +++ b/lib/queue/kue.js @@ -0,0 +1,53 @@ +var Q = require("q"); +var kue = require('kue'); +var url = require('url'); +var config = require("../config"); +var logger = require("../utils/logger")("queue"); + +var jobs; + +// Init +var init = function() { + logger.log("Init redis tasks queue"); + var redisURL = url.parse(config.tasks.redis); + + jobs = kue.createQueue({ + redis: { + port: redisURL.port, + host: redisURL.hostname, + auth: redisURL.auth? redisURL.auth.split(":")[1] : null, + options: { + no_ready_check: true + } + } + }); +}; + +// Create a job handler +var processJob = function(jobId, func) { + jobs.process(jobId, function(job, done){ + Q() + .then(function() { + return func(job.data); + }) + .then(function() { + done(); + }, function(err) { + logger.exception(err, false); + done(err); + }); + }); +}; + +// Create a new task +var createJob = function(jobId, task) { + logger.log("Create job", jobId); + jobs.create(jobId, task).save(); +}; + +module.exports = { + init: init, + process: processJob, + job: createJob, + worker: true +}; diff --git a/lib/queue/memory.js b/lib/queue/memory.js new file mode 100644 index 0000000..0bf6e23 --- /dev/null +++ b/lib/queue/memory.js @@ -0,0 +1,34 @@ +var Q = require("q"); +var JOBS = {}; +var logger = require("../utils/logger")("queue"); + +// Init +var init = function() { + logger.log("Init in-process tasks queue"); +}; + +// Create a job handler +var processJob = function(jobId, func) { + JOBS[jobId] = func; +}; + +// Create a new task +var createJob = function(jobId, task) { + if (!JOBS[jobId]) return Q.fail(new Error("Invlid job id")); + + logger.log("Create job", jobId); + + return Q() + .then(function() { + return JOBS[jobId](task); + }, function(err) { + logger.exception(err, false); + }); +}; + +module.exports = { + init: init, + process: processJob, + job: createJob, + worker: false +}; diff --git a/lib/utils/error.js b/lib/utils/error.js new file mode 100644 index 0000000..451983e --- /dev/null +++ b/lib/utils/error.js @@ -0,0 +1,34 @@ +var _ = require("lodash"); + +var VALID_CODES = [404, 500, 401]; + +// Return an error with a specific code +var withCode = function(code, msg) { + var e = new Error(msg); + e.code = code; + return e; +}; + +// Normalize mongoose error +var normMongooseError = function(err) { + return _.chain(err.errors || []) + .map(function(_err) { + return [ + _err.path, + { + message: _err.message + } + ]; + }) + .object() + .extend({ + global: (err.errors? null : err) + }) + .value(); +} + +module.exports = { + withCode: withCode, + mongooseError: normMongooseError, + VALID_CODES: VALID_CODES +}; diff --git a/lib/utils/logger.js b/lib/utils/logger.js new file mode 100644 index 0000000..4833baa --- /dev/null +++ b/lib/utils/logger.js @@ -0,0 +1,32 @@ +var _ = require("lodash"); + +// Colors for log types +var colors = { + 'log': ['\x1B[36m', '\x1B[39m'], + 'error': ['\x1B[31m', '\x1B[39m'] +}; + +// Base print method +var print = function(logType, logSection) { + var args = Array.prototype.slice.call(arguments, 2); + args.splice(0, 0, colors[logType][0]+"["+logType+"]"+colors[logType][1]+"["+logSection+"]"); + console.log.apply(console, args); +}; + +var error = _.partial(print, 'error'); +var log = _.partial(print, 'log'); +var exception = _.wrap(error, function(func, logSection, err, kill) { + func(logSection, err.message || err); + console.error(err.stack); + + // Kill process + if (kill != false) process.exit(1); +}); + +module.exports = function(name) { + return { + 'log': _.partial(log, name), + 'error': _.partial(error, name), + 'exception': _.partial(exception, name) + }; +}; \ No newline at end of file diff --git a/lib/utils/objects.js b/lib/utils/objects.js new file mode 100644 index 0000000..d87bf0d --- /dev/null +++ b/lib/utils/objects.js @@ -0,0 +1,31 @@ +var _ = require("lodash"); + +// Transform {a: {b: 1}} -> {"a.b": 1} +var flatten = function(obj, all) { + var keys= {}; + var getBase = function(base, key) { + if (_.size(base) == 0) return key; + return base+"."+key; + }; + + var addKeys = function(_obj, base) { + var _base, _isObject; + base = base || ""; + + _.each(_obj, function(value, key) { + _base = getBase(base, key); + _isObject = _.isObject(value) && !_.isArray(value); + + if (_isObject) addKeys(value, _base); + if (all == true || !_isObject) keys[_base] = value; + }); + }; + + addKeys(obj); + + return keys; +}; + +module.exports = { + flatten: flatten +}; diff --git a/package.json b/package.json new file mode 100644 index 0000000..4940e12 --- /dev/null +++ b/package.json @@ -0,0 +1,49 @@ +{ + "name": "reportr", + "description": "Your life personal dashboard.", + "version": "3.5.1", + "author": "samypesse@gmail.com", + "homepage": "https://github.com/Reportr/dashboard", + "bugs": "https://github.com/Reportr/dashboard/issues", + "repository": { + "type": "git", + "url": "https://github.com/Reportr/dashboard.git" + }, + "dependencies": { + "lodash": "2.4.1", + "q": "1.0.1", + "mongoose-q": "0.0.10", + "express": "4.1.2", + "st": "0.2.5", + "body-parser": "1.0.2", + "cookie-parser": "1.0.1", + "basic-auth-connect": "1.0.0", + "morgan": "1.0.1", + "request": "2.36.0", + "angular-expressions": "0.2.1", + "kue": "0.8.1", + "nodemailer": "0.7.0", + "twilio": "1.6.0" + }, + "devDependencies": { + "mocha": "1.18.2", + "mocha-mongoose": "1.0.1", + "grunt": "~0.4.2", + "grunt-cli": "0.1.11", + "grunt-contrib-less": "~0.5.0", + "grunt-bower-install-simple": "0.9.2", + "grunt-hr-builder": "1.1.0", + "happyrhino": "1.0.5" + }, + "bin": { + "reportr": "./bin/reportr.js" + }, + "scripts": { + "test": "export TESTING=true; mocha --reporter list", + "grunt": "grunt" + }, + "engines": { + "node": "0.10.x", + "npm": "1.4.x" + } +} \ No newline at end of file diff --git a/preview.png b/preview.png new file mode 100644 index 0000000000000000000000000000000000000000..fd81ddd433ef55e1ee9c5155ff15b1a83b79247e GIT binary patch literal 73800 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 CAq&6& literal 0 HcmV?d00001 diff --git a/public/build/index.html b/public/build/index.html new file mode 100644 index 0000000..1374ee6 --- /dev/null +++ b/public/build/index.html @@ -0,0 +1,28 @@ + + + + + Reportr + + + + + + + + + + + +
+
+
+
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/public/build/static/application.css b/public/build/static/application.css new file mode 100644 index 0000000..fac5c9c --- /dev/null +++ b/public/build/static/application.css @@ -0,0 +1 @@ +/*! normalize.css v3.0.0 | MIT License | git.io/normalize */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}@media print{*{text-shadow:none !important;color:#000 !important;background:transparent !important;box-shadow:none !important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}select{background:#fff !important}.navbar{display:none}.table td,.table th{background-color:#fff !important}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000 !important}.label{border:1px solid #000}.table{border-collapse:collapse !important}.table-bordered th,.table-bordered td{border:1px solid #ddd !important}}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:62.5%;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#717171;background-color:#fff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#594f8d;text-decoration:none}a:hover,a:focus{color:#3a345c;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive,.thumbnail>img,.thumbnail a>img,.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 .small,h2 .small,h3 .small,h4 .small,h5 .small,h6 .small,.h1 .small,.h2 .small,.h3 .small,.h4 .small,.h5 .small,.h6 .small{font-weight:normal;line-height:1;color:#999}h1,.h1,h2,.h2,h3,.h3{margin-top:20px;margin-bottom:10px}h1 small,.h1 small,h2 small,.h2 small,h3 small,.h3 small,h1 .small,.h1 .small,h2 .small,.h2 .small,h3 .small,.h3 .small{font-size:65%}h4,.h4,h5,.h5,h6,.h6{margin-top:10px;margin-bottom:10px}h4 small,.h4 small,h5 small,.h5 small,h6 small,.h6 small,h4 .small,.h4 .small,h5 .small,.h5 .small,h6 .small,.h6 .small{font-size:75%}h1,.h1{font-size:36px}h2,.h2{font-size:30px}h3,.h3{font-size:24px}h4,.h4{font-size:18px}h5,.h5{font-size:14px}h6,.h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:200;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}small,.small{font-size:85%}cite{font-style:normal}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-muted{color:#999}.text-primary{color:#594f8d}a.text-primary:hover{color:#443d6c}.text-success{color:#3c763d}a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#594f8d}a.bg-primary:hover{background-color:#443d6c}.bg-success{background-color:#dff0d8}a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ul,ol{margin-top:0;margin-bottom:10px}ul ul,ol ul,ul ol,ol ol{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none;margin-left:-5px}.list-inline>li{display:inline-block;padding-left:5px;padding-right:5px}dl{margin-top:0;margin-bottom:20px}dt,dd{line-height:1.42857143}dt{font-weight:bold}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote p:last-child,blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0}blockquote footer,blockquote small,blockquote .small{display:block;font-size:80%;line-height:1.42857143;color:#999}blockquote footer:before,blockquote small:before,blockquote .small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0;text-align:right}.blockquote-reverse footer:before,blockquote.pull-right footer:before,.blockquote-reverse small:before,blockquote.pull-right small:before,.blockquote-reverse .small:before,blockquote.pull-right .small:before{content:''}.blockquote-reverse footer:after,blockquote.pull-right footer:after,.blockquote-reverse small:after,blockquote.pull-right small:after,.blockquote-reverse .small:after,blockquote.pull-right .small:after{content:'\00A0 \2014'}blockquote:before,blockquote:after{content:""}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;white-space:nowrap;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;box-shadow:inset 0 -1px 0 rgba(0,0,0,0.25)}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;word-break:break-all;word-wrap:break-word;color:#333;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{margin-right:auto;margin-left:auto;padding-left:7.5px;padding-right:7.5px}@media (min-width:768px){.container{width:735px}}@media (min-width:992px){.container{width:955px}}@media (min-width:1200px){.container{width:1155px}}.container-fluid{margin-right:auto;margin-left:auto;padding-left:7.5px;padding-right:7.5px}.row{margin-left:-7.5px;margin-right:-7.5px}.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12{position:relative;min-height:1px;padding-left:7.5px;padding-right:7.5px}.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:0}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:0}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:0}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:0}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:0}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:0}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:0}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:0}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{max-width:100%;background-color:transparent}th{text-align:left}.table{width:100%;margin-bottom:20px}.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>th,.table>caption+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>td,.table>thead:first-child>tr:first-child>td{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>thead>tr>th,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>tbody>tr>td,.table-condensed>tfoot>tr>td{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-child(odd)>td,.table-striped>tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.table-hover>tbody>tr:hover>td,.table-hover>tbody>tr:hover>th{background-color:#f5f5f5}table col[class*="col-"]{position:static;float:none;display:table-column}table td[class*="col-"],table th[class*="col-"]{position:static;float:none;display:table-cell}.table>thead>tr>td.active,.table>tbody>tr>td.active,.table>tfoot>tr>td.active,.table>thead>tr>th.active,.table>tbody>tr>th.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>tbody>tr.active>td,.table>tfoot>tr.active>td,.table>thead>tr.active>th,.table>tbody>tr.active>th,.table>tfoot>tr.active>th{background-color:#f5f5f5}.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover,.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th{background-color:#e8e8e8}.table>thead>tr>td.success,.table>tbody>tr>td.success,.table>tfoot>tr>td.success,.table>thead>tr>th.success,.table>tbody>tr>th.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>tbody>tr.success>td,.table>tfoot>tr.success>td,.table>thead>tr.success>th,.table>tbody>tr.success>th,.table>tfoot>tr.success>th{background-color:#dff0d8}.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover,.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th{background-color:#d0e9c6}.table>thead>tr>td.info,.table>tbody>tr>td.info,.table>tfoot>tr>td.info,.table>thead>tr>th.info,.table>tbody>tr>th.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>tbody>tr.info>td,.table>tfoot>tr.info>td,.table>thead>tr.info>th,.table>tbody>tr.info>th,.table>tfoot>tr.info>th{background-color:#d9edf7}.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover,.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th{background-color:#c4e3f3}.table>thead>tr>td.warning,.table>tbody>tr>td.warning,.table>tfoot>tr>td.warning,.table>thead>tr>th.warning,.table>tbody>tr>th.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>tbody>tr.warning>td,.table>tfoot>tr.warning>td,.table>thead>tr.warning>th,.table>tbody>tr.warning>th,.table>tfoot>tr.warning>th{background-color:#fcf8e3}.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover,.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th{background-color:#faf2cc}.table>thead>tr>td.danger,.table>tbody>tr>td.danger,.table>tfoot>tr>td.danger,.table>thead>tr>th.danger,.table>tbody>tr>th.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>tbody>tr.danger>td,.table>tfoot>tr.danger>td,.table>thead>tr.danger>th,.table>tbody>tr.danger>th,.table>tfoot>tr.danger>th{background-color:#f2dede}.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover,.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th{background-color:#ebcccc}@media (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;overflow-x:scroll;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd;-webkit-overflow-scrolling:touch}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}fieldset{padding:0;margin:0;border:0;min-width:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;margin-bottom:5px;font-weight:bold}input[type="search"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type="file"]{display:block}input[type="range"]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border-color ease-in-out .15s, box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s, box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{cursor:not-allowed;background-color:#eee;opacity:1}textarea.form-control{height:auto}input[type="search"]{-webkit-appearance:none}input[type="date"]{line-height:34px}.form-group{margin-bottom:15px}.radio,.checkbox{display:block;min-height:20px;margin-top:10px;margin-bottom:10px;padding-left:20px}.radio label,.checkbox label{display:inline;font-weight:normal;cursor:pointer}.radio input[type="radio"],.radio-inline input[type="radio"],.checkbox input[type="checkbox"],.checkbox-inline input[type="checkbox"]{float:left;margin-left:-20px}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{display:inline-block;padding-left:20px;margin-bottom:0;vertical-align:middle;font-weight:normal;cursor:pointer}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}input[type="radio"][disabled],input[type="checkbox"][disabled],.radio[disabled],.radio-inline[disabled],.checkbox[disabled],.checkbox-inline[disabled],fieldset[disabled] input[type="radio"],fieldset[disabled] input[type="checkbox"],fieldset[disabled] .radio,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}textarea.input-sm,select[multiple].input-sm{height:auto}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-lg{height:46px;line-height:46px}textarea.input-lg,select[multiple].input-lg{height:auto}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.has-feedback .form-control-feedback{position:absolute;top:25px;right:0;display:block;width:34px;height:34px;line-height:34px;text-align:center}.has-success .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;border-color:#3c763d;background-color:#dff0d8}.has-success .form-control-feedback{color:#3c763d}.has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;border-color:#8a6d3b;background-color:#fcf8e3}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;border-color:#a94442;background-color:#f2dede}.has-error .form-control-feedback{color:#a94442}.form-control-static{margin-bottom:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#b1b1b1}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .radio,.form-inline .checkbox{display:inline-block;margin-top:0;margin-bottom:0;padding-left:0;vertical-align:middle}.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:none;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .control-label,.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{margin-top:0;margin-bottom:0;padding-top:7px}.form-horizontal .radio,.form-horizontal .checkbox{min-height:27px}.form-horizontal .form-group{margin-left:-7.5px;margin-right:-7.5px}.form-horizontal .form-control-static{padding-top:7px}@media (min-width:768px){.form-horizontal .control-label{text-align:right}}.form-horizontal .has-feedback .form-control-feedback{top:0;right:7.5px}.btn{display:inline-block;margin-bottom:0;font-weight:normal;text-align:center;vertical-align:middle;cursor:pointer;background-image:none;border:1px solid transparent;white-space:nowrap;padding:6px 12px;font-size:14px;line-height:1.42857143;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn:focus,.btn:active:focus,.btn.active:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus{color:#333;text-decoration:none}.btn:active,.btn.active{outline:0;background-image:none;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;pointer-events:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default:hover,.btn-default:focus,.btn-default:active,.btn-default.active,.open .dropdown-toggle.btn-default{color:#333;background-color:#ebebeb;border-color:#adadad}.btn-default:active,.btn-default.active,.open .dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default[disabled],fieldset[disabled] .btn-default,.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled:active,.btn-default[disabled]:active,fieldset[disabled] .btn-default:active,.btn-default.disabled.active,.btn-default[disabled].active,fieldset[disabled] .btn-default.active{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#594f8d;border-color:#4f467d}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.open .dropdown-toggle.btn-primary{color:#fff;background-color:#484073;border-color:#363055}.btn-primary:active,.btn-primary.active,.open .dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary[disabled],fieldset[disabled] .btn-primary,.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled:active,.btn-primary[disabled]:active,fieldset[disabled] .btn-primary:active,.btn-primary.disabled.active,.btn-primary[disabled].active,fieldset[disabled] .btn-primary.active{background-color:#594f8d;border-color:#4f467d}.btn-primary .badge{color:#594f8d;background-color:#fff}.btn-success{color:#fff;background-color:#a6d87a;border-color:#99d266}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.open .dropdown-toggle.btn-success{color:#fff;background-color:#91cf5a;border-color:#79c239}.btn-success:active,.btn-success.active,.open .dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success[disabled],fieldset[disabled] .btn-success,.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled:active,.btn-success[disabled]:active,fieldset[disabled] .btn-success:active,.btn-success.disabled.active,.btn-success[disabled].active,fieldset[disabled] .btn-success.active{background-color:#a6d87a;border-color:#99d266}.btn-success .badge{color:#a6d87a;background-color:#fff}.btn-info{color:#fff;background-color:#81daf6;border-color:#69d3f4}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.open .dropdown-toggle.btn-info{color:#fff;background-color:#5bcff3;border-color:#30c2f0}.btn-info:active,.btn-info.active,.open .dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info[disabled],fieldset[disabled] .btn-info,.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled:active,.btn-info[disabled]:active,fieldset[disabled] .btn-info:active,.btn-info.disabled.active,.btn-info[disabled].active,fieldset[disabled] .btn-info.active{background-color:#81daf6;border-color:#69d3f4}.btn-info .badge{color:#81daf6;background-color:#fff}.btn-warning{color:#fff;background-color:#fcc44d;border-color:#fcbc34}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.open .dropdown-toggle.btn-warning{color:#fff;background-color:#fbb725;border-color:#eea304}.btn-warning:active,.btn-warning.active,.open .dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-warning,.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled:active,.btn-warning[disabled]:active,fieldset[disabled] .btn-warning:active,.btn-warning.disabled.active,.btn-warning[disabled].active,fieldset[disabled] .btn-warning.active{background-color:#fcc44d;border-color:#fcbc34}.btn-warning .badge{color:#fcc44d;background-color:#fff}.btn-danger{color:#fff;background-color:#fb6b5b;border-color:#fa5542}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.open .dropdown-toggle.btn-danger{color:#fff;background-color:#fa4733;border-color:#f91f06}.btn-danger:active,.btn-danger.active,.open .dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger[disabled],fieldset[disabled] .btn-danger,.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled:active,.btn-danger[disabled]:active,fieldset[disabled] .btn-danger:active,.btn-danger.disabled.active,.btn-danger[disabled].active,fieldset[disabled] .btn-danger.active{background-color:#fb6b5b;border-color:#fa5542}.btn-danger .badge{color:#fb6b5b;background-color:#fff}.btn-link{color:#594f8d;font-weight:normal;cursor:pointer;border-radius:0}.btn-link,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#3a345c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#999;text-decoration:none}.btn-lg,.btn-group-lg>.btn{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.btn-sm,.btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs,.btn-group-xs>.btn{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%;padding-left:0;padding-right:0}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;transition:height .35s ease}@font-face{font-family:'Glyphicons Halflings';src:url('../fonts/glyphicons-halflings-regular.eot');src:url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'),url('../fonts/glyphicons-halflings-regular.woff') format('woff'),url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'),url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px solid;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;font-size:14px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,0.175);box-shadow:0 6px 12px rgba(0,0,0,0.175);background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{text-decoration:none;color:#262626;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;outline:0;background-color:#594f8d}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#999}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);cursor:not-allowed}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{left:auto;right:0}.dropdown-menu-left{left:0;right:auto}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#999}.dropdown-backdrop{position:fixed;left:0;right:0;bottom:0;top:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}@media (min-width:768px){.navbar-right .dropdown-menu{left:auto;right:0}.navbar-right .dropdown-menu-left{left:0;right:auto}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;float:left}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover,.btn-group>.btn:focus,.btn-group-vertical>.btn:focus,.btn-group>.btn:active,.btn-group-vertical>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn.active{z-index:2}.btn-group>.btn:focus,.btn-group-vertical>.btn:focus{outline:none}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child>.btn:last-child,.btn-group>.btn-group:first-child>.dropdown-toggle{border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn-group:last-child>.btn:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-left:8px;padding-right:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-left:12px;padding-right:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-bottom-left-radius:4px;border-top-right-radius:0;border-top-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-right-radius:0;border-top-left-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{float:none;display:table-cell;width:1%}.btn-group-justified>.btn-group .btn{width:100%}[data-toggle="buttons"]>.btn>input[type="radio"],[data-toggle="buttons"]>.btn>input[type="checkbox"]{display:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*="col-"]{float:none;padding-left:0;padding-right:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn,select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn,select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn{height:auto}.input-group-addon,.input-group-btn,.input-group .form-control{display:table-cell}.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child),.input-group .form-control:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:normal;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type="radio"],.input-group-addon input[type="checkbox"]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group-btn:last-child>.btn-group:not(:last-child)>.btn{border-bottom-right-radius:0;border-top-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:first-child>.btn-group:not(:first-child)>.btn{border-bottom-left-radius:0;border-top-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:hover,.input-group-btn>.btn:focus,.input-group-btn>.btn:active{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{margin-left:-1px}.nav{margin-bottom:0;padding-left:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#999}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#999;text-decoration:none;background-color:transparent;cursor:not-allowed}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#eee;border-color:#594f8d}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{color:#555;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent;cursor:default}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{text-align:center;margin-bottom:5px}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{color:#fff;background-color:#594f8d}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{text-align:center;margin-bottom:5px}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-right-radius:0;border-top-left-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{max-height:340px;overflow-x:visible;padding-right:7px;padding-left:7px;border-top:1px solid transparent;box-shadow:inset 0 1px 0 rgba(255,255,255,0.1);-webkit-overflow-scrolling:touch}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;box-shadow:none}.navbar-collapse.collapse{display:block !important;height:auto !important;padding-bottom:0;overflow:visible !important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{padding-left:0;padding-right:0}}.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:-7px;margin-left:-7px}@media (min-width:768px){.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;padding:15px 7px;font-size:18px;line-height:20px;height:50px}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-7px}}.navbar-toggle{position:relative;float:right;margin-right:7px;padding:9px 10px;margin-top:8px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:none}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -7px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;box-shadow:none}.navbar-nav .open .dropdown-menu>li>a,.navbar-nav .open .dropdown-menu .dropdown-header{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:hover,.navbar-nav .open .dropdown-menu>li>a:focus{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}.navbar-nav.navbar-right:last-child{margin-right:-7px}}@media (min-width:768px){.navbar-left{float:left !important}.navbar-right{float:right !important}}.navbar-form{margin-left:-7px;margin-right:-7px;padding:10px 7px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);margin-top:8px;margin-bottom:8px}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .radio,.navbar-form .checkbox{display:inline-block;margin-top:0;margin-bottom:0;padding-left:0;vertical-align:middle}.navbar-form .radio input[type="radio"],.navbar-form .checkbox input[type="checkbox"]{float:none;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}}@media (min-width:768px){.navbar-form{width:auto;border:0;margin-left:0;margin-right:0;padding-top:0;padding-bottom:0;-webkit-box-shadow:none;box-shadow:none}.navbar-form.navbar-right:last-child{margin-right:-7px}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-right-radius:0;border-top-left-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-left:7px;margin-right:7px}.navbar-text.navbar-right:last-child{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:hover,.navbar-default .navbar-nav>.open>a:focus{background-color:#e7e7e7;color:#555}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#999}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#999}.navbar-inverse .navbar-nav>li>a{color:#999}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:hover,.navbar-inverse .navbar-nav>.open>a:focus{background-color:#080808;color:#fff}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#999}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#999}.navbar-inverse .navbar-link:hover{color:#fff}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{content:"/\00a0";padding:0 5px;color:#ccc}.breadcrumb>.active{color:#999}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;line-height:1.42857143;text-decoration:none;color:#594f8d;background-color:#fff;border:1px solid #ddd;margin-left:-1px}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-bottom-left-radius:4px;border-top-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-bottom-right-radius:4px;border-top-right-radius:4px}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{color:#3a345c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:2;color:#fff;background-color:#594f8d;border-color:#594f8d;cursor:default}.pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#999;background-color:#fff;border-color:#ddd;cursor:not-allowed}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-bottom-left-radius:6px;border-top-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-bottom-right-radius:6px;border-top-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-bottom-left-radius:3px;border-top-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-bottom-right-radius:3px;border-top-right-radius:3px}.pager{padding-left:0;margin:20px 0;list-style:none;text-align:center}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#999;background-color:#fff;cursor:not-allowed}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:bold;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}.label[href]:hover,.label[href]:focus{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#999}.label-default[href]:hover,.label-default[href]:focus{background-color:#808080}.label-primary{background-color:#594f8d}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#443d6c}.label-success{background-color:#a6d87a}.label-success[href]:hover,.label-success[href]:focus{background-color:#8ccc53}.label-info{background-color:#81daf6}.label-info[href]:hover,.label-info[href]:focus{background-color:#51ccf3}.label-warning{background-color:#fcc44d}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#fbb31b}.label-danger{background-color:#fb6b5b}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#fa3e29}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:bold;color:#fff;line-height:1;vertical-align:baseline;white-space:nowrap;text-align:center;background-color:#999;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-xs .badge{top:0;padding:1px 5px}a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}a.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#594f8d;background-color:#fff}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron h1,.jumbotron .h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.container .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron{padding-left:60px;padding-right:60px}.jumbotron h1,.jumbotron .h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.thumbnail>img,.thumbnail a>img{margin-left:auto;margin-right:auto}a.thumbnail:hover,a.thumbnail:focus,a.thumbnail.active{border-color:#594f8d}.thumbnail .caption{padding:9px;color:#717171}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:bold}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable{padding-right:35px}.alert-dismissable .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{background-color:#dff0d8;border-color:#d6e9c6;color:#3c763d}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{background-color:#d9edf7;border-color:#bce8f1;color:#31708f}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{background-color:#fcf8e3;border-color:#faebcc;color:#8a6d3b}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{background-color:#f2dede;border-color:#ebccd1;color:#a94442}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{overflow:hidden;height:20px;margin-bottom:20px;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#594f8d;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-transition:width .6s ease;transition:width .6s ease}.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-size:40px 40px}.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#a6d87a}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-info{background-color:#81daf6}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-warning{background-color:#fcc44d}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-danger{background-color:#fb6b5b}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.media,.media-body{overflow:hidden;zoom:1}.media,.media .media{margin-top:15px}.media:first-child{margin-top:0}.media-object{display:block}.media-heading{margin:0 0 5px}.media>.pull-left{margin-right:10px}.media>.pull-right{margin-left:10px}.media-list{padding-left:0;list-style:none}.list-group{margin-bottom:20px;padding-left:0}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-right-radius:4px;border-top-left-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}a.list-group-item{color:#555}a.list-group-item .list-group-item-heading{color:#333}a.list-group-item:hover,a.list-group-item:focus{text-decoration:none;background-color:#f5f5f5}a.list-group-item.active,a.list-group-item.active:hover,a.list-group-item.active:focus{z-index:2;color:#fff;background-color:#594f8d;border-color:#594f8d}a.list-group-item.active .list-group-item-heading,a.list-group-item.active:hover .list-group-item-heading,a.list-group-item.active:focus .list-group-item-heading{color:inherit}a.list-group-item.active .list-group-item-text,a.list-group-item.active:hover .list-group-item-text,a.list-group-item.active:focus .list-group-item-text{color:#ccc8e0}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:hover,a.list-group-item-success:focus{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:hover,a.list-group-item-success.active:focus{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:hover,a.list-group-item-info:focus{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:hover,a.list-group-item-info.active:focus{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:hover,a.list-group-item-warning:focus{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:hover,a.list-group-item-warning.active:focus{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:hover,a.list-group-item-danger:focus{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:hover,a.list-group-item-danger.active:focus{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.05);box-shadow:0 1px 1px rgba(0,0,0,0.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-right-radius:3px;border-top-left-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group{margin-bottom:0}.panel>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-right-radius:3px;border-top-left-radius:3px}.panel>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.table:first-child,.panel>.table-responsive:first-child>.table:first-child{border-top-right-radius:3px;border-top-left-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table:last-child,.panel>.table-responsive:last-child>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child th,.panel>.table>tbody:first-child>tr:first-child td{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{border:0;margin-bottom:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px;overflow:hidden}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse .panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse .panel-body{border-top-color:#ddd}.panel-default>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#594f8d}.panel-primary>.panel-heading{color:#fff;background-color:#594f8d;border-color:#594f8d}.panel-primary>.panel-heading+.panel-collapse .panel-body{border-top-color:#594f8d}.panel-primary>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#594f8d}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse .panel-body{border-top-color:#d6e9c6}.panel-success>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse .panel-body{border-top-color:#bce8f1}.panel-info>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse .panel-body{border-top-color:#faebcc}.panel-warning>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse .panel-body{border-top-color:#ebccd1}.panel-danger>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#ebccd1}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:bold;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;opacity:.5;filter:alpha(opacity=50)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}.modal{display:none;overflow:auto;overflow-y:scroll;position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transform:translate(0, -25%);-ms-transform:translate(0, -25%);transform:translate(0, -25%);-webkit-transition:-webkit-transform 0.3s ease-out;-moz-transition:-moz-transform 0.3s ease-out;-o-transition:-o-transform 0.3s ease-out;transition:transform 0.3s ease-out}.modal.in .modal-dialog{-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);transform:translate(0, 0)}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,0.2);border-radius:6px;-webkit-box-shadow:0 3px 9px rgba(0,0,0,0.5);box-shadow:0 3px 9px rgba(0,0,0,0.5);background-clip:padding-box;outline:none}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#fff}.modal-backdrop.fade{opacity:0;filter:alpha(opacity=0)}.modal-backdrop.in{opacity:.5;filter:alpha(opacity=50)}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5;min-height:16.42857143px}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:20px}.modal-footer{margin-top:15px;padding:19px 20px 20px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-left:5px;margin-bottom:0}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,0.5);box-shadow:0 5px 15px rgba(0,0,0,0.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1030;display:block;visibility:visible;font-size:12px;line-height:1.4;opacity:0;filter:alpha(opacity=0)}.tooltip.in{opacity:.9;filter:alpha(opacity=90)}.tooltip.top{margin-top:-3px;padding:5px 0}.tooltip.right{margin-left:3px;padding:0 5px}.tooltip.bottom{margin-top:3px;padding:5px 0}.tooltip.left{margin-left:-3px;padding:0 5px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{bottom:0;left:5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;right:5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;left:5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;right:5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1010;display:none;max-width:276px;padding:1px;text-align:left;background-color:#fff;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);white-space:normal}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{margin:0;padding:8px 14px;font-size:14px;font-weight:normal;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{border-width:10px;content:""}.popover.top>.arrow{left:50%;margin-left:-11px;border-bottom-width:0;border-top-color:#999;border-top-color:rgba(0,0,0,0.25);bottom:-11px}.popover.top>.arrow:after{content:" ";bottom:1px;margin-left:-10px;border-bottom-width:0;border-top-color:#fff}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-left-width:0;border-right-color:#999;border-right-color:rgba(0,0,0,0.25)}.popover.right>.arrow:after{content:" ";left:1px;bottom:-10px;border-left-width:0;border-right-color:#fff}.popover.bottom>.arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,0.25);top:-11px}.popover.bottom>.arrow:after{content:" ";top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,0.25)}.popover.left>.arrow:after{content:" ";right:1px;border-right-width:0;border-left-color:#fff;bottom:-10px}.carousel{position:relative}.carousel-inner{position:relative;overflow:hidden;width:100%}.carousel-inner>.item{display:none;position:relative;-webkit-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{line-height:1}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;left:0;bottom:0;width:15%;opacity:.5;filter:alpha(opacity=50);font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,0.6)}.carousel-control.left{background-image:-webkit-linear-gradient(left, color-stop(rgba(0,0,0,0.5) 0), color-stop(rgba(0,0,0,0.0001) 100%));background-image:linear-gradient(to right, rgba(0,0,0,0.5) 0, rgba(0,0,0,0.0001) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1)}.carousel-control.right{left:auto;right:0;background-image:-webkit-linear-gradient(left, color-stop(rgba(0,0,0,0.0001) 0), color-stop(rgba(0,0,0,0.5) 100%));background-image:linear-gradient(to right, rgba(0,0,0,0.0001) 0, rgba(0,0,0,0.5) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1)}.carousel-control:hover,.carousel-control:focus{outline:none;color:#fff;text-decoration:none;opacity:.9;filter:alpha(opacity=90)}.carousel-control .icon-prev,.carousel-control .icon-next,.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right{position:absolute;top:50%;z-index:5;display:inline-block}.carousel-control .icon-prev,.carousel-control .glyphicon-chevron-left{left:50%}.carousel-control .icon-next,.carousel-control .glyphicon-chevron-right{right:50%}.carousel-control .icon-prev,.carousel-control .icon-next{width:20px;height:20px;margin-top:-10px;margin-left:-10px;font-family:serif}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;margin-left:-30%;padding-left:0;list-style:none;text-align:center}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;border:1px solid #fff;border-radius:10px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0)}.carousel-indicators .active{margin:0;width:12px;height:12px;background-color:#fff}.carousel-caption{position:absolute;left:15%;right:15%;bottom:20px;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,0.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-prev,.carousel-control .icon-next{width:30px;height:30px;margin-top:-15px;margin-left:-15px;font-size:30px}.carousel-caption{left:20%;right:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.clearfix:before,.clearfix:after,.container:before,.container:after,.container-fluid:before,.container-fluid:after,.row:before,.row:after,.form-horizontal .form-group:before,.form-horizontal .form-group:after,.btn-toolbar:before,.btn-toolbar:after,.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after,.nav:before,.nav:after,.navbar:before,.navbar:after,.navbar-header:before,.navbar-header:after,.navbar-collapse:before,.navbar-collapse:after,.pager:before,.pager:after,.panel-body:before,.panel-body:after,.modal-footer:before,.modal-footer:after{content:" ";display:table}.clearfix:after,.container:after,.container-fluid:after,.row:after,.form-horizontal .form-group:after,.btn-toolbar:after,.btn-group-vertical>.btn-group:after,.nav:after,.navbar:after,.navbar-header:after,.navbar-collapse:after,.pager:after,.panel-body:after,.modal-footer:after{clear:both}.center-block{display:block;margin-left:auto;margin-right:auto}.pull-right{float:right !important}.pull-left{float:left !important}.hide{display:none !important}.show{display:block !important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none !important;visibility:hidden !important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-xs,.visible-sm,.visible-md,.visible-lg{display:none !important}@media (max-width:767px){.visible-xs{display:block !important}table.visible-xs{display:table}tr.visible-xs{display:table-row !important}th.visible-xs,td.visible-xs{display:table-cell !important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block !important}table.visible-sm{display:table}tr.visible-sm{display:table-row !important}th.visible-sm,td.visible-sm{display:table-cell !important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block !important}table.visible-md{display:table}tr.visible-md{display:table-row !important}th.visible-md,td.visible-md{display:table-cell !important}}@media (min-width:1200px){.visible-lg{display:block !important}table.visible-lg{display:table}tr.visible-lg{display:table-row !important}th.visible-lg,td.visible-lg{display:table-cell !important}}@media (max-width:767px){.hidden-xs{display:none !important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none !important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none !important}}@media (min-width:1200px){.hidden-lg{display:none !important}}.visible-print{display:none !important}@media print{.visible-print{display:block !important}table.visible-print{display:table}tr.visible-print{display:table-row !important}th.visible-print,td.visible-print{display:table-cell !important}}@media print{.hidden-print{display:none !important}}.rickshaw_graph .detail{pointer-events:none;position:absolute;top:0;z-index:2;background:rgba(0,0,0,0.1);bottom:0;width:1px;transition:opacity .25s linear;-moz-transition:opacity .25s linear;-o-transition:opacity .25s linear;-webkit-transition:opacity .25s linear}.rickshaw_graph .detail.inactive{opacity:0}.rickshaw_graph .detail .item.active{opacity:1}.rickshaw_graph .detail .x_label{font-family:Arial,sans-serif;border-radius:3px;padding:6px;opacity:.5;border:1px solid #e0e0e0;font-size:12px;position:absolute;background:#fff;white-space:nowrap}.rickshaw_graph .detail .x_label.left{left:0}.rickshaw_graph .detail .x_label.right{right:0}.rickshaw_graph .detail .item{position:absolute;z-index:2;border-radius:3px;padding:.25em;font-size:12px;font-family:Arial,sans-serif;opacity:0;background:rgba(0,0,0,0.4);color:#fff;border:1px solid rgba(0,0,0,0.4);margin-left:1em;margin-right:1em;margin-top:-1em;white-space:nowrap}.rickshaw_graph .detail .item.left{left:0}.rickshaw_graph .detail .item.right{right:0}.rickshaw_graph .detail .item.active{opacity:1;background:rgba(0,0,0,0.8)}.rickshaw_graph .detail .item:after{position:absolute;display:block;width:0;height:0;content:"";border:5px solid transparent}.rickshaw_graph .detail .item.left:after{top:1em;left:-5px;margin-top:-5px;border-right-color:rgba(0,0,0,0.8);border-left-width:0}.rickshaw_graph .detail .item.right:after{top:1em;right:-5px;margin-top:-5px;border-left-color:rgba(0,0,0,0.8);border-right-width:0}.rickshaw_graph .detail .dot{width:4px;height:4px;margin-left:-2px;margin-top:-2px;border-radius:5px;position:absolute;box-shadow:0 0 2px rgba(0,0,0,0.6);background:#fff;border-width:2px;border-style:solid;display:none;background-clip:padding-box}.rickshaw_graph .detail .dot.active{display:block}.rickshaw_graph{position:relative}.rickshaw_graph svg{display:block;overflow:hidden}.rickshaw_graph .x_tick{position:absolute;top:0;bottom:0;width:0;border-left:1px dotted rgba(0,0,0,0.2);pointer-events:none}.rickshaw_graph .x_tick .title{position:absolute;font-size:12px;font-family:Arial,sans-serif;opacity:.5;white-space:nowrap;margin-left:3px;bottom:1px}.rickshaw_annotation_timeline{height:1px;border-top:1px solid #e0e0e0;margin-top:10px;position:relative}.rickshaw_annotation_timeline .annotation{position:absolute;height:6px;width:6px;margin-left:-2px;top:-3px;border-radius:5px;background-color:rgba(0,0,0,0.25)}.rickshaw_graph .annotation_line{position:absolute;top:0;bottom:-6px;width:0;border-left:2px solid rgba(0,0,0,0.3);display:none}.rickshaw_graph .annotation_line.active{display:block}.rickshaw_graph .annotation_range{background:rgba(0,0,0,0.1);display:none;position:absolute;top:0;bottom:-6px}.rickshaw_graph .annotation_range.active{display:block}.rickshaw_graph .annotation_range.active.offscreen{display:none}.rickshaw_annotation_timeline .annotation .content{background:#fff;color:#000;opacity:.9;padding:5px 5px;box-shadow:0 0 2px rgba(0,0,0,0.8);border-radius:3px;position:relative;z-index:20;font-size:12px;padding:6px 8px 8px;top:18px;left:-11px;width:160px;display:none;cursor:pointer}.rickshaw_annotation_timeline .annotation .content:before{content:"\25b2";position:absolute;top:-11px;color:#fff;text-shadow:0 -1px 1px rgba(0,0,0,0.8)}.rickshaw_annotation_timeline .annotation.active,.rickshaw_annotation_timeline .annotation:hover{background-color:rgba(0,0,0,0.8);cursor:none}.rickshaw_annotation_timeline .annotation .content:hover{z-index:50}.rickshaw_annotation_timeline .annotation.active .content{display:block}.rickshaw_annotation_timeline .annotation:hover .content{display:block;z-index:50}.rickshaw_graph .y_axis,.rickshaw_graph .x_axis_d3{fill:none}.rickshaw_graph .y_ticks .tick,.rickshaw_graph .x_ticks_d3 .tick{stroke:rgba(0,0,0,0.16);stroke-width:2px;shape-rendering:crisp-edges;pointer-events:none}.rickshaw_graph .y_grid .tick,.rickshaw_graph .x_grid_d3 .tick{z-index:-1;stroke:rgba(0,0,0,0.2);stroke-width:1px;stroke-dasharray:1 1}.rickshaw_graph .y_grid .tick[data-y-value="0"]{stroke-dasharray:1 0}.rickshaw_graph .y_grid path,.rickshaw_graph .x_grid_d3 path{fill:none;stroke:none}.rickshaw_graph .y_ticks path,.rickshaw_graph .x_ticks_d3 path{fill:none;stroke:#808080}.rickshaw_graph .y_ticks text,.rickshaw_graph .x_ticks_d3 text{opacity:.5;font-size:12px;pointer-events:none}.rickshaw_graph .x_tick.glow .title,.rickshaw_graph .y_ticks.glow text{fill:#000;color:#000;text-shadow:-1px 1px 0 rgba(255,255,255,0.1),1px -1px 0 rgba(255,255,255,0.1),1px 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1),0 -1px 0 rgba(255,255,255,0.1),1px 0 0 rgba(255,255,255,0.1),-1px 0 0 rgba(255,255,255,0.1),-1px -1px 0 rgba(255,255,255,0.1)}.rickshaw_graph .x_tick.inverse .title,.rickshaw_graph .y_ticks.inverse text{fill:#fff;color:#fff;text-shadow:-1px 1px 0 rgba(0,0,0,0.8),1px -1px 0 rgba(0,0,0,0.8),1px 1px 0 rgba(0,0,0,0.8),0 1px 0 rgba(0,0,0,0.8),0 -1px 0 rgba(0,0,0,0.8),1px 0 0 rgba(0,0,0,0.8),-1px 0 0 rgba(0,0,0,0.8),-1px -1px 0 rgba(0,0,0,0.8)}.rickshaw_legend{font-family:Arial;font-size:12px;color:#fff;background:#404040;display:inline-block;padding:12px 5px;border-radius:2px;position:relative}.rickshaw_legend:hover{z-index:10}.rickshaw_legend .swatch{width:10px;height:10px;border:1px solid rgba(0,0,0,0.2)}.rickshaw_legend .line{clear:both;line-height:140%;padding-right:15px}.rickshaw_legend .line .swatch{display:inline-block;margin-right:3px;border-radius:2px}.rickshaw_legend .label{margin:0;white-space:nowrap;display:inline;font-size:inherit;background-color:transparent;color:inherit;font-weight:normal;line-height:normal;padding:0;text-shadow:none}.rickshaw_legend .action:hover{opacity:.6}.rickshaw_legend .action{margin-right:.2em;font-size:10px;opacity:.2;cursor:pointer;font-size:14px}.rickshaw_legend .line.disabled{opacity:.4}.rickshaw_legend ul{list-style-type:none;margin:0;padding:0;margin:2px;cursor:pointer}.rickshaw_legend li{padding:0 0 0 2px;min-width:80px;white-space:nowrap}.rickshaw_legend li:hover{background:rgba(255,255,255,0.08);border-radius:3px}.rickshaw_legend li:active{background:rgba(255,255,255,0.2);border-radius:3px}.leaflet-map-pane,.leaflet-tile,.leaflet-marker-icon,.leaflet-marker-shadow,.leaflet-tile-pane,.leaflet-tile-container,.leaflet-overlay-pane,.leaflet-shadow-pane,.leaflet-marker-pane,.leaflet-popup-pane,.leaflet-overlay-pane svg,.leaflet-zoom-box,.leaflet-image-layer,.leaflet-layer{position:absolute;left:0;top:0}.leaflet-container{overflow:hidden;-ms-touch-action:none}.leaflet-tile,.leaflet-marker-icon,.leaflet-marker-shadow{-webkit-user-select:none;-moz-user-select:none;user-select:none;-webkit-user-drag:none}.leaflet-marker-icon,.leaflet-marker-shadow{display:block}.leaflet-container img{max-width:none !important}.leaflet-container img.leaflet-image-layer{max-width:15000px !important}.leaflet-tile{filter:inherit;visibility:hidden}.leaflet-tile-loaded{visibility:inherit}.leaflet-zoom-box{width:0;height:0}.leaflet-overlay-pane svg{-moz-user-select:none}.leaflet-tile-pane{z-index:2}.leaflet-objects-pane{z-index:3}.leaflet-overlay-pane{z-index:4}.leaflet-shadow-pane{z-index:5}.leaflet-marker-pane{z-index:6}.leaflet-popup-pane{z-index:7}.leaflet-vml-shape{width:1px;height:1px}.lvml{behavior:url(#default#VML);display:inline-block;position:absolute}.leaflet-control{position:relative;z-index:7;pointer-events:auto}.leaflet-top,.leaflet-bottom{position:absolute;z-index:1000;pointer-events:none}.leaflet-top{top:0}.leaflet-right{right:0}.leaflet-bottom{bottom:0}.leaflet-left{left:0}.leaflet-control{float:left;clear:both}.leaflet-right .leaflet-control{float:right}.leaflet-top .leaflet-control{margin-top:10px}.leaflet-bottom .leaflet-control{margin-bottom:10px}.leaflet-left .leaflet-control{margin-left:10px}.leaflet-right .leaflet-control{margin-right:10px}.leaflet-fade-anim .leaflet-tile,.leaflet-fade-anim .leaflet-popup{opacity:0;-webkit-transition:opacity .2s linear;-moz-transition:opacity .2s linear;-o-transition:opacity .2s linear;transition:opacity .2s linear}.leaflet-fade-anim .leaflet-tile-loaded,.leaflet-fade-anim .leaflet-map-pane .leaflet-popup{opacity:1}.leaflet-zoom-anim .leaflet-zoom-animated{-webkit-transition:-webkit-transform .25s cubic-bezier(0, 0, .25, 1);-moz-transition:-moz-transform .25s cubic-bezier(0, 0, .25, 1);-o-transition:-o-transform .25s cubic-bezier(0, 0, .25, 1);transition:transform .25s cubic-bezier(0, 0, .25, 1)}.leaflet-zoom-anim .leaflet-tile,.leaflet-pan-anim .leaflet-tile,.leaflet-touching .leaflet-zoom-animated{-webkit-transition:none;-moz-transition:none;-o-transition:none;transition:none}.leaflet-zoom-anim .leaflet-zoom-hide{visibility:hidden}.leaflet-clickable{cursor:pointer}.leaflet-container{cursor:-webkit-grab;cursor:-moz-grab}.leaflet-popup-pane,.leaflet-control{cursor:auto}.leaflet-dragging .leaflet-container,.leaflet-dragging .leaflet-clickable{cursor:move;cursor:-webkit-grabbing;cursor:-moz-grabbing}.leaflet-container{background:#ddd;outline:0}.leaflet-container a{color:#0078a8}.leaflet-container a.leaflet-active{outline:2px solid #ffa500}.leaflet-zoom-box{border:2px dotted #38f;background:rgba(255,255,255,0.5)}.leaflet-container{font:12px/1.5 "Helvetica Neue",Arial,Helvetica,sans-serif}.leaflet-bar{box-shadow:0 1px 5px rgba(0,0,0,0.65);border-radius:4px}.leaflet-bar a,.leaflet-bar a:hover{background-color:#fff;border-bottom:1px solid #ccc;width:26px;height:26px;line-height:26px;display:block;text-align:center;text-decoration:none;color:#000}.leaflet-bar a,.leaflet-control-layers-toggle{background-position:50% 50%;background-repeat:no-repeat;display:block}.leaflet-bar a:hover{background-color:#f4f4f4}.leaflet-bar a:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.leaflet-bar a:last-child{border-bottom-left-radius:4px;border-bottom-right-radius:4px;border-bottom:none}.leaflet-bar a.leaflet-disabled{cursor:default;background-color:#f4f4f4;color:#bbb}.leaflet-touch .leaflet-bar a{width:30px;height:30px;line-height:30px}.leaflet-control-zoom-in,.leaflet-control-zoom-out{font:bold 18px 'Lucida Console',Monaco,monospace;text-indent:1px}.leaflet-control-zoom-out{font-size:20px}.leaflet-touch .leaflet-control-zoom-in{font-size:22px}.leaflet-touch .leaflet-control-zoom-out{font-size:24px}.leaflet-control-layers{box-shadow:0 1px 5px rgba(0,0,0,0.4);background:#fff;border-radius:5px}.leaflet-control-layers-toggle{background-image:url(images/layers.png);width:36px;height:36px}.leaflet-retina .leaflet-control-layers-toggle{background-image:url(images/layers-2x.png);background-size:26px 26px}.leaflet-touch .leaflet-control-layers-toggle{width:44px;height:44px}.leaflet-control-layers .leaflet-control-layers-list,.leaflet-control-layers-expanded .leaflet-control-layers-toggle{display:none}.leaflet-control-layers-expanded .leaflet-control-layers-list{display:block;position:relative}.leaflet-control-layers-expanded{padding:6px 10px 6px 6px;color:#333;background:#fff}.leaflet-control-layers-selector{margin-top:2px;position:relative;top:1px}.leaflet-control-layers label{display:block}.leaflet-control-layers-separator{height:0;border-top:1px solid #ddd;margin:5px -10px 5px -6px}.leaflet-container .leaflet-control-attribution{background:#fff;background:rgba(255,255,255,0.7);margin:0}.leaflet-control-attribution,.leaflet-control-scale-line{padding:0 5px;color:#333}.leaflet-control-attribution a{text-decoration:none}.leaflet-control-attribution a:hover{text-decoration:underline}.leaflet-container .leaflet-control-attribution,.leaflet-container .leaflet-control-scale{font-size:11px}.leaflet-left .leaflet-control-scale{margin-left:5px}.leaflet-bottom .leaflet-control-scale{margin-bottom:5px}.leaflet-control-scale-line{border:2px solid #777;border-top:none;line-height:1.1;padding:2px 5px 1px;font-size:11px;white-space:nowrap;overflow:hidden;-moz-box-sizing:content-box;box-sizing:content-box;background:#fff;background:rgba(255,255,255,0.5)}.leaflet-control-scale-line:not(:first-child){border-top:2px solid #777;border-bottom:none;margin-top:-2px}.leaflet-control-scale-line:not(:first-child):not(:last-child){border-bottom:2px solid #777}.leaflet-touch .leaflet-control-attribution,.leaflet-touch .leaflet-control-layers,.leaflet-touch .leaflet-bar{box-shadow:none}.leaflet-touch .leaflet-control-layers,.leaflet-touch .leaflet-bar{border:2px solid rgba(0,0,0,0.2);background-clip:padding-box}.leaflet-popup{position:absolute;text-align:center}.leaflet-popup-content-wrapper{padding:1px;text-align:left;border-radius:12px}.leaflet-popup-content{margin:13px 19px;line-height:1.4}.leaflet-popup-content p{margin:18px 0}.leaflet-popup-tip-container{margin:0 auto;width:40px;height:20px;position:relative;overflow:hidden}.leaflet-popup-tip{width:17px;height:17px;padding:1px;margin:-10px auto 0;-webkit-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);-o-transform:rotate(45deg);transform:rotate(45deg)}.leaflet-popup-content-wrapper,.leaflet-popup-tip{background:#fff;box-shadow:0 3px 14px rgba(0,0,0,0.4)}.leaflet-container a.leaflet-popup-close-button{position:absolute;top:0;right:0;padding:4px 4px 0 0;text-align:center;width:18px;height:14px;font:16px/14px Tahoma,Verdana,sans-serif;color:#c3c3c3;text-decoration:none;font-weight:bold;background:transparent}.leaflet-container a.leaflet-popup-close-button:hover{color:#999}.leaflet-popup-scrolled{overflow:auto;border-bottom:1px solid #ddd;border-top:1px solid #ddd}.leaflet-oldie .leaflet-popup-content-wrapper{zoom:1}.leaflet-oldie .leaflet-popup-tip{width:24px;margin:0 auto;-ms-filter:"progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";filter:progid:DXImageTransform.Microsoft.Matrix(M11=.70710678, M12=.70710678, M21=-0.70710678, M22=.70710678)}.leaflet-oldie .leaflet-popup-tip-container{margin-top:-1px}.leaflet-oldie .leaflet-control-zoom,.leaflet-oldie .leaflet-control-layers,.leaflet-oldie .leaflet-popup-content-wrapper,.leaflet-oldie .leaflet-popup-tip{border:1px solid #999}.leaflet-div-icon{background:#fff;border:1px solid #666}.leaflet-cluster-anim .leaflet-marker-icon,.leaflet-cluster-anim .leaflet-marker-shadow{-webkit-transition:-webkit-transform .3s ease-out,opacity .3s ease-in;-moz-transition:-moz-transform .3s ease-out,opacity .3s ease-in;-o-transition:-o-transform .3s ease-out,opacity .3s ease-in;transition:transform .3s ease-out,opacity .3s ease-in}.marker-cluster-small{background-color:rgba(181,226,140,0.6)}.marker-cluster-small div{background-color:rgba(110,204,57,0.6)}.marker-cluster-medium{background-color:rgba(241,211,87,0.6)}.marker-cluster-medium div{background-color:rgba(240,194,12,0.6)}.marker-cluster-large{background-color:rgba(253,156,115,0.6)}.marker-cluster-large div{background-color:rgba(241,128,23,0.6)}.leaflet-oldie .marker-cluster-small{background-color:#b5e28c}.leaflet-oldie .marker-cluster-small div{background-color:#6ecc39}.leaflet-oldie .marker-cluster-medium{background-color:#f1d357}.leaflet-oldie .marker-cluster-medium div{background-color:#f0c20c}.leaflet-oldie .marker-cluster-large{background-color:#fd9c73}.leaflet-oldie .marker-cluster-large div{background-color:#f18017}.marker-cluster{background-clip:padding-box;border-radius:20px}.marker-cluster div{width:30px;height:30px;margin-left:5px;margin-top:5px;text-align:center;border-radius:15px;font:12px "Helvetica Neue",Arial,Helvetica,sans-serif}.marker-cluster span{line-height:30px}.intro{position:relative;width:100%;height:100%;background:#f3f5f9}.intro .spinner{position:absolute;top:40%;left:50%;margin-left:-50px;margin-top:-30px;width:100px;height:60px;text-align:center;font-size:10px}.intro .spinner>div{background-color:#a6d87a;height:100%;width:10px;display:inline-block;-webkit-animation:stretchdelay 1.2s infinite ease-in-out;animation:stretchdelay 1.2s infinite ease-in-out}.intro .spinner .rect2{-webkit-animation-delay:-1.1s;animation-delay:-1.1s}.intro .spinner .rect3{-webkit-animation-delay:-1s;animation-delay:-1s}.intro .spinner .rect4{-webkit-animation-delay:-0.9s;animation-delay:-0.9s}.intro .spinner .rect5{-webkit-animation-delay:-0.8s;animation-delay:-0.8s}@-webkit-keyframes stretchdelay{0%,40%,100%{-webkit-transform:scaleY(.4)}20%{-webkit-transform:scaleY(1)}}@keyframes stretchdelay{0%,40%,100%{transform:scaleY(.4);-webkit-transform:scaleY(.4)}20%{transform:scaleY(1);-webkit-transform:scaleY(1)}}.main-header{position:fixed;top:0;bottom:0;left:49px;right:0;height:50px;z-index:11;border-bottom:1px solid rgba(224,228,232,0.9);background:rgba(255,255,255,0.9)}.main-header h1{cursor:pointer;font-size:22px;font-weight:200;line-height:50px;margin:0;text-align:center}@media (max-width:768px){.main-header{top:0;left:0;right:0;width:auto;height:50px}}.main-toolbar{position:fixed;top:0;bottom:0;left:0;z-index:10;width:50px;background:rgba(255,255,255,0.9);border-right:1px solid rgba(224,228,232,0.9);text-align:center}.main-toolbar .group-actions .btn{color:#ccc;font-size:26px;box-shadow:none;outline:none}.main-toolbar .group-actions .btn:hover,.main-toolbar .group-actions .btn:focus{color:#a6a6a6;box-shadow:none}.main-toolbar .group-actions.secondary{position:absolute;bottom:0}@media (max-width:768px){.main-toolbar{top:50px;left:0;right:0;width:auto;height:50px;border-right:none;border-bottom:1px solid rgba(224,228,232,0.9);text-align:left;overflow:hidden}.main-toolbar:before,.main-toolbar:after{content:" ";display:table}.main-toolbar:after{clear:both}.main-toolbar:before,.main-toolbar:after{content:" ";display:table}.main-toolbar:after{clear:both}.main-toolbar .group-actions{position:static;float:left}.main-toolbar .group-actions .btn{font-size:20px;line-height:34px}.main-toolbar .group-actions.secondary{position:static;float:right}}.main-container{position:fixed;top:0;bottom:0;left:0;right:0;-webkit-overflow-scrolling:touch;overflow:auto;z-index:1}.main-body{margin-top:50px;margin-left:50px;padding:15px 7.5px}@media (max-width:768px){.main-body{margin-top:100px;margin-left:0}}.main-start{padding:5px}.main-start .message-no-reports{width:100%;max-width:400px;margin:80px auto;text-align:center;font-size:18px}.main-start .message-no-reports .icon{font-size:100px;line-height:140px;color:#b3b3b1}.main-start .message-no-reports p{color:#939391}.alerts-list{list-style:none;margin:0;padding:0;margin-top:20px}.alerts-list .alert-item{padding:8px 0;border-bottom:1px solid #eee}.visualizations-list{list-style:none;padding:0;margin:0}.visualizations-list .visualization-el{padding:7.5px}.visualizations-list .visualization-el.move,.visualizations-list .visualization-el.active.move{position:fixed;z-index:100000;pointer-events:none}.visualizations-list .visualization-el.move *,.visualizations-list .visualization-el.active.move *{pointer-events:none}.visualizations-list .visualization-el.dragover.col-md-6{border-left:2px solid #a6d87a}.visualizations-list .visualization-el.dragover.col-md-12{border-top:2px solid #a6d87a}.visualizations-list .visualization-el .visualization-container{padding:0;margin:0;margin-bottom:15px;background:#fff;border-radius:2px;border:1px solid #ebeff6;box-shadow:0 1px 1px rgba(0,0,0,0.05)}.visualizations-list .visualization-el .visualization-container .visualization-header{padding:5px 15px}.visualizations-list .visualization-el .visualization-container .visualization-header:before,.visualizations-list .visualization-el .visualization-container .visualization-header:after{content:" ";display:table}.visualizations-list .visualization-el .visualization-container .visualization-header:after{clear:both}.visualizations-list .visualization-el .visualization-container .visualization-header:before,.visualizations-list .visualization-el .visualization-container .visualization-header:after{content:" ";display:table}.visualizations-list .visualization-el .visualization-container .visualization-header:after{clear:both}.visualizations-list .visualization-el .visualization-container .visualization-header h3{margin:0;padding:0;font-size:15px;line-height:34px}.visualizations-list .visualization-el .visualization-container .visualization-header .btn-link{color:#ccc}.visualizations-list .visualization-el .visualization-container .visualization-header .btn-link:hover,.visualizations-list .visualization-el .visualization-container .visualization-header .btn-link:focus{color:#a6a6a6}.visualizations-list .visualization-el .visualization-container .visualization-header .btn-link.active{color:#a6d87a;-webkit-box-shadow:none;box-shadow:none}.visualizations-list .visualization-el .visualization-container .visualization-header .visualization-actions{opacity:0;-webkit-transition:all ease .4s;transition:all ease .4s}.visualizations-list .visualization-el .visualization-container .visualization-header:hover .visualization-actions{opacity:1}.visualizations-list .visualization-el .visualization-container .visualization-body{min-height:80px}.visualizations-list .visualization-el .visualization-container .visualization-body .visualization{height:250px;padding:15px}.visualizations-list .visualization-el.size-big .visualization-container .visualization-body .visualization{height:350px}.visualization.visualization-time{width:100%}.visualization.visualization-time .graph{width:100%;height:100%}.visualization.visualization-bar{position:relative}.visualization.visualization-bar:before,.visualization.visualization-bar:after{content:" ";display:table}.visualization.visualization-bar:after{clear:both}.visualization.visualization-bar:before,.visualization.visualization-bar:after{content:" ";display:table}.visualization.visualization-bar:after{clear:both}.visualization.visualization-bar .bar{height:100%;display:block;vertical-align:baseline;padding-top:25px;position:relative;float:left}.visualization.visualization-bar .bar .bar-inner{background:#a6d87a;color:#fff;margin:0 2px;position:absolute;bottom:25px;width:100%;border-radius:2px;border-right:2px solid #fff;text-align:center;font-size:20px;display:table;overflow:hidden}.visualization.visualization-bar .bar .bar-inner .percent{display:table-cell;vertical-align:middle;text-align:center}.visualization.visualization-bar .bar .bar-label{position:absolute;bottom:0;width:100%;height:25px;text-align:center;font-size:12px;line-height:25px;text-overflow:hidden;overflow:hidden;white-space:nowrap}.visualization.visualization-bar .bar:hover .bar-inner{background:#72b636}.visualization.visualization-value{width:100%;text-align:center;display:table;vertical-align:middle}.visualization.visualization-value .content{display:table-cell;vertical-align:middle}.visualization.visualization-value .content p{margin:0}.visualization.visualization-value .content .value{font-size:30px;font-weight:bold;color:#a6d87a}.visualization.visualization-value .content .value-label{margin-top:15px;font-size:18px}.visualization.visualization-map{width:100%}.visualization.visualization-map .map{width:100%;height:100%}.visualization.visualization-table{width:100%;position:relative}.visualization.visualization-table .table-container{width:100%;height:100%;overflow:hidden;position:absolute;top:0;left:0;right:0;bottom:0}.visualization.visualization-table .table-container tr{display:block}.visualization.visualization-table .table-container th,.visualization.visualization-table .table-container td{display:block;float:left;text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.visualization.visualization-table .table-container thead{position:absolute;top:0;left:0;right:0}.visualization.visualization-table .table-container tbody{position:absolute;top:38px;left:0;right:0;overflow:auto;bottom:0}*{-webkit-overflow-scrolling:touch;-webkit-tap-highlight-color:transparent;-webkit-text-size-adjust:none;-webkit-touch-callout:none;-webkit-font-smoothing:antialiased}body .octicon{font-size:inherit}html,body{height:100%}body{background:#f3f5f9}body .modal-content{-webkit-box-shadow:none;box-shadow:none;border-radius:1px}body .btn,body .btn:focus,body .btn:hover{outline:none !important}.message-list-empty{width:100%;max-width:400px;margin:80px auto;text-align:center}.message-list-empty span{font-size:80px;line-height:120px;color:#b3b3b1}.message-list-empty p{color:#b3b3b1} \ No newline at end of file diff --git a/public/build/static/application.js b/public/build/static/application.js new file mode 100644 index 0000000..c585cb6 --- /dev/null +++ b/public/build/static/application.js @@ -0,0 +1,56748 @@ + +/** vim: et:ts=4:sw=4:sts=4 + * @license RequireJS 2.1.6 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved. + * Available via the MIT or new BSD license. + * see: http://github.com/jrburke/requirejs for details + */ +//Not using strict: uneven strict support in browsers, #392, and causes +//problems with requirejs.exec()/transpiler plugins that may not be strict. +/*jslint regexp: true, nomen: true, sloppy: true */ +/*global window, navigator, document, importScripts, setTimeout, opera */ + +var requirejs, require, define; +(function (global) { + var req, s, head, baseElement, dataMain, src, + interactiveScript, currentlyAddingScript, mainScript, subPath, + version = '2.1.6', + commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg, + cjsRequireRegExp = /[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g, + jsSuffixRegExp = /\.js$/, + currDirRegExp = /^\.\//, + op = Object.prototype, + ostring = op.toString, + hasOwn = op.hasOwnProperty, + ap = Array.prototype, + apsp = ap.splice, + isBrowser = !!(typeof window !== 'undefined' && navigator && window.document), + isWebWorker = !isBrowser && typeof importScripts !== 'undefined', + //PS3 indicates loaded and complete, but need to wait for complete + //specifically. Sequence is 'loading', 'loaded', execution, + // then 'complete'. The UA check is unfortunate, but not sure how + //to feature test w/o causing perf issues. + readyRegExp = isBrowser && navigator.platform === 'PLAYSTATION 3' ? + /^complete$/ : /^(complete|loaded)$/, + defContextName = '_', + //Oh the tragedy, detecting opera. See the usage of isOpera for reason. + isOpera = typeof opera !== 'undefined' && opera.toString() === '[object Opera]', + contexts = {}, + cfg = {}, + globalDefQueue = [], + useInteractive = false; + + function isFunction(it) { + return ostring.call(it) === '[object Function]'; + } + + function isArray(it) { + return ostring.call(it) === '[object Array]'; + } + + /** + * Helper function for iterating over an array. If the func returns + * a true value, it will break out of the loop. + */ + function each(ary, func) { + if (ary) { + var i; + for (i = 0; i < ary.length; i += 1) { + if (ary[i] && func(ary[i], i, ary)) { + break; + } + } + } + } + + /** + * Helper function for iterating over an array backwards. If the func + * returns a true value, it will break out of the loop. + */ + function eachReverse(ary, func) { + if (ary) { + var i; + for (i = ary.length - 1; i > -1; i -= 1) { + if (ary[i] && func(ary[i], i, ary)) { + break; + } + } + } + } + + function hasProp(obj, prop) { + return hasOwn.call(obj, prop); + } + + function getOwn(obj, prop) { + return hasProp(obj, prop) && obj[prop]; + } + + /** + * Cycles over properties in an object and calls a function for each + * property value. If the function returns a truthy value, then the + * iteration is stopped. + */ + function eachProp(obj, func) { + var prop; + for (prop in obj) { + if (hasProp(obj, prop)) { + if (func(obj[prop], prop)) { + break; + } + } + } + } + + /** + * Simple function to mix in properties from source into target, + * but only if target does not already have a property of the same name. + */ + function mixin(target, source, force, deepStringMixin) { + if (source) { + eachProp(source, function (value, prop) { + if (force || !hasProp(target, prop)) { + if (deepStringMixin && typeof value !== 'string') { + if (!target[prop]) { + target[prop] = {}; + } + mixin(target[prop], value, force, deepStringMixin); + } else { + target[prop] = value; + } + } + }); + } + return target; + } + + //Similar to Function.prototype.bind, but the 'this' object is specified + //first, since it is easier to read/figure out what 'this' will be. + function bind(obj, fn) { + return function () { + return fn.apply(obj, arguments); + }; + } + + function scripts() { + return document.getElementsByTagName('script'); + } + + function defaultOnError(err) { + throw err; + } + + //Allow getting a global that expressed in + //dot notation, like 'a.b.c'. + function getGlobal(value) { + if (!value) { + return value; + } + var g = global; + each(value.split('.'), function (part) { + g = g[part]; + }); + return g; + } + + /** + * Constructs an error with a pointer to an URL with more information. + * @param {String} id the error ID that maps to an ID on a web page. + * @param {String} message human readable error. + * @param {Error} [err] the original error, if there is one. + * + * @returns {Error} + */ + function makeError(id, msg, err, requireModules) { + var e = new Error(msg + '\nhttp://requirejs.org/docs/errors.html#' + id); + e.requireType = id; + e.requireModules = requireModules; + if (err) { + e.originalError = err; + } + return e; + } + + if (typeof define !== 'undefined') { + //If a define is already in play via another AMD loader, + //do not overwrite. + return; + } + + if (typeof requirejs !== 'undefined') { + if (isFunction(requirejs)) { + //Do not overwrite and existing requirejs instance. + return; + } + cfg = requirejs; + requirejs = undefined; + } + + //Allow for a require config object + if (typeof require !== 'undefined' && !isFunction(require)) { + //assume it is a config object. + cfg = require; + require = undefined; + } + + function newContext(contextName) { + var inCheckLoaded, Module, context, handlers, + checkLoadedTimeoutId, + config = { + //Defaults. Do not set a default for map + //config to speed up normalize(), which + //will run faster if there is no default. + waitSeconds: 7, + baseUrl: './', + paths: {}, + pkgs: {}, + shim: {}, + config: {} + }, + registry = {}, + //registry of just enabled modules, to speed + //cycle breaking code when lots of modules + //are registered, but not activated. + enabledRegistry = {}, + undefEvents = {}, + defQueue = [], + defined = {}, + urlFetched = {}, + requireCounter = 1, + unnormalizedCounter = 1; + + /** + * Trims the . and .. from an array of path segments. + * It will keep a leading path segment if a .. will become + * the first path segment, to help with module name lookups, + * which act like paths, but can be remapped. But the end result, + * all paths that use this function should look normalized. + * NOTE: this method MODIFIES the input array. + * @param {Array} ary the array of path segments. + */ + function trimDots(ary) { + var i, part; + for (i = 0; ary[i]; i += 1) { + part = ary[i]; + if (part === '.') { + ary.splice(i, 1); + i -= 1; + } else if (part === '..') { + if (i === 1 && (ary[2] === '..' || ary[0] === '..')) { + //End of the line. Keep at least one non-dot + //path segment at the front so it can be mapped + //correctly to disk. Otherwise, there is likely + //no path mapping for a path starting with '..'. + //This can still fail, but catches the most reasonable + //uses of .. + break; + } else if (i > 0) { + ary.splice(i - 1, 2); + i -= 2; + } + } + } + } + + /** + * Given a relative module name, like ./something, normalize it to + * a real name that can be mapped to a path. + * @param {String} name the relative name + * @param {String} baseName a real name that the name arg is relative + * to. + * @param {Boolean} applyMap apply the map config to the value. Should + * only be done if this normalization is for a dependency ID. + * @returns {String} normalized name + */ + function normalize(name, baseName, applyMap) { + var pkgName, pkgConfig, mapValue, nameParts, i, j, nameSegment, + foundMap, foundI, foundStarMap, starI, + baseParts = baseName && baseName.split('/'), + normalizedBaseParts = baseParts, + map = config.map, + starMap = map && map['*']; + + //Adjust any relative paths. + if (name && name.charAt(0) === '.') { + //If have a base name, try to normalize against it, + //otherwise, assume it is a top-level require that will + //be relative to baseUrl in the end. + if (baseName) { + if (getOwn(config.pkgs, baseName)) { + //If the baseName is a package name, then just treat it as one + //name to concat the name with. + normalizedBaseParts = baseParts = [baseName]; + } else { + //Convert baseName to array, and lop off the last part, + //so that . matches that 'directory' and not name of the baseName's + //module. For instance, baseName of 'one/two/three', maps to + //'one/two/three.js', but we want the directory, 'one/two' for + //this normalization. + normalizedBaseParts = baseParts.slice(0, baseParts.length - 1); + } + + name = normalizedBaseParts.concat(name.split('/')); + trimDots(name); + + //Some use of packages may use a . path to reference the + //'main' module name, so normalize for that. + pkgConfig = getOwn(config.pkgs, (pkgName = name[0])); + name = name.join('/'); + if (pkgConfig && name === pkgName + '/' + pkgConfig.main) { + name = pkgName; + } + } else if (name.indexOf('./') === 0) { + // No baseName, so this is ID is resolved relative + // to baseUrl, pull off the leading dot. + name = name.substring(2); + } + } + + //Apply map config if available. + if (applyMap && map && (baseParts || starMap)) { + nameParts = name.split('/'); + + for (i = nameParts.length; i > 0; i -= 1) { + nameSegment = nameParts.slice(0, i).join('/'); + + if (baseParts) { + //Find the longest baseName segment match in the config. + //So, do joins on the biggest to smallest lengths of baseParts. + for (j = baseParts.length; j > 0; j -= 1) { + mapValue = getOwn(map, baseParts.slice(0, j).join('/')); + + //baseName segment has config, find if it has one for + //this name. + if (mapValue) { + mapValue = getOwn(mapValue, nameSegment); + if (mapValue) { + //Match, update name to the new value. + foundMap = mapValue; + foundI = i; + break; + } + } + } + } + + if (foundMap) { + break; + } + + //Check for a star map match, but just hold on to it, + //if there is a shorter segment match later in a matching + //config, then favor over this star map. + if (!foundStarMap && starMap && getOwn(starMap, nameSegment)) { + foundStarMap = getOwn(starMap, nameSegment); + starI = i; + } + } + + if (!foundMap && foundStarMap) { + foundMap = foundStarMap; + foundI = starI; + } + + if (foundMap) { + nameParts.splice(0, foundI, foundMap); + name = nameParts.join('/'); + } + } + + return name; + } + + function removeScript(name) { + if (isBrowser) { + each(scripts(), function (scriptNode) { + if (scriptNode.getAttribute('data-requiremodule') === name && + scriptNode.getAttribute('data-requirecontext') === context.contextName) { + scriptNode.parentNode.removeChild(scriptNode); + return true; + } + }); + } + } + + function hasPathFallback(id) { + var pathConfig = getOwn(config.paths, id); + if (pathConfig && isArray(pathConfig) && pathConfig.length > 1) { + removeScript(id); + //Pop off the first array value, since it failed, and + //retry + pathConfig.shift(); + context.require.undef(id); + context.require([id]); + return true; + } + } + + //Turns a plugin!resource to [plugin, resource] + //with the plugin being undefined if the name + //did not have a plugin prefix. + function splitPrefix(name) { + var prefix, + index = name ? name.indexOf('!') : -1; + if (index > -1) { + prefix = name.substring(0, index); + name = name.substring(index + 1, name.length); + } + return [prefix, name]; + } + + /** + * Creates a module mapping that includes plugin prefix, module + * name, and path. If parentModuleMap is provided it will + * also normalize the name via require.normalize() + * + * @param {String} name the module name + * @param {String} [parentModuleMap] parent module map + * for the module name, used to resolve relative names. + * @param {Boolean} isNormalized: is the ID already normalized. + * This is true if this call is done for a define() module ID. + * @param {Boolean} applyMap: apply the map config to the ID. + * Should only be true if this map is for a dependency. + * + * @returns {Object} + */ + function makeModuleMap(name, parentModuleMap, isNormalized, applyMap) { + var url, pluginModule, suffix, nameParts, + prefix = null, + parentName = parentModuleMap ? parentModuleMap.name : null, + originalName = name, + isDefine = true, + normalizedName = ''; + + //If no name, then it means it is a require call, generate an + //internal name. + if (!name) { + isDefine = false; + name = '_@r' + (requireCounter += 1); + } + + nameParts = splitPrefix(name); + prefix = nameParts[0]; + name = nameParts[1]; + + if (prefix) { + prefix = normalize(prefix, parentName, applyMap); + pluginModule = getOwn(defined, prefix); + } + + //Account for relative paths if there is a base name. + if (name) { + if (prefix) { + if (pluginModule && pluginModule.normalize) { + //Plugin is loaded, use its normalize method. + normalizedName = pluginModule.normalize(name, function (name) { + return normalize(name, parentName, applyMap); + }); + } else { + normalizedName = normalize(name, parentName, applyMap); + } + } else { + //A regular module. + normalizedName = normalize(name, parentName, applyMap); + + //Normalized name may be a plugin ID due to map config + //application in normalize. The map config values must + //already be normalized, so do not need to redo that part. + nameParts = splitPrefix(normalizedName); + prefix = nameParts[0]; + normalizedName = nameParts[1]; + isNormalized = true; + + url = context.nameToUrl(normalizedName); + } + } + + //If the id is a plugin id that cannot be determined if it needs + //normalization, stamp it with a unique ID so two matching relative + //ids that may conflict can be separate. + suffix = prefix && !pluginModule && !isNormalized ? + '_unnormalized' + (unnormalizedCounter += 1) : + ''; + + return { + prefix: prefix, + name: normalizedName, + parentMap: parentModuleMap, + unnormalized: !!suffix, + url: url, + originalName: originalName, + isDefine: isDefine, + id: (prefix ? + prefix + '!' + normalizedName : + normalizedName) + suffix + }; + } + + function getModule(depMap) { + var id = depMap.id, + mod = getOwn(registry, id); + + if (!mod) { + mod = registry[id] = new context.Module(depMap); + } + + return mod; + } + + function on(depMap, name, fn) { + var id = depMap.id, + mod = getOwn(registry, id); + + if (hasProp(defined, id) && + (!mod || mod.defineEmitComplete)) { + if (name === 'defined') { + fn(defined[id]); + } + } else { + mod = getModule(depMap); + if (mod.error && name === 'error') { + fn(mod.error); + } else { + mod.on(name, fn); + } + } + } + + function onError(err, errback) { + var ids = err.requireModules, + notified = false; + + if (errback) { + errback(err); + } else { + each(ids, function (id) { + var mod = getOwn(registry, id); + if (mod) { + //Set error on module, so it skips timeout checks. + mod.error = err; + if (mod.events.error) { + notified = true; + mod.emit('error', err); + } + } + }); + + if (!notified) { + req.onError(err); + } + } + } + + /** + * Internal method to transfer globalQueue items to this context's + * defQueue. + */ + function takeGlobalQueue() { + //Push all the globalDefQueue items into the context's defQueue + if (globalDefQueue.length) { + //Array splice in the values since the context code has a + //local var ref to defQueue, so cannot just reassign the one + //on context. + apsp.apply(defQueue, + [defQueue.length - 1, 0].concat(globalDefQueue)); + globalDefQueue = []; + } + } + + handlers = { + 'require': function (mod) { + if (mod.require) { + return mod.require; + } else { + return (mod.require = context.makeRequire(mod.map)); + } + }, + 'exports': function (mod) { + mod.usingExports = true; + if (mod.map.isDefine) { + if (mod.exports) { + return mod.exports; + } else { + return (mod.exports = defined[mod.map.id] = {}); + } + } + }, + 'module': function (mod) { + if (mod.module) { + return mod.module; + } else { + return (mod.module = { + id: mod.map.id, + uri: mod.map.url, + config: function () { + var c, + pkg = getOwn(config.pkgs, mod.map.id); + // For packages, only support config targeted + // at the main module. + c = pkg ? getOwn(config.config, mod.map.id + '/' + pkg.main) : + getOwn(config.config, mod.map.id); + return c || {}; + }, + exports: defined[mod.map.id] + }); + } + } + }; + + function cleanRegistry(id) { + //Clean up machinery used for waiting modules. + delete registry[id]; + delete enabledRegistry[id]; + } + + function breakCycle(mod, traced, processed) { + var id = mod.map.id; + + if (mod.error) { + mod.emit('error', mod.error); + } else { + traced[id] = true; + each(mod.depMaps, function (depMap, i) { + var depId = depMap.id, + dep = getOwn(registry, depId); + + //Only force things that have not completed + //being defined, so still in the registry, + //and only if it has not been matched up + //in the module already. + if (dep && !mod.depMatched[i] && !processed[depId]) { + if (getOwn(traced, depId)) { + mod.defineDep(i, defined[depId]); + mod.check(); //pass false? + } else { + breakCycle(dep, traced, processed); + } + } + }); + processed[id] = true; + } + } + + function checkLoaded() { + var map, modId, err, usingPathFallback, + waitInterval = config.waitSeconds * 1000, + //It is possible to disable the wait interval by using waitSeconds of 0. + expired = waitInterval && (context.startTime + waitInterval) < new Date().getTime(), + noLoads = [], + reqCalls = [], + stillLoading = false, + needCycleCheck = true; + + //Do not bother if this call was a result of a cycle break. + if (inCheckLoaded) { + return; + } + + inCheckLoaded = true; + + //Figure out the state of all the modules. + eachProp(enabledRegistry, function (mod) { + map = mod.map; + modId = map.id; + + //Skip things that are not enabled or in error state. + if (!mod.enabled) { + return; + } + + if (!map.isDefine) { + reqCalls.push(mod); + } + + if (!mod.error) { + //If the module should be executed, and it has not + //been inited and time is up, remember it. + if (!mod.inited && expired) { + if (hasPathFallback(modId)) { + usingPathFallback = true; + stillLoading = true; + } else { + noLoads.push(modId); + removeScript(modId); + } + } else if (!mod.inited && mod.fetched && map.isDefine) { + stillLoading = true; + if (!map.prefix) { + //No reason to keep looking for unfinished + //loading. If the only stillLoading is a + //plugin resource though, keep going, + //because it may be that a plugin resource + //is waiting on a non-plugin cycle. + return (needCycleCheck = false); + } + } + } + }); + + if (expired && noLoads.length) { + //If wait time expired, throw error of unloaded modules. + err = makeError('timeout', 'Load timeout for modules: ' + noLoads, null, noLoads); + err.contextName = context.contextName; + return onError(err); + } + + //Not expired, check for a cycle. + if (needCycleCheck) { + each(reqCalls, function (mod) { + breakCycle(mod, {}, {}); + }); + } + + //If still waiting on loads, and the waiting load is something + //other than a plugin resource, or there are still outstanding + //scripts, then just try back later. + if ((!expired || usingPathFallback) && stillLoading) { + //Something is still waiting to load. Wait for it, but only + //if a timeout is not already in effect. + if ((isBrowser || isWebWorker) && !checkLoadedTimeoutId) { + checkLoadedTimeoutId = setTimeout(function () { + checkLoadedTimeoutId = 0; + checkLoaded(); + }, 50); + } + } + + inCheckLoaded = false; + } + + Module = function (map) { + this.events = getOwn(undefEvents, map.id) || {}; + this.map = map; + this.shim = getOwn(config.shim, map.id); + this.depExports = []; + this.depMaps = []; + this.depMatched = []; + this.pluginMaps = {}; + this.depCount = 0; + + /* this.exports this.factory + this.depMaps = [], + this.enabled, this.fetched + */ + }; + + Module.prototype = { + init: function (depMaps, factory, errback, options) { + options = options || {}; + + //Do not do more inits if already done. Can happen if there + //are multiple define calls for the same module. That is not + //a normal, common case, but it is also not unexpected. + if (this.inited) { + return; + } + + this.factory = factory; + + if (errback) { + //Register for errors on this module. + this.on('error', errback); + } else if (this.events.error) { + //If no errback already, but there are error listeners + //on this module, set up an errback to pass to the deps. + errback = bind(this, function (err) { + this.emit('error', err); + }); + } + + //Do a copy of the dependency array, so that + //source inputs are not modified. For example + //"shim" deps are passed in here directly, and + //doing a direct modification of the depMaps array + //would affect that config. + this.depMaps = depMaps && depMaps.slice(0); + + this.errback = errback; + + //Indicate this module has be initialized + this.inited = true; + + this.ignore = options.ignore; + + //Could have option to init this module in enabled mode, + //or could have been previously marked as enabled. However, + //the dependencies are not known until init is called. So + //if enabled previously, now trigger dependencies as enabled. + if (options.enabled || this.enabled) { + //Enable this module and dependencies. + //Will call this.check() + this.enable(); + } else { + this.check(); + } + }, + + defineDep: function (i, depExports) { + //Because of cycles, defined callback for a given + //export can be called more than once. + if (!this.depMatched[i]) { + this.depMatched[i] = true; + this.depCount -= 1; + this.depExports[i] = depExports; + } + }, + + fetch: function () { + if (this.fetched) { + return; + } + this.fetched = true; + + context.startTime = (new Date()).getTime(); + + var map = this.map; + + //If the manager is for a plugin managed resource, + //ask the plugin to load it now. + if (this.shim) { + context.makeRequire(this.map, { + enableBuildCallback: true + })(this.shim.deps || [], bind(this, function () { + return map.prefix ? this.callPlugin() : this.load(); + })); + } else { + //Regular dependency. + return map.prefix ? this.callPlugin() : this.load(); + } + }, + + load: function () { + var url = this.map.url; + + //Regular dependency. + if (!urlFetched[url]) { + urlFetched[url] = true; + context.load(this.map.id, url); + } + }, + + /** + * Checks if the module is ready to define itself, and if so, + * define it. + */ + check: function () { + if (!this.enabled || this.enabling) { + return; + } + + var err, cjsModule, + id = this.map.id, + depExports = this.depExports, + exports = this.exports, + factory = this.factory; + + if (!this.inited) { + this.fetch(); + } else if (this.error) { + this.emit('error', this.error); + } else if (!this.defining) { + //The factory could trigger another require call + //that would result in checking this module to + //define itself again. If already in the process + //of doing that, skip this work. + this.defining = true; + + if (this.depCount < 1 && !this.defined) { + if (isFunction(factory)) { + //If there is an error listener, favor passing + //to that instead of throwing an error. However, + //only do it for define()'d modules. require + //errbacks should not be called for failures in + //their callbacks (#699). However if a global + //onError is set, use that. + if ((this.events.error && this.map.isDefine) || + req.onError !== defaultOnError) { + try { + exports = context.execCb(id, factory, depExports, exports); + } catch (e) { + err = e; + } + } else { + exports = context.execCb(id, factory, depExports, exports); + } + + if (this.map.isDefine) { + //If setting exports via 'module' is in play, + //favor that over return value and exports. After that, + //favor a non-undefined return value over exports use. + cjsModule = this.module; + if (cjsModule && + cjsModule.exports !== undefined && + //Make sure it is not already the exports value + cjsModule.exports !== this.exports) { + exports = cjsModule.exports; + } else if (exports === undefined && this.usingExports) { + //exports already set the defined value. + exports = this.exports; + } + } + + if (err) { + err.requireMap = this.map; + err.requireModules = this.map.isDefine ? [this.map.id] : null; + err.requireType = this.map.isDefine ? 'define' : 'require'; + return onError((this.error = err)); + } + + } else { + //Just a literal value + exports = factory; + } + + this.exports = exports; + + if (this.map.isDefine && !this.ignore) { + defined[id] = exports; + + if (req.onResourceLoad) { + req.onResourceLoad(context, this.map, this.depMaps); + } + } + + //Clean up + cleanRegistry(id); + + this.defined = true; + } + + //Finished the define stage. Allow calling check again + //to allow define notifications below in the case of a + //cycle. + this.defining = false; + + if (this.defined && !this.defineEmitted) { + this.defineEmitted = true; + this.emit('defined', this.exports); + this.defineEmitComplete = true; + } + + } + }, + + callPlugin: function () { + var map = this.map, + id = map.id, + //Map already normalized the prefix. + pluginMap = makeModuleMap(map.prefix); + + //Mark this as a dependency for this plugin, so it + //can be traced for cycles. + this.depMaps.push(pluginMap); + + on(pluginMap, 'defined', bind(this, function (plugin) { + var load, normalizedMap, normalizedMod, + name = this.map.name, + parentName = this.map.parentMap ? this.map.parentMap.name : null, + localRequire = context.makeRequire(map.parentMap, { + enableBuildCallback: true + }); + + //If current map is not normalized, wait for that + //normalized name to load instead of continuing. + if (this.map.unnormalized) { + //Normalize the ID if the plugin allows it. + if (plugin.normalize) { + name = plugin.normalize(name, function (name) { + return normalize(name, parentName, true); + }) || ''; + } + + //prefix and name should already be normalized, no need + //for applying map config again either. + normalizedMap = makeModuleMap(map.prefix + '!' + name, + this.map.parentMap); + on(normalizedMap, + 'defined', bind(this, function (value) { + this.init([], function () { return value; }, null, { + enabled: true, + ignore: true + }); + })); + + normalizedMod = getOwn(registry, normalizedMap.id); + if (normalizedMod) { + //Mark this as a dependency for this plugin, so it + //can be traced for cycles. + this.depMaps.push(normalizedMap); + + if (this.events.error) { + normalizedMod.on('error', bind(this, function (err) { + this.emit('error', err); + })); + } + normalizedMod.enable(); + } + + return; + } + + load = bind(this, function (value) { + this.init([], function () { return value; }, null, { + enabled: true + }); + }); + + load.error = bind(this, function (err) { + this.inited = true; + this.error = err; + err.requireModules = [id]; + + //Remove temp unnormalized modules for this module, + //since they will never be resolved otherwise now. + eachProp(registry, function (mod) { + if (mod.map.id.indexOf(id + '_unnormalized') === 0) { + cleanRegistry(mod.map.id); + } + }); + + onError(err); + }); + + //Allow plugins to load other code without having to know the + //context or how to 'complete' the load. + load.fromText = bind(this, function (text, textAlt) { + /*jslint evil: true */ + var moduleName = map.name, + moduleMap = makeModuleMap(moduleName), + hasInteractive = useInteractive; + + //As of 2.1.0, support just passing the text, to reinforce + //fromText only being called once per resource. Still + //support old style of passing moduleName but discard + //that moduleName in favor of the internal ref. + if (textAlt) { + text = textAlt; + } + + //Turn off interactive script matching for IE for any define + //calls in the text, then turn it back on at the end. + if (hasInteractive) { + useInteractive = false; + } + + //Prime the system by creating a module instance for + //it. + getModule(moduleMap); + + //Transfer any config to this other module. + if (hasProp(config.config, id)) { + config.config[moduleName] = config.config[id]; + } + + try { + req.exec(text); + } catch (e) { + return onError(makeError('fromtexteval', + 'fromText eval for ' + id + + ' failed: ' + e, + e, + [id])); + } + + if (hasInteractive) { + useInteractive = true; + } + + //Mark this as a dependency for the plugin + //resource + this.depMaps.push(moduleMap); + + //Support anonymous modules. + context.completeLoad(moduleName); + + //Bind the value of that module to the value for this + //resource ID. + localRequire([moduleName], load); + }); + + //Use parentName here since the plugin's name is not reliable, + //could be some weird string with no path that actually wants to + //reference the parentName's path. + plugin.load(map.name, localRequire, load, config); + })); + + context.enable(pluginMap, this); + this.pluginMaps[pluginMap.id] = pluginMap; + }, + + enable: function () { + enabledRegistry[this.map.id] = this; + this.enabled = true; + + //Set flag mentioning that the module is enabling, + //so that immediate calls to the defined callbacks + //for dependencies do not trigger inadvertent load + //with the depCount still being zero. + this.enabling = true; + + //Enable each dependency + each(this.depMaps, bind(this, function (depMap, i) { + var id, mod, handler; + + if (typeof depMap === 'string') { + //Dependency needs to be converted to a depMap + //and wired up to this module. + depMap = makeModuleMap(depMap, + (this.map.isDefine ? this.map : this.map.parentMap), + false, + !this.skipMap); + this.depMaps[i] = depMap; + + handler = getOwn(handlers, depMap.id); + + if (handler) { + this.depExports[i] = handler(this); + return; + } + + this.depCount += 1; + + on(depMap, 'defined', bind(this, function (depExports) { + this.defineDep(i, depExports); + this.check(); + })); + + if (this.errback) { + on(depMap, 'error', bind(this, this.errback)); + } + } + + id = depMap.id; + mod = registry[id]; + + //Skip special modules like 'require', 'exports', 'module' + //Also, don't call enable if it is already enabled, + //important in circular dependency cases. + if (!hasProp(handlers, id) && mod && !mod.enabled) { + context.enable(depMap, this); + } + })); + + //Enable each plugin that is used in + //a dependency + eachProp(this.pluginMaps, bind(this, function (pluginMap) { + var mod = getOwn(registry, pluginMap.id); + if (mod && !mod.enabled) { + context.enable(pluginMap, this); + } + })); + + this.enabling = false; + + this.check(); + }, + + on: function (name, cb) { + var cbs = this.events[name]; + if (!cbs) { + cbs = this.events[name] = []; + } + cbs.push(cb); + }, + + emit: function (name, evt) { + each(this.events[name], function (cb) { + cb(evt); + }); + if (name === 'error') { + //Now that the error handler was triggered, remove + //the listeners, since this broken Module instance + //can stay around for a while in the registry. + delete this.events[name]; + } + } + }; + + function callGetModule(args) { + //Skip modules already defined. + if (!hasProp(defined, args[0])) { + getModule(makeModuleMap(args[0], null, true)).init(args[1], args[2]); + } + } + + function removeListener(node, func, name, ieName) { + //Favor detachEvent because of IE9 + //issue, see attachEvent/addEventListener comment elsewhere + //in this file. + if (node.detachEvent && !isOpera) { + //Probably IE. If not it will throw an error, which will be + //useful to know. + if (ieName) { + node.detachEvent(ieName, func); + } + } else { + node.removeEventListener(name, func, false); + } + } + + /** + * Given an event from a script node, get the requirejs info from it, + * and then removes the event listeners on the node. + * @param {Event} evt + * @returns {Object} + */ + function getScriptData(evt) { + //Using currentTarget instead of target for Firefox 2.0's sake. Not + //all old browsers will be supported, but this one was easy enough + //to support and still makes sense. + var node = evt.currentTarget || evt.srcElement; + + //Remove the listeners once here. + removeListener(node, context.onScriptLoad, 'load', 'onreadystatechange'); + removeListener(node, context.onScriptError, 'error'); + + return { + node: node, + id: node && node.getAttribute('data-requiremodule') + }; + } + + function intakeDefines() { + var args; + + //Any defined modules in the global queue, intake them now. + takeGlobalQueue(); + + //Make sure any remaining defQueue items get properly processed. + while (defQueue.length) { + args = defQueue.shift(); + if (args[0] === null) { + return onError(makeError('mismatch', 'Mismatched anonymous define() module: ' + args[args.length - 1])); + } else { + //args are id, deps, factory. Should be normalized by the + //define() function. + callGetModule(args); + } + } + } + + context = { + config: config, + contextName: contextName, + registry: registry, + defined: defined, + urlFetched: urlFetched, + defQueue: defQueue, + Module: Module, + makeModuleMap: makeModuleMap, + nextTick: req.nextTick, + onError: onError, + + /** + * Set a configuration for the context. + * @param {Object} cfg config object to integrate. + */ + configure: function (cfg) { + //Make sure the baseUrl ends in a slash. + if (cfg.baseUrl) { + if (cfg.baseUrl.charAt(cfg.baseUrl.length - 1) !== '/') { + cfg.baseUrl += '/'; + } + } + + //Save off the paths and packages since they require special processing, + //they are additive. + var pkgs = config.pkgs, + shim = config.shim, + objs = { + paths: true, + config: true, + map: true + }; + + eachProp(cfg, function (value, prop) { + if (objs[prop]) { + if (prop === 'map') { + if (!config.map) { + config.map = {}; + } + mixin(config[prop], value, true, true); + } else { + mixin(config[prop], value, true); + } + } else { + config[prop] = value; + } + }); + + //Merge shim + if (cfg.shim) { + eachProp(cfg.shim, function (value, id) { + //Normalize the structure + if (isArray(value)) { + value = { + deps: value + }; + } + if ((value.exports || value.init) && !value.exportsFn) { + value.exportsFn = context.makeShimExports(value); + } + shim[id] = value; + }); + config.shim = shim; + } + + //Adjust packages if necessary. + if (cfg.packages) { + each(cfg.packages, function (pkgObj) { + var location; + + pkgObj = typeof pkgObj === 'string' ? { name: pkgObj } : pkgObj; + location = pkgObj.location; + + //Create a brand new object on pkgs, since currentPackages can + //be passed in again, and config.pkgs is the internal transformed + //state for all package configs. + pkgs[pkgObj.name] = { + name: pkgObj.name, + location: location || pkgObj.name, + //Remove leading dot in main, so main paths are normalized, + //and remove any trailing .js, since different package + //envs have different conventions: some use a module name, + //some use a file name. + main: (pkgObj.main || 'main') + .replace(currDirRegExp, '') + .replace(jsSuffixRegExp, '') + }; + }); + + //Done with modifications, assing packages back to context config + config.pkgs = pkgs; + } + + //If there are any "waiting to execute" modules in the registry, + //update the maps for them, since their info, like URLs to load, + //may have changed. + eachProp(registry, function (mod, id) { + //If module already has init called, since it is too + //late to modify them, and ignore unnormalized ones + //since they are transient. + if (!mod.inited && !mod.map.unnormalized) { + mod.map = makeModuleMap(id); + } + }); + + //If a deps array or a config callback is specified, then call + //require with those args. This is useful when require is defined as a + //config object before require.js is loaded. + if (cfg.deps || cfg.callback) { + context.require(cfg.deps || [], cfg.callback); + } + }, + + makeShimExports: function (value) { + function fn() { + var ret; + if (value.init) { + ret = value.init.apply(global, arguments); + } + return ret || (value.exports && getGlobal(value.exports)); + } + return fn; + }, + + makeRequire: function (relMap, options) { + options = options || {}; + + function localRequire(deps, callback, errback) { + var id, map, requireMod; + + if (options.enableBuildCallback && callback && isFunction(callback)) { + callback.__requireJsBuild = true; + } + + if (typeof deps === 'string') { + if (isFunction(callback)) { + //Invalid call + return onError(makeError('requireargs', 'Invalid require call'), errback); + } + + //If require|exports|module are requested, get the + //value for them from the special handlers. Caveat: + //this only works while module is being defined. + if (relMap && hasProp(handlers, deps)) { + return handlers[deps](registry[relMap.id]); + } + + //Synchronous access to one module. If require.get is + //available (as in the Node adapter), prefer that. + if (req.get) { + return req.get(context, deps, relMap, localRequire); + } + + //Normalize module name, if it contains . or .. + map = makeModuleMap(deps, relMap, false, true); + id = map.id; + + if (!hasProp(defined, id)) { + return onError(makeError('notloaded', 'Module name "' + + id + + '" has not been loaded yet for context: ' + + contextName + + (relMap ? '' : '. Use require([])'))); + } + return defined[id]; + } + + //Grab defines waiting in the global queue. + intakeDefines(); + + //Mark all the dependencies as needing to be loaded. + context.nextTick(function () { + //Some defines could have been added since the + //require call, collect them. + intakeDefines(); + + requireMod = getModule(makeModuleMap(null, relMap)); + + //Store if map config should be applied to this require + //call for dependencies. + requireMod.skipMap = options.skipMap; + + requireMod.init(deps, callback, errback, { + enabled: true + }); + + checkLoaded(); + }); + + return localRequire; + } + + mixin(localRequire, { + isBrowser: isBrowser, + + /** + * Converts a module name + .extension into an URL path. + * *Requires* the use of a module name. It does not support using + * plain URLs like nameToUrl. + */ + toUrl: function (moduleNamePlusExt) { + var ext, + index = moduleNamePlusExt.lastIndexOf('.'), + segment = moduleNamePlusExt.split('/')[0], + isRelative = segment === '.' || segment === '..'; + + //Have a file extension alias, and it is not the + //dots from a relative path. + if (index !== -1 && (!isRelative || index > 1)) { + ext = moduleNamePlusExt.substring(index, moduleNamePlusExt.length); + moduleNamePlusExt = moduleNamePlusExt.substring(0, index); + } + + return context.nameToUrl(normalize(moduleNamePlusExt, + relMap && relMap.id, true), ext, true); + }, + + defined: function (id) { + return hasProp(defined, makeModuleMap(id, relMap, false, true).id); + }, + + specified: function (id) { + id = makeModuleMap(id, relMap, false, true).id; + return hasProp(defined, id) || hasProp(registry, id); + } + }); + + //Only allow undef on top level require calls + if (!relMap) { + localRequire.undef = function (id) { + //Bind any waiting define() calls to this context, + //fix for #408 + takeGlobalQueue(); + + var map = makeModuleMap(id, relMap, true), + mod = getOwn(registry, id); + + delete defined[id]; + delete urlFetched[map.url]; + delete undefEvents[id]; + + if (mod) { + //Hold on to listeners in case the + //module will be attempted to be reloaded + //using a different config. + if (mod.events.defined) { + undefEvents[id] = mod.events; + } + + cleanRegistry(id); + } + }; + } + + return localRequire; + }, + + /** + * Called to enable a module if it is still in the registry + * awaiting enablement. A second arg, parent, the parent module, + * is passed in for context, when this method is overriden by + * the optimizer. Not shown here to keep code compact. + */ + enable: function (depMap) { + var mod = getOwn(registry, depMap.id); + if (mod) { + getModule(depMap).enable(); + } + }, + + /** + * Internal method used by environment adapters to complete a load event. + * A load event could be a script load or just a load pass from a synchronous + * load call. + * @param {String} moduleName the name of the module to potentially complete. + */ + completeLoad: function (moduleName) { + var found, args, mod, + shim = getOwn(config.shim, moduleName) || {}, + shExports = shim.exports; + + takeGlobalQueue(); + + while (defQueue.length) { + args = defQueue.shift(); + if (args[0] === null) { + args[0] = moduleName; + //If already found an anonymous module and bound it + //to this name, then this is some other anon module + //waiting for its completeLoad to fire. + if (found) { + break; + } + found = true; + } else if (args[0] === moduleName) { + //Found matching define call for this script! + found = true; + } + + callGetModule(args); + } + + //Do this after the cycle of callGetModule in case the result + //of those calls/init calls changes the registry. + mod = getOwn(registry, moduleName); + + if (!found && !hasProp(defined, moduleName) && mod && !mod.inited) { + if (config.enforceDefine && (!shExports || !getGlobal(shExports))) { + if (hasPathFallback(moduleName)) { + return; + } else { + return onError(makeError('nodefine', + 'No define call for ' + moduleName, + null, + [moduleName])); + } + } else { + //A script that does not call define(), so just simulate + //the call for it. + callGetModule([moduleName, (shim.deps || []), shim.exportsFn]); + } + } + + checkLoaded(); + }, + + /** + * Converts a module name to a file path. Supports cases where + * moduleName may actually be just an URL. + * Note that it **does not** call normalize on the moduleName, + * it is assumed to have already been normalized. This is an + * internal API, not a public one. Use toUrl for the public API. + */ + nameToUrl: function (moduleName, ext, skipExt) { + var paths, pkgs, pkg, pkgPath, syms, i, parentModule, url, + parentPath; + + //If a colon is in the URL, it indicates a protocol is used and it is just + //an URL to a file, or if it starts with a slash, contains a query arg (i.e. ?) + //or ends with .js, then assume the user meant to use an url and not a module id. + //The slash is important for protocol-less URLs as well as full paths. + if (req.jsExtRegExp.test(moduleName)) { + //Just a plain path, not module name lookup, so just return it. + //Add extension if it is included. This is a bit wonky, only non-.js things pass + //an extension, this method probably needs to be reworked. + url = moduleName + (ext || ''); + } else { + //A module that needs to be converted to a path. + paths = config.paths; + pkgs = config.pkgs; + + syms = moduleName.split('/'); + //For each module name segment, see if there is a path + //registered for it. Start with most specific name + //and work up from it. + for (i = syms.length; i > 0; i -= 1) { + parentModule = syms.slice(0, i).join('/'); + pkg = getOwn(pkgs, parentModule); + parentPath = getOwn(paths, parentModule); + if (parentPath) { + //If an array, it means there are a few choices, + //Choose the one that is desired + if (isArray(parentPath)) { + parentPath = parentPath[0]; + } + syms.splice(0, i, parentPath); + break; + } else if (pkg) { + //If module name is just the package name, then looking + //for the main module. + if (moduleName === pkg.name) { + pkgPath = pkg.location + '/' + pkg.main; + } else { + pkgPath = pkg.location; + } + syms.splice(0, i, pkgPath); + break; + } + } + + //Join the path parts together, then figure out if baseUrl is needed. + url = syms.join('/'); + url += (ext || (/\?/.test(url) || skipExt ? '' : '.js')); + url = (url.charAt(0) === '/' || url.match(/^[\w\+\.\-]+:/) ? '' : config.baseUrl) + url; + } + + return config.urlArgs ? url + + ((url.indexOf('?') === -1 ? '?' : '&') + + config.urlArgs) : url; + }, + + //Delegates to req.load. Broken out as a separate function to + //allow overriding in the optimizer. + load: function (id, url) { + req.load(context, id, url); + }, + + /** + * Executes a module callback function. Broken out as a separate function + * solely to allow the build system to sequence the files in the built + * layer in the right sequence. + * + * @private + */ + execCb: function (name, callback, args, exports) { + return callback.apply(exports, args); + }, + + /** + * callback for script loads, used to check status of loading. + * + * @param {Event} evt the event from the browser for the script + * that was loaded. + */ + onScriptLoad: function (evt) { + //Using currentTarget instead of target for Firefox 2.0's sake. Not + //all old browsers will be supported, but this one was easy enough + //to support and still makes sense. + if (evt.type === 'load' || + (readyRegExp.test((evt.currentTarget || evt.srcElement).readyState))) { + //Reset interactive script so a script node is not held onto for + //to long. + interactiveScript = null; + + //Pull out the name of the module and the context. + var data = getScriptData(evt); + context.completeLoad(data.id); + } + }, + + /** + * Callback for script errors. + */ + onScriptError: function (evt) { + var data = getScriptData(evt); + if (!hasPathFallback(data.id)) { + return onError(makeError('scripterror', 'Script error for: ' + data.id, evt, [data.id])); + } + } + }; + + context.require = context.makeRequire(); + return context; + } + + /** + * Main entry point. + * + * If the only argument to require is a string, then the module that + * is represented by that string is fetched for the appropriate context. + * + * If the first argument is an array, then it will be treated as an array + * of dependency string names to fetch. An optional function callback can + * be specified to execute when all of those dependencies are available. + * + * Make a local req variable to help Caja compliance (it assumes things + * on a require that are not standardized), and to give a short + * name for minification/local scope use. + */ + req = requirejs = function (deps, callback, errback, optional) { + + //Find the right context, use default + var context, config, + contextName = defContextName; + + // Determine if have config object in the call. + if (!isArray(deps) && typeof deps !== 'string') { + // deps is a config object + config = deps; + if (isArray(callback)) { + // Adjust args if there are dependencies + deps = callback; + callback = errback; + errback = optional; + } else { + deps = []; + } + } + + if (config && config.context) { + contextName = config.context; + } + + context = getOwn(contexts, contextName); + if (!context) { + context = contexts[contextName] = req.s.newContext(contextName); + } + + if (config) { + context.configure(config); + } + + return context.require(deps, callback, errback); + }; + + /** + * Support require.config() to make it easier to cooperate with other + * AMD loaders on globally agreed names. + */ + req.config = function (config) { + return req(config); + }; + + /** + * Execute something after the current tick + * of the event loop. Override for other envs + * that have a better solution than setTimeout. + * @param {Function} fn function to execute later. + */ + req.nextTick = typeof setTimeout !== 'undefined' ? function (fn) { + setTimeout(fn, 4); + } : function (fn) { fn(); }; + + /** + * Export require as a global, but only if it does not already exist. + */ + if (!require) { + require = req; + } + + req.version = version; + + //Used to filter out dependencies that are already paths. + req.jsExtRegExp = /^\/|:|\?|\.js$/; + req.isBrowser = isBrowser; + s = req.s = { + contexts: contexts, + newContext: newContext + }; + + //Create default context. + req({}); + + //Exports some context-sensitive methods on global require. + each([ + 'toUrl', + 'undef', + 'defined', + 'specified' + ], function (prop) { + //Reference from contexts instead of early binding to default context, + //so that during builds, the latest instance of the default context + //with its config gets used. + req[prop] = function () { + var ctx = contexts[defContextName]; + return ctx.require[prop].apply(ctx, arguments); + }; + }); + + if (isBrowser) { + head = s.head = document.getElementsByTagName('head')[0]; + //If BASE tag is in play, using appendChild is a problem for IE6. + //When that browser dies, this can be removed. Details in this jQuery bug: + //http://dev.jquery.com/ticket/2709 + baseElement = document.getElementsByTagName('base')[0]; + if (baseElement) { + head = s.head = baseElement.parentNode; + } + } + + /** + * Any errors that require explicitly generates will be passed to this + * function. Intercept/override it if you want custom error handling. + * @param {Error} err the error object. + */ + req.onError = defaultOnError; + + /** + * Does the request to load a module for the browser case. + * Make this a separate function to allow other environments + * to override it. + * + * @param {Object} context the require context to find state. + * @param {String} moduleName the name of the module. + * @param {Object} url the URL to the module. + */ + req.load = function (context, moduleName, url) { + var config = (context && context.config) || {}, + node; + if (isBrowser) { + //In the browser so use a script tag + node = config.xhtml ? + document.createElementNS('http://www.w3.org/1999/xhtml', 'html:script') : + document.createElement('script'); + node.type = config.scriptType || 'text/javascript'; + node.charset = 'utf-8'; + node.async = true; + + node.setAttribute('data-requirecontext', context.contextName); + node.setAttribute('data-requiremodule', moduleName); + + //Set up load listener. Test attachEvent first because IE9 has + //a subtle issue in its addEventListener and script onload firings + //that do not match the behavior of all other browsers with + //addEventListener support, which fire the onload event for a + //script right after the script execution. See: + //https://connect.microsoft.com/IE/feedback/details/648057/script-onload-event-is-not-fired-immediately-after-script-execution + //UNFORTUNATELY Opera implements attachEvent but does not follow the script + //script execution mode. + if (node.attachEvent && + //Check if node.attachEvent is artificially added by custom script or + //natively supported by browser + //read https://github.com/jrburke/requirejs/issues/187 + //if we can NOT find [native code] then it must NOT natively supported. + //in IE8, node.attachEvent does not have toString() + //Note the test for "[native code" with no closing brace, see: + //https://github.com/jrburke/requirejs/issues/273 + !(node.attachEvent.toString && node.attachEvent.toString().indexOf('[native code') < 0) && + !isOpera) { + //Probably IE. IE (at least 6-8) do not fire + //script onload right after executing the script, so + //we cannot tie the anonymous define call to a name. + //However, IE reports the script as being in 'interactive' + //readyState at the time of the define call. + useInteractive = true; + + node.attachEvent('onreadystatechange', context.onScriptLoad); + //It would be great to add an error handler here to catch + //404s in IE9+. However, onreadystatechange will fire before + //the error handler, so that does not help. If addEventListener + //is used, then IE will fire error before load, but we cannot + //use that pathway given the connect.microsoft.com issue + //mentioned above about not doing the 'script execute, + //then fire the script load event listener before execute + //next script' that other browsers do. + //Best hope: IE10 fixes the issues, + //and then destroys all installs of IE 6-9. + //node.attachEvent('onerror', context.onScriptError); + } else { + node.addEventListener('load', context.onScriptLoad, false); + node.addEventListener('error', context.onScriptError, false); + } + node.src = url; + + //For some cache cases in IE 6-8, the script executes before the end + //of the appendChild execution, so to tie an anonymous define + //call to the module name (which is stored on the node), hold on + //to a reference to this node, but clear after the DOM insertion. + currentlyAddingScript = node; + if (baseElement) { + head.insertBefore(node, baseElement); + } else { + head.appendChild(node); + } + currentlyAddingScript = null; + + return node; + } else if (isWebWorker) { + try { + //In a web worker, use importScripts. This is not a very + //efficient use of importScripts, importScripts will block until + //its script is downloaded and evaluated. However, if web workers + //are in play, the expectation that a build has been done so that + //only one script needs to be loaded anyway. This may need to be + //reevaluated if other use cases become common. + importScripts(url); + + //Account for anonymous modules + context.completeLoad(moduleName); + } catch (e) { + context.onError(makeError('importscripts', + 'importScripts failed for ' + + moduleName + ' at ' + url, + e, + [moduleName])); + } + } + }; + + function getInteractiveScript() { + if (interactiveScript && interactiveScript.readyState === 'interactive') { + return interactiveScript; + } + + eachReverse(scripts(), function (script) { + if (script.readyState === 'interactive') { + return (interactiveScript = script); + } + }); + return interactiveScript; + } + + //Look for a data-main script attribute, which could also adjust the baseUrl. + if (isBrowser) { + //Figure out baseUrl. Get it from the script tag with require.js in it. + eachReverse(scripts(), function (script) { + //Set the 'head' where we can append children by + //using the script's parent. + if (!head) { + head = script.parentNode; + } + + //Look for a data-main attribute to set main script for the page + //to load. If it is there, the path to data main becomes the + //baseUrl, if it is not already set. + dataMain = script.getAttribute('data-main'); + if (dataMain) { + //Preserve dataMain in case it is a path (i.e. contains '?') + mainScript = dataMain; + + //Set final baseUrl if there is not already an explicit one. + if (!cfg.baseUrl) { + //Pull off the directory of data-main for use as the + //baseUrl. + src = mainScript.split('/'); + mainScript = src.pop(); + subPath = src.length ? src.join('/') + '/' : './'; + + cfg.baseUrl = subPath; + } + + //Strip off any trailing .js since mainScript is now + //like a module name. + mainScript = mainScript.replace(jsSuffixRegExp, ''); + + //If mainScript is still a path, fall back to dataMain + if (req.jsExtRegExp.test(mainScript)) { + mainScript = dataMain; + } + + //Put the data-main script in the files to load. + cfg.deps = cfg.deps ? cfg.deps.concat(mainScript) : [mainScript]; + + return true; + } + }); + } + + /** + * The function that handles definitions of modules. Differs from + * require() in that a string for the module should be the first argument, + * and the function to execute after dependencies are loaded should + * return a value to define the module corresponding to the first argument's + * name. + */ + define = function (name, deps, callback) { + var node, context; + + //Allow for anonymous modules + if (typeof name !== 'string') { + //Adjust args appropriately + callback = deps; + deps = name; + name = null; + } + + //This module may not have dependencies + if (!isArray(deps)) { + callback = deps; + deps = null; + } + + //If no name, and callback is a function, then figure out if it a + //CommonJS thing with dependencies. + if (!deps && isFunction(callback)) { + deps = []; + //Remove comments from the callback string, + //look for require calls, and pull them into the dependencies, + //but only if there are function args. + if (callback.length) { + callback + .toString() + .replace(commentRegExp, '') + .replace(cjsRequireRegExp, function (match, dep) { + deps.push(dep); + }); + + //May be a CommonJS thing even without require calls, but still + //could use exports, and module. Avoid doing exports and module + //work though if it just needs require. + //REQUIRES the function to expect the CommonJS variables in the + //order listed below. + deps = (callback.length === 1 ? ['require'] : ['require', 'exports', 'module']).concat(deps); + } + } + + //If in IE 6-8 and hit an anonymous define() call, do the interactive + //work. + if (useInteractive) { + node = currentlyAddingScript || getInteractiveScript(); + if (node) { + if (!name) { + name = node.getAttribute('data-requiremodule'); + } + context = contexts[node.getAttribute('data-requirecontext')]; + } + } + + //Always save off evaluating the def call until the script onload handler. + //This allows multiple modules to be in a file without prematurely + //tracing dependencies, and allows for anonymous module support, + //where the module name is not known until the script onload event + //occurs. If no context, use the global queue, and get it processed + //in the onscript load callback. + (context ? context.defQueue : globalDefQueue).push([name, deps, callback]); + }; + + define.amd = { + jQuery: true + }; + + + /** + * Executes the text. Normally just uses eval, but can be modified + * to use a better, environment-specific call. Only used for transpiling + * loader plugins, not for plain JS modules. + * @param {String} text the text to execute/evaluate. + */ + req.exec = function (text) { + /*jslint evil: true */ + return eval(text); + }; + + //Set up with config info. + req(cfg); +}(this)); + +define("requireLib", function(){}); + +/*! + * jQuery JavaScript Library v2.1.0 + * http://jquery.com/ + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * + * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2014-01-23T21:10Z + */ + +(function( global, factory ) { + + if ( typeof module === "object" && typeof module.exports === "object" ) { + // For CommonJS and CommonJS-like environments where a proper window is present, + // execute the factory and get jQuery + // For environments that do not inherently posses a window with a document + // (such as Node.js), expose a jQuery-making factory as module.exports + // This accentuates the need for the creation of a real window + // e.g. var jQuery = require("jquery")(window); + // See ticket #14549 for more info + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "jQuery requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); + } + +// Pass this if window is not defined yet +}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) { + +// Can't do this because several apps including ASP.NET trace +// the stack via arguments.caller.callee and Firefox dies if +// you try to trace through "use strict" call chains. (#13335) +// Support: Firefox 18+ +// + +var arr = []; + +var slice = arr.slice; + +var concat = arr.concat; + +var push = arr.push; + +var indexOf = arr.indexOf; + +var class2type = {}; + +var toString = class2type.toString; + +var hasOwn = class2type.hasOwnProperty; + +var trim = "".trim; + +var support = {}; + + + +var + // Use the correct document accordingly with window argument (sandbox) + document = window.document, + + version = "2.1.0", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }, + + // Matches dashed string for camelizing + rmsPrefix = /^-ms-/, + rdashAlpha = /-([\da-z])/gi, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return letter.toUpperCase(); + }; + +jQuery.fn = jQuery.prototype = { + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // Start with an empty selector + selector: "", + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num != null ? + + // Return a 'clean' array + ( num < 0 ? this[ num + this.length ] : this[ num ] ) : + + // Return just the object + slice.call( this ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + ret.context = this.context; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function( elem, i ) { + return callback.call( elem, i, elem ); + })); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] ); + }, + + end: function() { + return this.prevObject || this.constructor(null); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: arr.sort, + splice: arr.splice +}; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction(target) ) { + target = {}; + } + + // extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) { + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray(src) ? src : []; + + } else { + clone = src && jQuery.isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend({ + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function( msg ) { + throw new Error( msg ); + }, + + noop: function() {}, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return jQuery.type(obj) === "function"; + }, + + isArray: Array.isArray, + + isWindow: function( obj ) { + return obj != null && obj === obj.window; + }, + + isNumeric: function( obj ) { + // parseFloat NaNs numeric-cast false positives (null|true|false|"") + // ...but misinterprets leading-number strings, particularly hex literals ("0x...") + // subtraction forces infinities to NaN + return obj - parseFloat( obj ) >= 0; + }, + + isPlainObject: function( obj ) { + // Not plain objects: + // - Any object or value whose internal [[Class]] property is not "[object Object]" + // - DOM nodes + // - window + if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + // Support: Firefox <20 + // The try/catch suppresses exceptions thrown when attempting to access + // the "constructor" property of certain host objects, ie. |window.location| + // https://bugzilla.mozilla.org/show_bug.cgi?id=814622 + try { + if ( obj.constructor && + !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) { + return false; + } + } catch ( e ) { + return false; + } + + // If the function hasn't returned already, we're confident that + // |obj| is a plain object, created by {} or constructed with new Object + return true; + }, + + isEmptyObject: function( obj ) { + var name; + for ( name in obj ) { + return false; + } + return true; + }, + + type: function( obj ) { + if ( obj == null ) { + return obj + ""; + } + // Support: Android < 4.0, iOS < 6 (functionish RegExp) + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call(obj) ] || "object" : + typeof obj; + }, + + // Evaluates a script in a global context + globalEval: function( code ) { + var script, + indirect = eval; + + code = jQuery.trim( code ); + + if ( code ) { + // If the code includes a valid, prologue position + // strict mode pragma, execute code by injecting a + // script tag into the document. + if ( code.indexOf("use strict") === 1 ) { + script = document.createElement("script"); + script.text = code; + document.head.appendChild( script ).parentNode.removeChild( script ); + } else { + // Otherwise, avoid the DOM node creation, insertion + // and removal by using an indirect global eval + indirect( code ); + } + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + }, + + // args is for internal usage only + each: function( obj, callback, args ) { + var value, + i = 0, + length = obj.length, + isArray = isArraylike( obj ); + + if ( args ) { + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback.apply( obj[ i ], args ); + + if ( value === false ) { + break; + } + } + } else { + for ( i in obj ) { + value = callback.apply( obj[ i ], args ); + + if ( value === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback.call( obj[ i ], i, obj[ i ] ); + + if ( value === false ) { + break; + } + } + } else { + for ( i in obj ) { + value = callback.call( obj[ i ], i, obj[ i ] ); + + if ( value === false ) { + break; + } + } + } + } + + return obj; + }, + + trim: function( text ) { + return text == null ? "" : trim.call( text ); + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArraylike( Object(arr) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + return arr == null ? -1 : indexOf.call( arr, elem, i ); + }, + + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + for ( ; j < len; j++ ) { + first[ i++ ] = second[ j ]; + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var value, + i = 0, + length = elems.length, + isArray = isArraylike( elems ), + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + var tmp, args, proxy; + + if ( typeof context === "string" ) { + tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + args = slice.call( arguments, 2 ); + proxy = function() { + return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || jQuery.guid++; + + return proxy; + }, + + now: Date.now, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +}); + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +function isArraylike( obj ) { + var length = obj.length, + type = jQuery.type( obj ); + + if ( type === "function" || jQuery.isWindow( obj ) ) { + return false; + } + + if ( obj.nodeType === 1 && length ) { + return true; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v1.10.16 + * http://sizzlejs.com/ + * + * Copyright 2013 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2014-01-13 + */ +(function( window ) { + +var i, + support, + Expr, + getText, + isXML, + compile, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + -(new Date()), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // General-purpose constants + strundefined = typeof undefined, + MAX_NEGATIVE = 1 << 31, + + // Instance methods + hasOwn = ({}).hasOwnProperty, + arr = [], + pop = arr.pop, + push_native = arr.push, + push = arr.push, + slice = arr.slice, + // Use a stripped-down indexOf if we can't use a native one + indexOf = arr.indexOf || function( elem ) { + var i = 0, + len = this.length; + for ( ; i < len; i++ ) { + if ( this[i] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + // http://www.w3.org/TR/css3-syntax/#characters + characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", + + // Loosely modeled on CSS identifier characters + // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors + // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = characterEncoding.replace( "w", "w#" ), + + // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace + + "*(?:([*^$|!~]?=)" + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]", + + // Prefer arguments quoted, + // then not containing pseudos/brackets, + // then attribute selectors/non-parenthetical expressions, + // then anything else + // These preferences are here to reduce the number of selectors + // needing tokenize in the PSEUDO preFilter + pseudos = ":(" + characterEncoding + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + attributes.replace( 3, 8 ) + ")*)|.*)\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), + + rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + characterEncoding + ")" ), + "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), + "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + rescape = /'|\\/g, + + // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), + funescape = function( _, escaped, escapedWhitespace ) { + var high = "0x" + escaped - 0x10000; + // NaN means non-codepoint + // Support: Firefox + // Workaround erroneous numeric interpretation of +"0x" + return high !== high || escapedWhitespace ? + escaped : + high < 0 ? + // BMP codepoint + String.fromCharCode( high + 0x10000 ) : + // Supplemental Plane codepoint (surrogate pair) + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }; + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + (arr = slice.call( preferredDoc.childNodes )), + preferredDoc.childNodes + ); + // Support: Android<4.0 + // Detect silently failing push.apply + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + push_native.apply( target, slice.call(els) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + // Can't trust NodeList.length + while ( (target[j++] = els[i++]) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var match, elem, m, nodeType, + // QSA vars + i, groups, old, nid, newContext, newSelector; + + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { + setDocument( context ); + } + + context = context || document; + results = results || []; + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) { + return []; + } + + if ( documentIsHTML && !seed ) { + + // Shortcuts + if ( (match = rquickExpr.exec( selector )) ) { + // Speed-up: Sizzle("#ID") + if ( (m = match[1]) ) { + if ( nodeType === 9 ) { + elem = context.getElementById( m ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document (jQuery #6963) + if ( elem && elem.parentNode ) { + // Handle the case where IE, Opera, and Webkit return items + // by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + } else { + // Context is not a document + if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && + contains( context, elem ) && elem.id === m ) { + results.push( elem ); + return results; + } + } + + // Speed-up: Sizzle("TAG") + } else if ( match[2] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Speed-up: Sizzle(".CLASS") + } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) { + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // QSA path + if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { + nid = old = expando; + newContext = context; + newSelector = nodeType === 9 && selector; + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + groups = tokenize( selector ); + + if ( (old = context.getAttribute("id")) ) { + nid = old.replace( rescape, "\\$&" ); + } else { + context.setAttribute( "id", nid ); + } + nid = "[id='" + nid + "'] "; + + i = groups.length; + while ( i-- ) { + groups[i] = nid + toSelector( groups[i] ); + } + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context; + newSelector = groups.join(","); + } + + if ( newSelector ) { + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch(qsaError) { + } finally { + if ( !old ) { + context.removeAttribute("id"); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {Function(string, Object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return (cache[ key + " " ] = value); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created div and expects a boolean result + */ +function assert( fn ) { + var div = document.createElement("div"); + + try { + return !!fn( div ); + } catch (e) { + return false; + } finally { + // Remove from its parent by default + if ( div.parentNode ) { + div.parentNode.removeChild( div ); + } + // release memory in IE + div = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split("|"), + i = attrs.length; + + while ( i-- ) { + Expr.attrHandle[ arr[i] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + ( ~b.sourceIndex || MAX_NEGATIVE ) - + ( ~a.sourceIndex || MAX_NEGATIVE ); + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( (cur = cur.nextSibling) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== strundefined && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = elem && (elem.ownerDocument || elem).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, + doc = node ? node.ownerDocument || node : preferredDoc, + parent = doc.defaultView; + + // If no document and documentElement is available, return + if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Set our document + document = doc; + docElem = doc.documentElement; + + // Support tests + documentIsHTML = !isXML( doc ); + + // Support: IE>8 + // If iframe document is assigned to "document" variable and if iframe has been reloaded, + // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936 + // IE6-8 do not support the defaultView property so parent will be undefined + if ( parent && parent !== parent.top ) { + // IE11 does not have attachEvent, so all must suffer + if ( parent.addEventListener ) { + parent.addEventListener( "unload", function() { + setDocument(); + }, false ); + } else if ( parent.attachEvent ) { + parent.attachEvent( "onunload", function() { + setDocument(); + }); + } + } + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans) + support.attributes = assert(function( div ) { + div.className = "i"; + return !div.getAttribute("className"); + }); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert(function( div ) { + div.appendChild( doc.createComment("") ); + return !div.getElementsByTagName("*").length; + }); + + // Check if getElementsByClassName can be trusted + support.getElementsByClassName = rnative.test( doc.getElementsByClassName ) && assert(function( div ) { + div.innerHTML = "
"; + + // Support: Safari<4 + // Catch class over-caching + div.firstChild.className = "i"; + // Support: Opera<10 + // Catch gEBCN failure to find non-leading classes + return div.getElementsByClassName("i").length === 2; + }); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert(function( div ) { + docElem.appendChild( div ).id = expando; + return !doc.getElementsByName || !doc.getElementsByName( expando ).length; + }); + + // ID find and filter + if ( support.getById ) { + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== strundefined && documentIsHTML ) { + var m = context.getElementById( id ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [m] : []; + } + }; + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute("id") === attrId; + }; + }; + } else { + // Support: IE6/7 + // getElementById is not reliable as a find shortcut + delete Expr.find["ID"]; + + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id"); + return node && node.value === attrId; + }; + }; + } + + // Tag + Expr.find["TAG"] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== strundefined ) { + return context.getElementsByTagName( tag ); + } + } : + function( tag, context ) { + var elem, + tmp = [], + i = 0, + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( (elem = results[i++]) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See http://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) { + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( div ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // http://bugs.jquery.com/ticket/12359 + div.innerHTML = ""; + + // Support: IE8, Opera 10-12 + // Nothing should be selected when empty strings follow ^= or $= or *= + if ( div.querySelectorAll("[t^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !div.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + }); + + assert(function( div ) { + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = doc.createElement("input"); + input.setAttribute( "type", "hidden" ); + div.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( div.querySelectorAll("[name=d]").length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":enabled").length ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Opera 10-11 does not throw on post-comma invalid pseudos + div.querySelectorAll("*,:x"); + rbuggyQSA.push(",.*:"); + }); + } + + if ( (support.matchesSelector = rnative.test( (matches = docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector) )) ) { + + assert(function( div ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( div, "div" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( div, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + }); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully does not implement inclusive descendent + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + )); + } : + function( a, b ) { + if ( b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { + + // Choose the first element that is related to our preferred document + if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { + return -1; + } + if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + return a === doc ? -1 : + b === doc ? 1 : + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( (cur = cur.parentNode) ) { + ap.unshift( cur ); + } + cur = b; + while ( (cur = cur.parentNode) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[i] === bp[i] ) { + i++; + } + + return i ? + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[i], bp[i] ) : + + // Otherwise nodes in our document sort first + ap[i] === preferredDoc ? -1 : + bp[i] === preferredDoc ? 1 : + 0; + }; + + return doc; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + // Make sure that attribute selectors are quoted + expr = expr.replace( rattributeQuotes, "='$1']" ); + + if ( support.matchesSelector && documentIsHTML && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch(e) {} + } + + return Sizzle( expr, document, null, [elem] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + // Set document vars if needed + if ( ( context.ownerDocument || context ) !== document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + (val = elem.getAttributeNode(name)) && val.specified ? + val.value : + null; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( (elem = results[i++]) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + // If no nodeType, this is expected to be an array + while ( (node = elem[i++]) ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[4] || match[5] || "" ).replace( runescape, funescape ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1].slice( 0, 3 ) === "nth" ) { + // nth-* requires argument + if ( !match[3] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); + match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); + + // other types prohibit arguments + } else if ( match[3] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[5] && match[2]; + + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[3] && match[4] !== undefined ) { + match[2] = match[4]; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + match[0] = match[0].slice( 0, excess ); + match[2] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { return true; } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && + classCache( className, function( elem ) { + return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" ); + }); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + }; + }, + + "CHILD": function( type, what, argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, context, xml ) { + var cache, outerCache, node, diff, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( (node = node[ dir ]) ) { + if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { + return false; + } + } + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + // Seek `elem` from a previously-cached index + outerCache = parent[ expando ] || (parent[ expando ] = {}); + cache = outerCache[ type ] || []; + nodeIndex = cache[0] === dirruns && cache[1]; + diff = cache[0] === dirruns && cache[2]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( (node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + (diff = nodeIndex = 0) || start.pop()) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + outerCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + // Use previously-cached element index if available + } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) { + diff = cache[1]; + + // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...) + } else { + // Use the same loop as above to seek `elem` from the start + while ( (node = ++nodeIndex && node && node[ dir ] || + (diff = nodeIndex = 0) || start.pop()) ) { + + if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { + // Cache the index of each encountered element + if ( useCache ) { + (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf.call( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + // Potentially complex pseudos + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + return function( elem ) { + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + // lang value must be a valid identifier + if ( !ridentifier.test(lang || "") ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( (elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); + return false; + }; + }), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + + // Boolean properties + "enabled": function( elem ) { + return elem.disabled === false; + }, + + "disabled": function( elem ) { + return elem.disabled === true; + }, + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "selected": function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos["empty"]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "first": createPositionalPseudo(function() { + return [ 0 ]; + }), + + "last": createPositionalPseudo(function( matchIndexes, length ) { + return [ length - 1 ]; + }), + + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), + + "even": createPositionalPseudo(function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) + } +}; + +Expr.pseudos["nth"] = Expr.pseudos["eq"]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +function tokenize( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + // Don't consume trailing commas as valid + soFar = soFar.slice( match[0].length ) || soFar; + } + groups.push( (tokens = []) ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + matched = match.shift(); + tokens.push({ + value: matched, + // Cast descendant combinators to space + type: match[0].replace( rtrim, " " ) + }); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + (match = preFilters[ type ]( match ))) ) { + matched = match.shift(); + tokens.push({ + value: matched, + type: type, + matches: match + }); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +} + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[i].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + checkNonElements = base && dir === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching + if ( xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || (elem[ expando ] = {}); + if ( (oldCache = outerCache[ dir ]) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return (newCache[ 2 ] = oldCache[ 2 ]); + } else { + // Reuse newcache so results back-propagate to previous elements + outerCache[ dir ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { + return true; + } + } + } + } + } + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[i]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[0]; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( (elem = unmatched[i]) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction(function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( (elem = temp[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + // Restore matcherIn since elem is not yet a final match + temp.push( (matcherIn[i] = elem) ); + } + } + postFinder( null, (matcherOut = []), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) && + (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) { + + seed[temp] = !(results[temp] = elem); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + }); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[0].type ], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf.call( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + return ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + } ]; + + for ( ; i < len; i++ ) { + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { + matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; + } else { + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, outermost ) { + var elem, j, matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), + len = elems.length; + + if ( outermost ) { + outermostContext = context !== document && context; + } + + // Add elements passing elementMatchers directly to results + // Keep `i` a string if there are no elements so `matchedCount` will be "00" below + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id + for ( ; i !== len && (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + while ( (matcher = elementMatchers[j++]) ) { + if ( matcher( elem, context, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // Apply set filters to unmatched elements + matchedCount += i; + if ( bySet && i !== matchedCount ) { + j = 0; + while ( (matcher = setMatchers[j++]) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !group ) { + group = tokenize( selector ); + } + i = group.length; + while ( i-- ) { + cached = matcherFromTokens( group[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + } + return cached; +}; + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results ); + } + return results; +} + +function select( selector, context, results, seed ) { + var i, tokens, token, type, find, + match = tokenize( selector ); + + if ( !seed ) { + // Try to minimize operations if there is only one group + if ( match.length === 1 ) { + + // Take a shortcut and set the context if the root selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + support.getById && context.nodeType === 9 && documentIsHTML && + Expr.relative[ tokens[1].type ] ) { + + context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; + if ( !context ) { + return results; + } + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( runescape, funescape ), + rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + } + + // Compile and execute a filtering function + // Provide `match` to avoid retokenization if we modified the selector above + compile( selector, match )( + seed, + context, + !documentIsHTML, + results, + rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; +} + +// One-time assignments + +// Sort stability +support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; + +// Support: Chrome<14 +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = !!hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert(function( div1 ) { + // Should return 1, but returns 4 (following) + return div1.compareDocumentPosition( document.createElement("div") ) & 1; +}); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert(function( div ) { + div.innerHTML = ""; + return div.firstChild.getAttribute("href") === "#" ; +}) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + }); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert(function( div ) { + div.innerHTML = ""; + div.firstChild.setAttribute( "value", "" ); + return div.firstChild.getAttribute( "value" ) === ""; +}) ) { + addHandle( "value", function( elem, name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + }); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert(function( div ) { + return div.getAttribute("disabled") == null; +}) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + (val = elem.getAttributeNode( name )) && val.specified ? + val.value : + null; + } + }); +} + +return Sizzle; + +})( window ); + + + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.pseudos; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + + +var rneedsContext = jQuery.expr.match.needsContext; + +var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/); + + + +var risSimple = /^.[^:#\[\.,]*$/; + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + /* jshint -W018 */ + return !!qualifier.call( elem, i, elem ) !== not; + }); + + } + + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + }); + + } + + if ( typeof qualifier === "string" ) { + if ( risSimple.test( qualifier ) ) { + return jQuery.filter( qualifier, elements, not ); + } + + qualifier = jQuery.filter( qualifier, elements ); + } + + return jQuery.grep( elements, function( elem ) { + return ( indexOf.call( qualifier, elem ) >= 0 ) !== not; + }); +} + +jQuery.filter = function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 && elem.nodeType === 1 ? + jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : + jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + })); +}; + +jQuery.fn.extend({ + find: function( selector ) { + var i, + len = this.length, + ret = [], + self = this; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter(function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }) ); + } + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + // Needed because $( selector, context ) becomes $( context ).find( selector ) + ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); + ret.selector = this.selector ? this.selector + " " + selector : selector; + return ret; + }, + filter: function( selector ) { + return this.pushStack( winnow(this, selector || [], false) ); + }, + not: function( selector ) { + return this.pushStack( winnow(this, selector || [], true) ); + }, + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } +}); + + +// Initialize a jQuery object + + +// A central reference to the root jQuery(document) +var rootjQuery, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, + + init = jQuery.fn.init = function( selector, context ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector[0] === "<" && selector[ selector.length - 1 ] === ">" && selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + + // scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[1], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + // Properties of context are called as methods if possible + if ( jQuery.isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[2] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Inject the element directly into the jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || rootjQuery ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return typeof rootjQuery.ready !== "undefined" ? + rootjQuery.ready( selector ) : + // Execute immediately if ready is not present + selector( jQuery ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }; + +// Give the init function the jQuery prototype for later instantiation +init.prototype = jQuery.fn; + +// Initialize central reference +rootjQuery = jQuery( document ); + + +var rparentsprev = /^(?:parents|prev(?:Until|All))/, + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.extend({ + dir: function( elem, dir, until ) { + var matched = [], + truncate = until !== undefined; + + while ( (elem = elem[ dir ]) && elem.nodeType !== 9 ) { + if ( elem.nodeType === 1 ) { + if ( truncate && jQuery( elem ).is( until ) ) { + break; + } + matched.push( elem ); + } + } + return matched; + }, + + sibling: function( n, elem ) { + var matched = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + matched.push( n ); + } + } + + return matched; + } +}); + +jQuery.fn.extend({ + has: function( target ) { + var targets = jQuery( target, this ), + l = targets.length; + + return this.filter(function() { + var i = 0; + for ( ; i < l; i++ ) { + if ( jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + matched = [], + pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( ; i < l; i++ ) { + for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) { + // Always skip document fragments + if ( cur.nodeType < 11 && (pos ? + pos.index(cur) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector(cur, selectors)) ) { + + matched.push( cur ); + break; + } + } + } + + return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return indexOf.call( jQuery( elem ), this[ 0 ] ); + } + + // Locate the position of the desired element + return indexOf.call( this, + + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[ 0 ] : elem + ); + }, + + add: function( selector, context ) { + return this.pushStack( + jQuery.unique( + jQuery.merge( this.get(), jQuery( selector, context ) ) + ) + ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter(selector) + ); + } +}); + +function sibling( cur, dir ) { + while ( (cur = cur[dir]) && cur.nodeType !== 1 ) {} + return cur; +} + +jQuery.each({ + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return elem.contentDocument || jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var matched = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + matched = jQuery.filter( selector, matched ); + } + + if ( this.length > 1 ) { + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + jQuery.unique( matched ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + matched.reverse(); + } + } + + return this.pushStack( matched ); + }; +}); +var rnotwhite = (/\S+/g); + + + +// String to Object options format cache +var optionsCache = {}; + +// Convert String-formatted options into Object-formatted ones and store in cache +function createOptions( options ) { + var object = optionsCache[ options ] = {}; + jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) { + object[ flag ] = true; + }); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + ( optionsCache[ options ] || createOptions( options ) ) : + jQuery.extend( {}, options ); + + var // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list was already fired + fired, + // Flag to know if list is currently firing + firing, + // First callback to fire (used internally by add and fireWith) + firingStart, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = !options.once && [], + // Fire callbacks + fire = function( data ) { + memory = options.memory && data; + fired = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + firing = true; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { + memory = false; // To prevent further calls using add + break; + } + } + firing = false; + if ( list ) { + if ( stack ) { + if ( stack.length ) { + fire( stack.shift() ); + } + } else if ( memory ) { + list = []; + } else { + self.disable(); + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + // First, we save the current length + var start = list.length; + (function add( args ) { + jQuery.each( args, function( _, arg ) { + var type = jQuery.type( arg ); + if ( type === "function" ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && type !== "string" ) { + // Inspect recursively + add( arg ); + } + }); + })( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away + } else if ( memory ) { + firingStart = start; + fire( memory ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + // Handle firing indexes + if ( firing ) { + if ( index <= firingLength ) { + firingLength--; + } + if ( index <= firingIndex ) { + firingIndex--; + } + } + } + }); + } + return this; + }, + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length ); + }, + // Remove all callbacks from the list + empty: function() { + list = []; + firingLength = 0; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( list && ( !fired || stack ) ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + if ( firing ) { + stack.push( args ); + } else { + fire( args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + +jQuery.extend({ + + Deferred: function( func ) { + var tuples = [ + // action, add listener, listener list, final state + [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], + [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], + [ "notify", "progress", jQuery.Callbacks("memory") ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + then: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + return jQuery.Deferred(function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; + // deferred[ done | fail | progress ] for forwarding actions to newDefer + deferred[ tuple[1] ](function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .done( newDefer.resolve ) + .fail( newDefer.reject ) + .progress( newDefer.notify ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); + } + }); + }); + fns = null; + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Keep pipe for back-compat + promise.pipe = promise.then; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 3 ]; + + // promise[ done | fail | progress ] = list.add + promise[ tuple[1] ] = list.add; + + // Handle state + if ( stateString ) { + list.add(function() { + // state = [ resolved | rejected ] + state = stateString; + + // [ reject_list | resolve_list ].disable; progress_list.lock + }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); + } + + // deferred[ resolve | reject | notify ] + deferred[ tuple[0] ] = function() { + deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments ); + return this; + }; + deferred[ tuple[0] + "With" ] = list.fireWith; + }); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( subordinate /* , ..., subordinateN */ ) { + var i = 0, + resolveValues = slice.call( arguments ), + length = resolveValues.length, + + // the count of uncompleted subordinates + remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, + + // the master Deferred. If resolveValues consist of only a single Deferred, just use that. + deferred = remaining === 1 ? subordinate : jQuery.Deferred(), + + // Update function for both resolve and progress values + updateFunc = function( i, contexts, values ) { + return function( value ) { + contexts[ i ] = this; + values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; + if ( values === progressValues ) { + deferred.notifyWith( contexts, values ); + } else if ( !( --remaining ) ) { + deferred.resolveWith( contexts, values ); + } + }; + }, + + progressValues, progressContexts, resolveContexts; + + // add listeners to Deferred subordinates; treat others as resolved + if ( length > 1 ) { + progressValues = new Array( length ); + progressContexts = new Array( length ); + resolveContexts = new Array( length ); + for ( ; i < length; i++ ) { + if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { + resolveValues[ i ].promise() + .done( updateFunc( i, resolveContexts, resolveValues ) ) + .fail( deferred.reject ) + .progress( updateFunc( i, progressContexts, progressValues ) ); + } else { + --remaining; + } + } + } + + // if we're not waiting on anything, resolve the master + if ( !remaining ) { + deferred.resolveWith( resolveContexts, resolveValues ); + } + + return deferred.promise(); + } +}); + + +// The deferred used on DOM ready +var readyList; + +jQuery.fn.ready = function( fn ) { + // Add the callback + jQuery.ready.promise().done( fn ); + + return this; +}; + +jQuery.extend({ + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.trigger ) { + jQuery( document ).trigger("ready").off("ready"); + } + } +}); + +/** + * The ready event handler and self cleanup method + */ +function completed() { + document.removeEventListener( "DOMContentLoaded", completed, false ); + window.removeEventListener( "load", completed, false ); + jQuery.ready(); +} + +jQuery.ready.promise = function( obj ) { + if ( !readyList ) { + + readyList = jQuery.Deferred(); + + // Catch cases where $(document).ready() is called after the browser event has already occurred. + // we once tried to use readyState "interactive" here, but it caused issues like the one + // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + setTimeout( jQuery.ready ); + + } else { + + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed, false ); + } + } + return readyList.promise( obj ); +}; + +// Kick off the DOM ready check even if the user does not +jQuery.ready.promise(); + + + + +// Multifunctional method to get and set values of a collection +// The value/s can optionally be executed if it's a function +var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + len = elems.length, + bulk = key == null; + + // Sets many values + if ( jQuery.type( key ) === "object" ) { + chainable = true; + for ( i in key ) { + jQuery.access( elems, fn, i, key[i], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !jQuery.isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < len; i++ ) { + fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) ); + } + } + } + + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + len ? fn( elems[0], key ) : emptyGet; +}; + + +/** + * Determines whether an object can have data + */ +jQuery.acceptData = function( owner ) { + // Accepts only: + // - Node + // - Node.ELEMENT_NODE + // - Node.DOCUMENT_NODE + // - Object + // - Any + /* jshint -W018 */ + return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); +}; + + +function Data() { + // Support: Android < 4, + // Old WebKit does not have Object.preventExtensions/freeze method, + // return new empty object instead with no [[set]] accessor + Object.defineProperty( this.cache = {}, 0, { + get: function() { + return {}; + } + }); + + this.expando = jQuery.expando + Math.random(); +} + +Data.uid = 1; +Data.accepts = jQuery.acceptData; + +Data.prototype = { + key: function( owner ) { + // We can accept data for non-element nodes in modern browsers, + // but we should not, see #8335. + // Always return the key for a frozen object. + if ( !Data.accepts( owner ) ) { + return 0; + } + + var descriptor = {}, + // Check if the owner object already has a cache key + unlock = owner[ this.expando ]; + + // If not, create one + if ( !unlock ) { + unlock = Data.uid++; + + // Secure it in a non-enumerable, non-writable property + try { + descriptor[ this.expando ] = { value: unlock }; + Object.defineProperties( owner, descriptor ); + + // Support: Android < 4 + // Fallback to a less secure definition + } catch ( e ) { + descriptor[ this.expando ] = unlock; + jQuery.extend( owner, descriptor ); + } + } + + // Ensure the cache object + if ( !this.cache[ unlock ] ) { + this.cache[ unlock ] = {}; + } + + return unlock; + }, + set: function( owner, data, value ) { + var prop, + // There may be an unlock assigned to this node, + // if there is no entry for this "owner", create one inline + // and set the unlock as though an owner entry had always existed + unlock = this.key( owner ), + cache = this.cache[ unlock ]; + + // Handle: [ owner, key, value ] args + if ( typeof data === "string" ) { + cache[ data ] = value; + + // Handle: [ owner, { properties } ] args + } else { + // Fresh assignments by object are shallow copied + if ( jQuery.isEmptyObject( cache ) ) { + jQuery.extend( this.cache[ unlock ], data ); + // Otherwise, copy the properties one-by-one to the cache object + } else { + for ( prop in data ) { + cache[ prop ] = data[ prop ]; + } + } + } + return cache; + }, + get: function( owner, key ) { + // Either a valid cache is found, or will be created. + // New caches will be created and the unlock returned, + // allowing direct access to the newly created + // empty data object. A valid owner object must be provided. + var cache = this.cache[ this.key( owner ) ]; + + return key === undefined ? + cache : cache[ key ]; + }, + access: function( owner, key, value ) { + var stored; + // In cases where either: + // + // 1. No key was specified + // 2. A string key was specified, but no value provided + // + // Take the "read" path and allow the get method to determine + // which value to return, respectively either: + // + // 1. The entire cache object + // 2. The data stored at the key + // + if ( key === undefined || + ((key && typeof key === "string") && value === undefined) ) { + + stored = this.get( owner, key ); + + return stored !== undefined ? + stored : this.get( owner, jQuery.camelCase(key) ); + } + + // [*]When the key is not a string, or both a key and value + // are specified, set or extend (existing objects) with either: + // + // 1. An object of properties + // 2. A key and value + // + this.set( owner, key, value ); + + // Since the "set" path can have two possible entry points + // return the expected data based on which path was taken[*] + return value !== undefined ? value : key; + }, + remove: function( owner, key ) { + var i, name, camel, + unlock = this.key( owner ), + cache = this.cache[ unlock ]; + + if ( key === undefined ) { + this.cache[ unlock ] = {}; + + } else { + // Support array or space separated string of keys + if ( jQuery.isArray( key ) ) { + // If "name" is an array of keys... + // When data is initially created, via ("key", "val") signature, + // keys will be converted to camelCase. + // Since there is no way to tell _how_ a key was added, remove + // both plain key and camelCase key. #12786 + // This will only penalize the array argument path. + name = key.concat( key.map( jQuery.camelCase ) ); + } else { + camel = jQuery.camelCase( key ); + // Try the string as a key before any manipulation + if ( key in cache ) { + name = [ key, camel ]; + } else { + // If a key with the spaces exists, use it. + // Otherwise, create an array by matching non-whitespace + name = camel; + name = name in cache ? + [ name ] : ( name.match( rnotwhite ) || [] ); + } + } + + i = name.length; + while ( i-- ) { + delete cache[ name[ i ] ]; + } + } + }, + hasData: function( owner ) { + return !jQuery.isEmptyObject( + this.cache[ owner[ this.expando ] ] || {} + ); + }, + discard: function( owner ) { + if ( owner[ this.expando ] ) { + delete this.cache[ owner[ this.expando ] ]; + } + } +}; +var data_priv = new Data(); + +var data_user = new Data(); + + + +/* + Implementation Summary + + 1. Enforce API surface and semantic compatibility with 1.9.x branch + 2. Improve the module's maintainability by reducing the storage + paths to a single mechanism. + 3. Use the same single mechanism to support "private" and "user" data. + 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) + 5. Avoid exposing implementation details on user objects (eg. expando properties) + 6. Provide a clear path for implementation upgrade to WeakMap in 2014 +*/ +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + rmultiDash = /([A-Z])/g; + +function dataAttr( elem, key, data ) { + var name; + + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + // Only convert to a number if it doesn't change the string + +data + "" === data ? +data : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + data_user.set( elem, key, data ); + } else { + data = undefined; + } + } + return data; +} + +jQuery.extend({ + hasData: function( elem ) { + return data_user.hasData( elem ) || data_priv.hasData( elem ); + }, + + data: function( elem, name, data ) { + return data_user.access( elem, name, data ); + }, + + removeData: function( elem, name ) { + data_user.remove( elem, name ); + }, + + // TODO: Now that all calls to _data and _removeData have been replaced + // with direct calls to data_priv methods, these can be deprecated. + _data: function( elem, name, data ) { + return data_priv.access( elem, name, data ); + }, + + _removeData: function( elem, name ) { + data_priv.remove( elem, name ); + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var i, name, data, + elem = this[ 0 ], + attrs = elem && elem.attributes; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = data_user.get( elem ); + + if ( elem.nodeType === 1 && !data_priv.get( elem, "hasDataAttrs" ) ) { + i = attrs.length; + while ( i-- ) { + name = attrs[ i ].name; + + if ( name.indexOf( "data-" ) === 0 ) { + name = jQuery.camelCase( name.slice(5) ); + dataAttr( elem, name, data[ name ] ); + } + } + data_priv.set( elem, "hasDataAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each(function() { + data_user.set( this, key ); + }); + } + + return access( this, function( value ) { + var data, + camelKey = jQuery.camelCase( key ); + + // The calling jQuery object (element matches) is not empty + // (and therefore has an element appears at this[ 0 ]) and the + // `value` parameter was not undefined. An empty jQuery object + // will result in `undefined` for elem = this[ 0 ] which will + // throw an exception if an attempt to read a data cache is made. + if ( elem && value === undefined ) { + // Attempt to get data from the cache + // with the key as-is + data = data_user.get( elem, key ); + if ( data !== undefined ) { + return data; + } + + // Attempt to get data from the cache + // with the key camelized + data = data_user.get( elem, camelKey ); + if ( data !== undefined ) { + return data; + } + + // Attempt to "discover" the data in + // HTML5 custom data-* attrs + data = dataAttr( elem, camelKey, undefined ); + if ( data !== undefined ) { + return data; + } + + // We tried really hard, but the data doesn't exist. + return; + } + + // Set the data... + this.each(function() { + // First, attempt to store a copy or reference of any + // data that might've been store with a camelCased key. + var data = data_user.get( this, camelKey ); + + // For HTML5 data-* attribute interop, we have to + // store property names with dashes in a camelCase form. + // This might not apply to all properties...* + data_user.set( this, camelKey, value ); + + // *... In the case of properties that might _actually_ + // have dashes, we need to also store a copy of that + // unchanged property. + if ( key.indexOf("-") !== -1 && data !== undefined ) { + data_user.set( this, key, value ); + } + }); + }, null, value, arguments.length > 1, null, true ); + }, + + removeData: function( key ) { + return this.each(function() { + data_user.remove( this, key ); + }); + } +}); + + +jQuery.extend({ + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = data_priv.get( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || jQuery.isArray( data ) ) { + queue = data_priv.access( elem, type, jQuery.makeArray(data) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // not intended for public consumption - generates a queueHooks object, or returns the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return data_priv.get( elem, key ) || data_priv.access( elem, key, { + empty: jQuery.Callbacks("once memory").add(function() { + data_priv.remove( elem, [ type + "queue", key ] ); + }) + }); + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[0], type ); + } + + return data === undefined ? + this : + this.each(function() { + var queue = jQuery.queue( this, type, data ); + + // ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + }); + }, + dequeue: function( type ) { + return this.each(function() { + jQuery.dequeue( this, type ); + }); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while ( i-- ) { + tmp = data_priv.get( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +}); +var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source; + +var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; + +var isHidden = function( elem, el ) { + // isHidden might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); + }; + +var rcheckableType = (/^(?:checkbox|radio)$/i); + + + +(function() { + var fragment = document.createDocumentFragment(), + div = fragment.appendChild( document.createElement( "div" ) ); + + // #11217 - WebKit loses check when the name is after the checked attribute + div.innerHTML = ""; + + // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3 + // old WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Make sure textarea (and checkbox) defaultValue is properly cloned + // Support: IE9-IE11+ + div.innerHTML = ""; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; +})(); +var strundefined = typeof undefined; + + + +support.focusinBubbles = "onfocusin" in window; + + +var + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)$/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + + var handleObjIn, eventHandle, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = data_priv.get( elem ); + + // Don't attach events to noData or text/comment nodes (but allow plain objects) + if ( !elemData ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !(events = elemData.events) ) { + events = elemData.events = {}; + } + if ( !(eventHandle = elemData.handle) ) { + eventHandle = elemData.handle = function( e ) { + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== strundefined && jQuery.event.triggered !== e.type ? + jQuery.event.dispatch.apply( elem, arguments ) : undefined; + }; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( rnotwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend({ + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join(".") + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !(handlers = events[ type ]) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener if the special events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var j, origCount, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = data_priv.hasData( elem ) && data_priv.get( elem ); + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( rnotwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + delete elemData.handle; + data_priv.remove( elem, "events" ); + } + }, + + trigger: function( event, data, elem, onlyHandlers ) { + + var i, cur, tmp, bubbleType, ontype, handle, special, + eventPath = [ elem || document ], + type = hasOwn.call( event, "type" ) ? event.type : event, + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : []; + + cur = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf(".") >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf(":") < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join("."); + event.namespace_re = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === (elem.ownerDocument || document) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) { + + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( data_priv.get( cur, "events" ) || {} )[ event.type ] && data_priv.get( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && handle.apply && jQuery.acceptData( cur ) ) { + event.result = handle.apply( cur, data ); + if ( event.result === false ) { + event.preventDefault(); + } + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) && + jQuery.acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + elem[ type ](); + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event ); + + var i, j, ret, matched, handleObj, + handlerQueue = [], + args = slice.call( arguments ), + handlers = ( data_priv.get( this, "events" ) || {} )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) { + + // Triggered event must either 1) have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). + if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) + .apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( (event.result = ret) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var i, matches, sel, handleObj, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + // Black-hole SVG instance trees (#13180) + // Avoid non-left-click bubbling in Firefox (#3861) + if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) { + + for ( ; cur !== this; cur = cur.parentNode || this ) { + + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.disabled !== true || event.type !== "click" ) { + matches = []; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matches[ sel ] === undefined ) { + matches[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) >= 0 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matches[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, handlers: matches }); + } + } + } + } + + // Add the remaining (directly-bound) handlers + if ( delegateCount < handlers.length ) { + handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) }); + } + + return handlerQueue; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split(" "), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var eventDoc, doc, body, + button = original.button; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, copy, + type = event.type, + originalEvent = event, + fixHook = this.fixHooks[ type ]; + + if ( !fixHook ) { + this.fixHooks[ type ] = fixHook = + rmouseEvent.test( type ) ? this.mouseHooks : + rkeyEvent.test( type ) ? this.keyHooks : + {}; + } + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = new jQuery.Event( originalEvent ); + + i = copy.length; + while ( i-- ) { + prop = copy[ i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Support: Cordova 2.5 (WebKit) (#13255) + // All events should have a target; Cordova deviceready doesn't + if ( !event.target ) { + event.target = document; + } + + // Support: Safari 6.0+, Chrome < 28 + // Target should not be a text node (#504, #13143) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + return fixHook.filter ? fixHook.filter( event, originalEvent ) : event; + }, + + special: { + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + focus: { + // Fire native event if possible so blur/focus sequence is correct + trigger: function() { + if ( this !== safeActiveElement() && this.focus ) { + this.focus(); + return false; + } + }, + delegateType: "focusin" + }, + blur: { + trigger: function() { + if ( this === safeActiveElement() && this.blur ) { + this.blur(); + return false; + } + }, + delegateType: "focusout" + }, + click: { + // For checkbox, fire native event so checked state will be right + trigger: function() { + if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) { + this.click(); + return false; + } + }, + + // For cross-browser consistency, don't fire native .click() on links + _default: function( event ) { + return jQuery.nodeName( event.target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + if ( event.result !== undefined ) { + event.originalEvent.returnValue = event.result; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // Piggyback on a donor event to simulate a different one. + // Fake originalEvent to avoid donor's stopPropagation, but if the + // simulated event prevents default then we do the same on the donor. + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + jQuery.event.trigger( e, null, elem ); + } else { + jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +jQuery.removeEvent = function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } +}; + +jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof jQuery.Event) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || + // Support: Android < 4.0 + src.defaultPrevented === undefined && + src.getPreventDefault && src.getPreventDefault() ? + returnTrue : + returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + + if ( e && e.preventDefault ) { + e.preventDefault(); + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + + if ( e && e.stopPropagation ) { + e.stopPropagation(); + } + }, + stopImmediatePropagation: function() { + this.isImmediatePropagationStopped = returnTrue; + this.stopPropagation(); + } +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +// Support: Chrome 15+ +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !jQuery.contains( target, related )) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +}); + +// Create "bubbling" focus and blur events +// Support: Firefox, Chrome, Safari +if ( !support.focusinBubbles ) { + jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler on the document while someone wants focusin/focusout + var handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + var doc = this.ownerDocument || this, + attaches = data_priv.access( doc, fix ); + + if ( !attaches ) { + doc.addEventListener( orig, handler, true ); + } + data_priv.access( doc, fix, ( attaches || 0 ) + 1 ); + }, + teardown: function() { + var doc = this.ownerDocument || this, + attaches = data_priv.access( doc, fix ) - 1; + + if ( !attaches ) { + doc.removeEventListener( orig, handler, true ); + data_priv.remove( doc, fix ); + + } else { + data_priv.access( doc, fix, attaches ); + } + } + }; + }); +} + +jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return this.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on( types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + jQuery.event.remove( this, types, fn, selector ); + }); + }, + + trigger: function( type, data ) { + return this.each(function() { + jQuery.event.trigger( type, data, this ); + }); + }, + triggerHandler: function( type, data ) { + var elem = this[0]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +}); + + +var + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, + rtagName = /<([\w:]+)/, + rhtml = /<|&#?\w+;/, + rnoInnerhtml = /<(?:script|style|link)/i, + // checked="checked" or checked + rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, + rscriptType = /^$|\/(?:java|ecma)script/i, + rscriptTypeMasked = /^true\/(.*)/, + rcleanScript = /^\s*\s*$/g, + + // We have to close these tags to support XHTML (#13200) + wrapMap = { + + // Support: IE 9 + option: [ 1, "" ], + + thead: [ 1, "", "
" ], + col: [ 2, "", "
" ], + tr: [ 2, "", "
" ], + td: [ 3, "", "
" ], + + _default: [ 0, "", "" ] + }; + +// Support: IE 9 +wrapMap.optgroup = wrapMap.option; + +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// Support: 1.x compatibility +// Manipulating tables requires a tbody +function manipulationTarget( elem, content ) { + return jQuery.nodeName( elem, "table" ) && + jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ? + + elem.getElementsByTagName("tbody")[0] || + elem.appendChild( elem.ownerDocument.createElement("tbody") ) : + elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + var match = rscriptTypeMasked.exec( elem.type ); + + if ( match ) { + elem.type = match[ 1 ]; + } else { + elem.removeAttribute("type"); + } + + return elem; +} + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + data_priv.set( + elems[ i ], "globalEval", !refElements || data_priv.get( refElements[ i ], "globalEval" ) + ); + } +} + +function cloneCopyEvent( src, dest ) { + var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; + + if ( dest.nodeType !== 1 ) { + return; + } + + // 1. Copy private data: events, handlers, etc. + if ( data_priv.hasData( src ) ) { + pdataOld = data_priv.access( src ); + pdataCur = data_priv.set( dest, pdataOld ); + events = pdataOld.events; + + if ( events ) { + delete pdataCur.handle; + pdataCur.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + } + + // 2. Copy user data + if ( data_user.hasData( src ) ) { + udataOld = data_user.access( src ); + udataCur = jQuery.extend( {}, udataOld ); + + data_user.set( dest, udataCur ); + } +} + +function getAll( context, tag ) { + var ret = context.getElementsByTagName ? context.getElementsByTagName( tag || "*" ) : + context.querySelectorAll ? context.querySelectorAll( tag || "*" ) : + []; + + return tag === undefined || tag && jQuery.nodeName( context, tag ) ? + jQuery.merge( [ context ], ret ) : + ret; +} + +// Support: IE >= 9 +function fixInput( src, dest ) { + var nodeName = dest.nodeName.toLowerCase(); + + // Fails to persist the checked state of a cloned checkbox or radio button. + if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + dest.checked = src.checked; + + // Fails to return the selected option to the default selected state when cloning options + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +jQuery.extend({ + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var i, l, srcElements, destElements, + clone = elem.cloneNode( true ), + inPage = jQuery.contains( elem.ownerDocument, elem ); + + // Support: IE >= 9 + // Fix Cloning issues + if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && + !jQuery.isXMLDoc( elem ) ) { + + // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + fixInput( srcElements[ i ], destElements[ i ] ); + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + cloneCopyEvent( srcElements[ i ], destElements[ i ] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + // Return the cloned set + return clone; + }, + + buildFragment: function( elems, context, scripts, selection ) { + var elem, tmp, tag, wrap, contains, j, + fragment = context.createDocumentFragment(), + nodes = [], + i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( jQuery.type( elem ) === "object" ) { + // Support: QtWebKit + // jQuery.merge because push.apply(_, arraylike) throws + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || fragment.appendChild( context.createElement("div") ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + tmp.innerHTML = wrap[ 1 ] + elem.replace( rxhtmlTag, "<$1>" ) + wrap[ 2 ]; + + // Descend through wrappers to the right content + j = wrap[ 0 ]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Support: QtWebKit + // jQuery.merge because push.apply(_, arraylike) throws + jQuery.merge( nodes, tmp.childNodes ); + + // Remember the top-level container + tmp = fragment.firstChild; + + // Fixes #12346 + // Support: Webkit, IE + tmp.textContent = ""; + } + } + } + + // Remove wrapper from fragment + fragment.textContent = ""; + + i = 0; + while ( (elem = nodes[ i++ ]) ) { + + // #4087 - If origin and destination elements are the same, and this is + // that element, do not do anything + if ( selection && jQuery.inArray( elem, selection ) !== -1 ) { + continue; + } + + contains = jQuery.contains( elem.ownerDocument, elem ); + + // Append to fragment + tmp = getAll( fragment.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( contains ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( (elem = tmp[ j++ ]) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + return fragment; + }, + + cleanData: function( elems ) { + var data, elem, events, type, key, j, + special = jQuery.event.special, + i = 0; + + for ( ; (elem = elems[ i ]) !== undefined; i++ ) { + if ( jQuery.acceptData( elem ) ) { + key = elem[ data_priv.expando ]; + + if ( key && (data = data_priv.cache[ key ]) ) { + events = Object.keys( data.events || {} ); + if ( events.length ) { + for ( j = 0; (type = events[j]) !== undefined; j++ ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + if ( data_priv.cache[ key ] ) { + // Discard any remaining `private` data + delete data_priv.cache[ key ]; + } + } + } + // Discard any remaining `user` data + delete data_user.cache[ elem[ data_user.expando ] ]; + } + } +}); + +jQuery.fn.extend({ + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().each(function() { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + this.textContent = value; + } + }); + }, null, value, arguments.length ); + }, + + append: function() { + return this.domManip( arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + }); + }, + + prepend: function() { + return this.domManip( arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + }); + }, + + before: function() { + return this.domManip( arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + }); + }, + + after: function() { + return this.domManip( arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + }); + }, + + remove: function( selector, keepData /* Internal Use Only */ ) { + var elem, + elems = selector ? jQuery.filter( selector, this ) : this, + i = 0; + + for ( ; (elem = elems[i]) != null; i++ ) { + if ( !keepData && elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem ) ); + } + + if ( elem.parentNode ) { + if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) { + setGlobalEval( getAll( elem, "script" ) ); + } + elem.parentNode.removeChild( elem ); + } + } + + return this; + }, + + empty: function() { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { + if ( elem.nodeType === 1 ) { + + // Prevent memory leaks + jQuery.cleanData( getAll( elem, false ) ); + + // Remove any remaining nodes + elem.textContent = ""; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map(function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + }); + }, + + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; + + if ( value === undefined && elem.nodeType === 1 ) { + return elem.innerHTML; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { + + value = value.replace( rxhtmlTag, "<$1>" ); + + try { + for ( ; i < l; i++ ) { + elem = this[ i ] || {}; + + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch( e ) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var arg = arguments[ 0 ]; + + // Make the changes, replacing each context element with the new content + this.domManip( arguments, function( elem ) { + arg = this.parentNode; + + jQuery.cleanData( getAll( this ) ); + + if ( arg ) { + arg.replaceChild( elem, this ); + } + }); + + // Force removal if there was no new content (e.g., from empty arguments) + return arg && (arg.length || arg.nodeType) ? this : this.remove(); + }, + + detach: function( selector ) { + return this.remove( selector, true ); + }, + + domManip: function( args, callback ) { + + // Flatten any nested arrays + args = concat.apply( [], args ); + + var fragment, first, scripts, hasScripts, node, doc, + i = 0, + l = this.length, + set = this, + iNoClone = l - 1, + value = args[ 0 ], + isFunction = jQuery.isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( isFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return this.each(function( index ) { + var self = set.eq( index ); + if ( isFunction ) { + args[ 0 ] = value.call( this, index, self.html() ); + } + self.domManip( args, callback ); + }); + } + + if ( l ) { + fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + if ( first ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + // Support: QtWebKit + // jQuery.merge because push.apply(_, arraylike) throws + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( this[ i ], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !data_priv.access( node, "globalEval" ) && jQuery.contains( doc, node ) ) { + + if ( node.src ) { + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl ) { + jQuery._evalUrl( node.src ); + } + } else { + jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) ); + } + } + } + } + } + } + + return this; + } +}); + +jQuery.each({ + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1, + i = 0; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone( true ); + jQuery( insert[ i ] )[ original ]( elems ); + + // Support: QtWebKit + // .get() because push.apply(_, arraylike) throws + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +}); + + +var iframe, + elemdisplay = {}; + +/** + * Retrieve the actual display of a element + * @param {String} name nodeName of the element + * @param {Object} doc Document object + */ +// Called only from within defaultDisplay +function actualDisplay( name, doc ) { + var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ), + + // getDefaultComputedStyle might be reliably used only on attached element + display = window.getDefaultComputedStyle ? + + // Use of this method is a temporary fix (more like optmization) until something better comes along, + // since it was removed from specification and supported only in FF + window.getDefaultComputedStyle( elem[ 0 ] ).display : jQuery.css( elem[ 0 ], "display" ); + + // We don't have any data stored on the element, + // so use "detach" method as fast way to get rid of the element + elem.detach(); + + return display; +} + +/** + * Try to determine the default display value of an element + * @param {String} nodeName + */ +function defaultDisplay( nodeName ) { + var doc = document, + display = elemdisplay[ nodeName ]; + + if ( !display ) { + display = actualDisplay( nodeName, doc ); + + // If the simple way fails, read from inside an iframe + if ( display === "none" || !display ) { + + // Use the already-created iframe if possible + iframe = (iframe || jQuery( "